diff --git a/Examples/.gitignore b/Examples/.gitignore deleted file mode 100644 index 3d690c19..00000000 --- a/Examples/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.idea/ -target/ -*.iml -~* -*.*~ -*[Oo]ut* diff --git a/Examples/.project b/Examples/.project deleted file mode 100644 index f7b6dad8..00000000 --- a/Examples/.project +++ /dev/null @@ -1,34 +0,0 @@ - - - Aspose.Words Examples - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.m2e.core.maven2Nature - org.eclipse.jdt.core.javanature - - - - 1356841242113 - src - 26 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-bin - - - - diff --git a/Examples/ApiExamples/Java/pom.xml b/Examples/ApiExamples/Java/pom.xml new file mode 100644 index 00000000..595e0188 --- /dev/null +++ b/Examples/ApiExamples/Java/pom.xml @@ -0,0 +1,109 @@ + + + 4.0.0 + + + UTF-8 + + + com.aspose.apiexamples + ApiExamples-Tests + 1.0-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M4 + + ${basedir}/src/main/java/ + ${project.build.directory}/classes/ + + **/Ex*.java + + + + + + + + + AsposeJavaAPI + Aspose Java API + https://releases.aspose.com/java/repo/ + + + com.springsource.repository.bundles.external + SpringSource Enterprise Bundle Repository - External Bundle Releases + https://repository.springsource.com/maven/bundles/external + + + + + + com.aspose + aspose-words + 25.9 + jdk17 + + + com.aspose + aspose-words + 25.9 + shaping-harfbuzz-plugin + + + com.aspose + aspose-barcode + 25.8 + jdk18 + + + com.aspose + aspose-pdf + 25.8 + jdk17 + + + org.testng + testng + 7.5.1 + + + javax.media.jai + com.springsource.javax.media.jai.core + 1.1.3 + + + net.sf.ucanaccess + ucanaccess + 3.0.6 + + + commons-io + commons-io + 2.16.1 + + + org.apache.commons + commons-collections4 + 4.4 + + + org.apache.poi + poi + 5.0.0 + + + \ No newline at end of file diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ApiExampleBase.java b/Examples/ApiExamples/Java/src/main/java/Examples/ApiExampleBase.java new file mode 100644 index 00000000..dc8a8d80 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ApiExampleBase.java @@ -0,0 +1,197 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.CurrentThreadSettings; +import com.aspose.words.License; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; + +import java.io.File; +import java.net.URI; +import java.util.Locale; + +/** + * Provides common infrastructure for all API examples that are implemented as unit tests. + */ +public class ApiExampleBase { + + /** + * Test artifacts directory. + */ + private final File artifactsDirPath = new File(getArtifactsDir()); + + /** + * Delete all dirs and files from directory. + * + * @param dir directory to be deleted + */ + private static void deleteDir(final File dir) { + String[] entries = dir.list(); + for (String s : entries) { + File currentFile = new File(dir.getPath(), s); + if (currentFile.isDirectory()) { + deleteDir(currentFile); + } else { + currentFile.delete(); + } + } + dir.delete(); + } + + /** + * Delete and create new empty directory for test artifacts. + * + * @throws Exception exception for setUnlimitedLicense() + */ + @BeforeClass(alwaysRun = true) + public void setUp() throws Exception { + CurrentThreadSettings.setLocale(Locale.US); + setUnlimitedLicense(); + + if (!artifactsDirPath.exists()) { + artifactsDirPath.mkdir(); + } else { + deleteDir(artifactsDirPath); + artifactsDirPath.mkdir(); + } + } + + /** + * Delete all dirs and files from directory for test artifacts. + */ + @AfterClass(alwaysRun = true) + public void tearDown() { + deleteDir(artifactsDirPath); + } + + /** + * Set java licence for using library without any restrictions. + * + * @throws Exception exception for setting licence + */ + private static void setUnlimitedLicense() throws Exception { + // This is where the test license is on my development machine. + String testLicenseFileName = getLicenseDir() + "Aspose.Total.Java.lic"; + if (new File(testLicenseFileName).exists()) { + // This shows how to use an Aspose.Words license when you have purchased one. + // You don't have to specify full path as shown here. You can specify just the + // file name if you copy the license file into the same folder as your application + // binaries or you add the license to your project as an embedded resource. + License wordsLicense = new License(); + wordsLicense.setLicense(testLicenseFileName); + + com.aspose.pdf.License pdfLicense = new com.aspose.pdf.License(); + pdfLicense.setLicense(testLicenseFileName); + + com.aspose.barcode.License barcodeLicense = new com.aspose.barcode.License(); + barcodeLicense.setLicense(testLicenseFileName); + } + } + + /** + * Gets the path to the license used by the code examples. + * + * @return licence directory + */ + static String getLicenseDir() { + return G_LICENSE_DIR; + } + + /** + * Gets the path to the documents used by the code examples. Ends with a back slash. + * + * @return directory for test artifacts + */ + static String getArtifactsDir() { + return G_ARTIFACTS_DIR; + } + + /** + * Gets the path to the documents used by the code examples. Ends with a back slash. + * + * @return directory with expected documents + */ + static String getGoldsDir() { + return G_GOLDS_DIR; + } + + /** + * Gets the path to the documents used by the code examples. Ends with a back slash. + * + * @return directory with documents for testing + */ + static String getMyDir() { + return G_MY_DIR; + } + + /** + * Gets the path to the images used by the code examples. Ends with a back slash. + * + * @return directory with images for testing + */ + protected static String getImageDir() { + return G_IMAGE_DIR; + } + + /** + * Gets the path to the codebase directory. + * + * @return directory with data files for testing + */ + static String getDatabaseDir() { + return G_DATABASE_DIR; + } + + /** + * Gets the path of the free fonts. Ends with a back slash. + * + * @return directory with public fonts for testing + */ + static String getFontsDir() { + return G_FONTS_DIR; + } + + /** + * Gets the path to the codebase directory. + * + * @return url with aspose logo image + */ + static URI getAsposelogoUri() { + return G_ASPOSELOGO_URI; + } + + private static final String G_ASSEMBLY_DIR; + private static final String G_CODE_BASE_DIR; + private static final String G_LICENSE_DIR; + private static final String G_ARTIFACTS_DIR; + private static final String G_GOLDS_DIR; + private static final String G_MY_DIR; + private static final String G_IMAGE_DIR; + private static final String G_DATABASE_DIR; + private static final String G_FONTS_DIR; + private static final URI G_ASPOSELOGO_URI; + + static { + try { + G_ASSEMBLY_DIR = System.getProperty("user.dir"); + G_CODE_BASE_DIR = new File(G_ASSEMBLY_DIR).getParentFile().getParentFile() + File.separator; + G_LICENSE_DIR = G_CODE_BASE_DIR + "Data" + File.separator + "License" + File.separator; + G_ARTIFACTS_DIR = G_CODE_BASE_DIR + "Data" + File.separator + "Artifacts" + File.separator; + G_GOLDS_DIR = G_CODE_BASE_DIR + "Data" + File.separator + "Golds" + File.separator; + G_MY_DIR = G_CODE_BASE_DIR + "Data" + File.separator; + G_IMAGE_DIR = G_CODE_BASE_DIR + "Data" + File.separator + "Images" + File.separator; + G_DATABASE_DIR = G_CODE_BASE_DIR + "Data" + File.separator + "Database" + File.separator; + G_FONTS_DIR = G_CODE_BASE_DIR + "Data" + File.separator + "MyFonts" + File.separator; + G_ASPOSELOGO_URI = new URI("https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/CustomBarcodeGenerator.java b/Examples/ApiExamples/Java/src/main/java/Examples/CustomBarcodeGenerator.java new file mode 100644 index 00000000..b21bae55 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/CustomBarcodeGenerator.java @@ -0,0 +1,266 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.barcode.generation.*; +import com.aspose.words.BarcodeParameters; +import com.aspose.words.IBarcodeGenerator; + +import java.awt.*; +import java.awt.image.BufferedImage; + +class CustomBarcodeGeneratorUtils { + /// + /// Converts a height value in twips to pixels using a default DPI of 96. + /// + /// The height value in twips. + /// The default value to return if the conversion fails. + /// The height value in pixels. + public static double twipsToPixels(String heightInTwips, double defVal) { + return twipsToPixels(heightInTwips, 96.0, defVal); + } + + /// + /// Converts a height value in twips to pixels based on the given resolution. + /// + /// The height value in twips to be converted. + /// The resolution in pixels per inch. + /// The default value to be returned if the conversion fails. + /// The converted height value in pixels. + public static double twipsToPixels(String heightInTwips, double resolution, double defVal) { + try { + int lVal = Integer.parseInt(heightInTwips); + return (lVal / 1440.0) * resolution; + } catch (Exception e) { + return defVal; + } + } + + /// + /// Gets the rotation angle in degrees based on the given rotation angle string. + /// + /// The rotation angle string. + /// The default value to return if the rotation angle is not recognized. + /// The rotation angle in degrees. + public static float getRotationAngle(String rotationAngle, float defVal) { + switch (rotationAngle) { + case "0": + return 0f; + case "1": + return 270f; + case "2": + return 180f; + case "3": + return 90f; + default: + return defVal; + } + } + + /// + /// Converts a string representation of an error correction level to a QRErrorLevel enum value. + /// + /// The string representation of the error correction level. + /// The default error correction level to return if the input is invalid. + /// The corresponding QRErrorLevel enum value. + public static QRErrorLevel getQRCorrectionLevel(String errorCorrectionLevel, QRErrorLevel def) { + switch (errorCorrectionLevel) { + case "0": + return QRErrorLevel.LEVEL_L; + case "1": + return QRErrorLevel.LEVEL_M; + case "2": + return QRErrorLevel.LEVEL_Q; + case "3": + return QRErrorLevel.LEVEL_H; + default: + return def; + } + } + + /// + /// Gets the barcode encode type based on the given encode type from Word. + /// + /// The encode type from Word. + /// The barcode encode type. + public static SymbologyEncodeType getBarcodeEncodeType(String encodeTypeFromWord) { + // https://support.microsoft.com/en-au/office/field-codes-displaybarcode-6d81eade-762d-4b44-ae81-f9d3d9e07be3 + switch (encodeTypeFromWord) { + case "QR": + return EncodeTypes.QR; + case "CODE128": + return EncodeTypes.CODE_128; + case "CODE39": + return EncodeTypes.CODE_39; + case "JPPOST": + return EncodeTypes.RM_4_SCC; + case "EAN8": + case "JAN8": + return EncodeTypes.EAN_8; + case "EAN13": + case "JAN13": + return EncodeTypes.EAN_13; + case "UPCA": + return EncodeTypes.UPCA; + case "UPCE": + return EncodeTypes.UPCE; + case "CASE": + case "ITF14": + return EncodeTypes.ITF_14; + case "NW7": + return EncodeTypes.CODABAR; + default: + return EncodeTypes.NONE; + } + } + + /// + /// Converts a hexadecimal color string to a Color object. + /// + /// The hexadecimal color string to convert. + /// The default Color value to return if the conversion fails. + /// The Color object representing the converted color, or the default value if the conversion fails. + public static Color convertColor(String inputColor, Color defVal) { + if (inputColor == null || inputColor.isEmpty()) return defVal; + try { + int color = Integer.parseInt(inputColor, 16); + // Return Color.FromArgb((color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF); + return new Color((color & 0xFF), ((color >> 8) & 0xFF), ((color >> 16) & 0xFF)); + } catch (Exception e) { + return defVal; + } + } + + /// + /// Calculates the scale factor based on the provided string representation. + /// + /// The string representation of the scale factor. + /// The default value to return if the scale factor cannot be parsed. + /// + /// The scale factor as a decimal value between 0 and 1, or the default value if the scale factor cannot be parsed. + /// + public static double scaleFactor(String scaleFactor, double defVal) { + try { + int scale = Integer.parseInt(scaleFactor); + return scale / 100.0; + } catch (Exception e) { + return defVal; + } + } + + /// + /// Sets the position code style for a barcode generator. + /// + /// The barcode generator. + /// The position code style to set. + /// The barcode value. + public static void setPosCodeStyle(BarcodeGenerator gen, String posCodeStyle, String barcodeValue) { + switch (posCodeStyle) { + // STD default and without changes. + case "SUP2": + gen.setCodeText(barcodeValue.substring((0), (0) + (barcodeValue.length() - 2))); + gen.getParameters().getBarcode().getSupplement().setSupplementData(barcodeValue.substring((barcodeValue.length() - 2), (barcodeValue.length() - 2) + (2))); + break; + case "SUP5": + gen.setCodeText(barcodeValue.substring((0), (0) + (barcodeValue.length() - 5))); + gen.getParameters().getBarcode().getSupplement().setSupplementData(barcodeValue.substring((barcodeValue.length() - 5), (barcodeValue.length() - 5) + (5))); + break; + case "CASE": + gen.getParameters().getBorder().setVisible(true); + gen.getParameters().getBorder().setColor(gen.getParameters().getBarcode().getBarColor()); + gen.getParameters().getBorder().setDashStyle(BorderDashStyle.SOLID); + gen.getParameters().getBorder().getWidth().setPixels(gen.getParameters().getBarcode().getXDimension().getPixels() * 5); + break; + } + } + + public static final double DEFAULT_QRX_DIMENSION_IN_PIXELS = 4.0; + public static final double DEFAULT_1_DX_DIMENSION_IN_PIXELS = 1.0; + + /// + /// Draws an error image with the specified exception message. + /// + /// The exception containing the error message. + /// A Bitmap object representing the error image. + public static BufferedImage drawErrorImage(Exception error) { + BufferedImage bmp = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB); + + Graphics2D grf = bmp.createGraphics(); + grf.setColor(Color.WHITE); + grf.fillRect(0, 0, bmp.getWidth(), bmp.getHeight()); + grf.setFont(new Font("Microsoft Sans Serif", 8, FontStyle.REGULAR)); + grf.setColor(Color.RED); + grf.drawString(error.getMessage(), 0, 0); + + return bmp; + } + + public static BufferedImage convertImageToWord(BufferedImage bmp) { + return bmp; + } +} + +class CustomBarcodeGenerator implements IBarcodeGenerator { + public BufferedImage getBarcodeImage(BarcodeParameters parameters) { + try { + BarcodeGenerator gen = new BarcodeGenerator(CustomBarcodeGeneratorUtils.getBarcodeEncodeType(parameters.getBarcodeType()), parameters.getBarcodeValue()); + + // Set color. + gen.getParameters().getBarcode().setBarColor(CustomBarcodeGeneratorUtils.convertColor(parameters.getForegroundColor(), gen.getParameters().getBarcode().getBarColor())); + gen.getParameters().setBackColor(CustomBarcodeGeneratorUtils.convertColor(parameters.getBackgroundColor(), gen.getParameters().getBackColor())); + + // Set display or hide text. + if (!parameters.getDisplayText()) + gen.getParameters().getBarcode().getCodeTextParameters().setLocation(CodeLocation.NONE); + else + gen.getParameters().getBarcode().getCodeTextParameters().setLocation(CodeLocation.BELOW); + + // Set QR Code error correction level.s + gen.getParameters().getBarcode().getQR().setQrErrorLevel(QRErrorLevel.LEVEL_H); + String errorCorrectionLevel = parameters.getErrorCorrectionLevel(); + if (errorCorrectionLevel != null) + gen.getParameters().getBarcode().getQR().setQrErrorLevel(CustomBarcodeGeneratorUtils.getQRCorrectionLevel(errorCorrectionLevel, gen.getParameters().getBarcode().getQR().getQrErrorLevel())); + + // Set rotation angle. + String symbolRotation = parameters.getSymbolRotation(); + if (symbolRotation != null) + gen.getParameters().setRotationAngle(CustomBarcodeGeneratorUtils.getRotationAngle(symbolRotation, gen.getParameters().getRotationAngle())); + + // Set scaling factor. + double scalingFactor = 1.0; + if (parameters.getScalingFactor() != null) + scalingFactor = CustomBarcodeGeneratorUtils.scaleFactor(parameters.getScalingFactor(), scalingFactor); + + // Set size. + if (gen.getBarcodeType() == EncodeTypes.QR) + gen.getParameters().getBarcode().getXDimension().setPixels((float) Math.max(1.0, Math.round(CustomBarcodeGeneratorUtils.DEFAULT_QRX_DIMENSION_IN_PIXELS * scalingFactor))); + else + gen.getParameters().getBarcode().getXDimension().setPixels((float) Math.max(1.0, Math.round(CustomBarcodeGeneratorUtils.DEFAULT_1_DX_DIMENSION_IN_PIXELS * scalingFactor))); + + //Set height. + String symbolHeight = parameters.getSymbolHeight(); + if (symbolHeight != null) + gen.getParameters().getBarcode().getBarHeight().setPixels((float) Math.max(5.0, + Math.round(CustomBarcodeGeneratorUtils.twipsToPixels(symbolHeight, gen.getParameters().getBarcode().getBarHeight().getPixels()) * scalingFactor))); + + // Set style of a Point-of-Sale barcode. + String posCodeStyle = parameters.getPosCodeStyle(); + if (posCodeStyle != null) + CustomBarcodeGeneratorUtils.setPosCodeStyle(gen, posCodeStyle, parameters.getBarcodeValue()); + + return CustomBarcodeGeneratorUtils.convertImageToWord(gen.generateBarCodeImage()); + } catch (Exception e) { + return CustomBarcodeGeneratorUtils.convertImageToWord(CustomBarcodeGeneratorUtils.drawErrorImage(e)); + } + } + + public BufferedImage getOldBarcodeImage(BarcodeParameters parameters) { + throw new UnsupportedOperationException(); + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/DocumentHelper.java b/Examples/ApiExamples/Java/src/main/java/Examples/DocumentHelper.java new file mode 100644 index 00000000..493de655 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/DocumentHelper.java @@ -0,0 +1,489 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; + +import java.io.*; +import java.sql.ResultSet; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.regex.Pattern; + +import static Examples.ApiExampleBase.getDatabaseDir; + +/** + * Functions for operations with document and content. + */ +public final class DocumentHelper { + + private DocumentHelper() { + //not called + } + + /** + * Create simple document without run in the paragraph. + * + * @return new document without any text + * @throws Exception exception for creating new document + */ + static Document createDocumentWithoutDummyText() throws Exception { + Document doc = new Document(); + + //Remove the previous changes of the document + doc.removeAllChildren(); + + //Set the document author + doc.getBuiltInDocumentProperties().setAuthor("Test Author"); + + //Create paragraph without run + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln(); + + return doc; + } + + /** + * Create new document with text. + * + * @return new document with dummy text + * @throws Exception exception for creating new document + */ + static Document createDocumentFillWithDummyText() throws Exception { + Document doc = new Document(); + + //Remove the previous changes of the document + doc.removeAllChildren(); + + //Set the document author + doc.getBuiltInDocumentProperties().setAuthor("Test Author"); + + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Page "); + builder.insertField("PAGE", ""); + builder.write(" of "); + builder.insertField("NUMPAGES", ""); + + //Insert new table with two rows and two cells + insertTable(builder); + + builder.writeln("Hello World!"); + + // Continued on page 2 of the document content + builder.insertBreak(BreakType.PAGE_BREAK); + + //Insert TOC entries + insertToc(builder); + + return doc; + } + + /** + * Find text in file. + * + * @param path file path + * @param expression expression for text search + * @throws IOException exception for reading file + */ + static void findTextInFile(final String path, final String expression) throws IOException { + BufferedReader sr = new BufferedReader(new FileReader(path)); + try { + String line = sr.readLine(); + while (line != null) { + if (line.isEmpty()) { + line = sr.readLine(); + continue; + } + + if (line.contains(expression)) { + System.out.println(line); + break; + } else { + line = sr.readLine(); + if (line == null) + { + Assert.fail(); + break; + } + } + } + } finally { + if (sr != null) { + sr.close(); + } + } + } + + /** + * Create new document template for reporting engine. + * + * @param templateText template text + * @throws Exception exception for creating new document + */ + static Document createSimpleDocument(final String templateText) throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write(templateText); + + return doc; + } + + /** + * Create new document with textbox shape and some query. + * + * @param templateText template text + * @param shapeType type of shape + * @throws Exception exception for creating new document + */ + static Document createTemplateDocumentWithDrawObjects(final String templateText, final int shapeType) throws Exception { + final double shapeWidth = 431.5; + final double shapeHeight = 431.5; + + Document doc = new Document(); + + // Create textbox shape. + Shape shape = new Shape(doc, shapeType); + shape.setWidth(shapeWidth); + shape.setHeight(shapeHeight); + + Paragraph paragraph = new Paragraph(doc); + paragraph.appendChild(new Run(doc, templateText)); + + // Insert paragraph into the textbox. + shape.appendChild(paragraph); + + // Insert textbox into the document. + doc.getFirstSection().getBody().getFirstParagraph().appendChild(shape); + + return doc; + } + + /** + * Compare word documents. + * + * @param filePathDoc1 First document path + * @param filePathDoc2 Second document path + * @return Result of compare document + * @throws Exception exception for creating new document + */ + static boolean compareDocs(final String filePathDoc1, final String filePathDoc2) throws Exception { + Document doc1 = new Document(filePathDoc1); + Document doc2 = new Document(filePathDoc2); + + return doc1.getText().equals(doc2.getText()); + + } + + /** + * Insert run into the current document + * + * @param doc Current document + * @param text Custom text + * @param paraIndex Paragraph index + */ + static Run insertNewRun(final Document doc, final String text, final int paraIndex) { + Paragraph para = getParagraph(doc, paraIndex); + + Run run = new Run(doc); + run.setText(text); + + para.appendChild(run); + + return run; + } + + /** + * Insert text into the current document. + * + * @param builder Current document builder + * @param textStrings Custom text + */ + static void insertBuilderText(final DocumentBuilder builder, final String[] textStrings) { + for (String textString : textStrings) { + builder.writeln(textString); + } + } + + /** + * Get paragraph text of the current document. + * + * @param doc Current document + * @param paraIndex Paragraph number from collection + */ + static String getParagraphText(final Document doc, final int paraIndex) { + return doc.getFirstSection().getBody().getParagraphs().get(paraIndex).getText(); + } + + /** + * Insert new table in the document. + * + * @param builder Current document builder + * @throws Exception exception for setting width to fit the table contents + */ + static Table insertTable(final DocumentBuilder builder) throws Exception { + //Start creating a new table + Table table = builder.startTable(); + + //Insert Row 1 Cell 1 + builder.insertCell(); + builder.write("Date"); + + //Set width to fit the table contents + table.autoFit(AutoFitBehavior.AUTO_FIT_TO_CONTENTS); + + //Insert Row 1 Cell 2 + builder.insertCell(); + builder.write(" "); + + builder.endRow(); + + //Insert Row 2 Cell 1 + builder.insertCell(); + builder.write("Author"); + + //Insert Row 2 Cell 2 + builder.insertCell(); + builder.write(" "); + + builder.endRow(); + + builder.endTable(); + + return table; + } + + /** + * Insert TOC entries in the document + * + * @param builder The builder + */ + static void insertToc(final DocumentBuilder builder) { + // Creating TOC entries + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + + builder.writeln("Heading 1"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); + + builder.writeln("Heading 1.1"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_4); + + builder.writeln("Heading 1.1.1.1"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_5); + + builder.writeln("Heading 1.1.1.1.1"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_9); + + builder.writeln("Heading 1.1.1.1.1.1.1.1.1"); + } + + /** + * Get section text of the current document + * + * @param doc Current document + * @param secIndex Section number from collection + * @return current document section text + */ + static String getSectionText(final Document doc, final int secIndex) { + return doc.getSections().get(secIndex).getText(); + } + + /** + * Get paragraph of the current document + * + * @param doc Current document + * @param paraIndex Paragraph number from collection + * @return current document paragraph + */ + static Paragraph getParagraph(final Document doc, final int paraIndex) { + return doc.getFirstSection().getBody().getParagraphs().get(paraIndex); + } + + /** + * Get paragraph of the current document. + * + * @param inputStream stream with test image + * @return byte array + * @throws IOException exception for reading array stream + */ + static byte[] getBytesFromStream(final InputStream inputStream) throws IOException { + final int bufferSize = 1024; + int len; + + ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream(); + byte[] buffer = new byte[bufferSize]; + + while ((len = inputStream.read(buffer)) != -1) { + byteBuffer.write(buffer, 0, len); + } + return byteBuffer.toByteArray(); + } + + /** + * Create specific date for tests. + * + * @return specific date + */ + static Date createDate(int year, int month, int day) { + Calendar cal = Calendar.getInstance(); + cal.set(year, month, day); + return cal.getTime(); + } + + /** + * Create specific date for tests. + * + * @return specific date + */ + static Date createDate(int year, int month, int day, int hours, int minuts, int seconds) { + Calendar cal = Calendar.getInstance(); + cal.set(year, month, day, hours, minuts, seconds); + return cal.getTime(); + } + + /** + * Create date without time for tests. + * + * @return specific date without time + */ + static Date getDateWithoutTimeUsingFormat(Date date) + throws ParseException { + SimpleDateFormat formatter = new SimpleDateFormat( + "dd/MM/yyyy"); + return formatter.parse(formatter.format(date)); + } + + /** + * Get date base on system configuration. + * + * @return specific date without time + */ + static LocalDate getLocalDate(Date date) + { + return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()).toLocalDate(); + } + + static ArrayList directoryGetFiles(final String dirname, final String filenamePattern) { + File dirFile = new File(dirname); + Pattern re = Pattern.compile(filenamePattern.replace("*", ".*").replace("?", ".?")); + ArrayList dirFiles = new ArrayList<>(); + for (File file : dirFile.listFiles()) { + if (file.isDirectory()) { + dirFiles.addAll(directoryGetFiles(file.getPath(), filenamePattern)); + } else { + if (re.matcher(file.getName()).matches()) { + dirFiles.add(file.getPath()); + } + } + } + return dirFiles; + } + + /** + * Utility function that creates a connection, command, + * executes the command and return the result in a DataTable. + */ + static ResultSet executeDataTable(final String commandText) throws Exception { + // Loads the driver + Class.forName("net.ucanaccess.jdbc.UcanaccessDriver"); + + // Open the database connection + String connString = "jdbc:ucanaccess://" + getDatabaseDir() + "Northwind.accdb"; + + // From Wikipedia: The Sun driver has a known issue with character encoding and Microsoft Access databases + // Microsoft Access may use an encoding that is not correctly translated by the driver, leading to the replacement + // in strings of, for example, accented characters by question marks + // + // In this case I have to set CP1252 for the european characters to come through in the data values + java.util.Properties props = new java.util.Properties(); + props.put("charSet", "Cp1252"); + props.put("UID", "Admin"); + + // DSN-less DB connection + java.sql.Connection conn = java.sql.DriverManager.getConnection(connString, props); + + // Create and execute a command + java.sql.Statement statement = conn.createStatement(); + return statement.executeQuery(commandText); + } + + /// + /// Save the document to a stream, immediately re-open it and return the newly opened version + /// + /// + /// Used for testing how document features are preserved after saving/loading + /// + /// The document we wish to re-open + static Document saveOpen(Document doc) throws Exception { + ByteArrayOutputStream docStream = new ByteArrayOutputStream(); + try { + doc.save(docStream, new OoxmlSaveOptions(SaveFormat.DOCX)); + return new Document(new ByteArrayInputStream(docStream.toByteArray())); + } finally { + if (docStream != null) docStream.close(); + } + } + + static int getListItemCount(NodeCollection paragraphs) { + int listItemCount = 0; + + for (Paragraph para : (Iterable) paragraphs) { + if (para.getListFormat().isListItem()) { + listItemCount++; + } + } + + return listItemCount; + } + + static int getListLevelNumberCount(NodeCollection paragraphs, int listLevelNumber) { + int listLevelNumberCount = 0; + + for (Paragraph para : (Iterable) paragraphs) { + if (para.getListFormat().getListLevelNumber() == listLevelNumber) { + listLevelNumberCount++; + } + } + + return listLevelNumberCount; + } + + static int getFieldsCount(FieldCollection fields, int fieldType) { + int fieldsCount = 0; + + for (Field field : fields) { + if (field.getType() == fieldType) { + fieldsCount++; + } + } + + return fieldsCount; + } + + static Object getField(FieldCollection fields, int fieldType) { + for (Field field : fields) { + if (field.getType() == fieldType) + return field; + } + + return null; + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExAI.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExAI.java new file mode 100644 index 00000000..96e078b6 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExAI.java @@ -0,0 +1,130 @@ +package Examples; + +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.annotations.Test; + +@Test +public class ExAI extends ApiExampleBase +{ + @Test (enabled = false, description = "This test should be run manually to manage API requests amount") + public void aiSummarize() throws Exception + { + //ExStart:AiSummarize + //GistId:72d57eeddb7fb342fd51b26e5fcf9642 + //ExFor:GoogleAiModel + //ExFor:OpenAiModel + //ExFor:OpenAiModel.WithOrganization(String) + //ExFor:OpenAiModel.WithProject(String) + //ExFor:AiModel + //ExFor:AiModel.Summarize(Document, SummarizeOptions) + //ExFor:AiModel.Summarize(Document[], SummarizeOptions) + //ExFor:AiModel.Create(AiModelType) + //ExFor:AiModel.WithApiKey(String) + //ExFor:AiModelType + //ExFor:SummarizeOptions + //ExFor:SummarizeOptions.#ctor + //ExFor:SummarizeOptions.SummaryLength + //ExFor:SummaryLength + //ExSummary:Shows how to summarize text using OpenAI and Google models. + Document firstDoc = new Document(getMyDir() + "Big document.docx"); + Document secondDoc = new Document(getMyDir() + "Document.docx"); + + String apiKey = System.getenv("API_KEY"); + // Use OpenAI or Google generative language models. + AiModel model = ((OpenAiModel)AiModel.create(AiModelType.GPT_4_O_MINI).withApiKey(apiKey)).withOrganization("Organization").withProject("Project"); + + SummarizeOptions options = new SummarizeOptions(); + + options.setSummaryLength(SummaryLength.SHORT); + Document oneDocumentSummary = model.summarize(firstDoc, options); + oneDocumentSummary.save(getArtifactsDir() + "AI.AiSummarize.One.docx"); + + options.setSummaryLength(SummaryLength.LONG); + Document multiDocumentSummary = model.summarize(new Document[] { firstDoc, secondDoc }, options); + multiDocumentSummary.save(getArtifactsDir() + "AI.AiSummarize.Multi.docx"); + //ExEnd:AiSummarize + } + + @Test (enabled = false, description = "This test should be run manually to manage API requests amount") + public void aiTranslate() throws Exception + { + //ExStart:AiTranslate + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:AiModel.Translate(Document, AI.Language) + //ExFor:AI.Language + //ExSummary:Shows how to translate text using Google models. + Document doc = new Document(getMyDir() + "Document.docx"); + + String apiKey = System.getenv("API_KEY"); + // Use Google generative language models. + AiModel model = AiModel.create(AiModelType.GEMINI_15_FLASH).withApiKey(apiKey); + + Document translatedDoc = model.translate(doc, Language.ARABIC); + translatedDoc.save(getArtifactsDir() + "AI.AiTranslate.docx"); + //ExEnd:AiTranslate + } + + @Test (enabled = false, description = "This test should be run manually to manage API requests amount") + public void aiGrammar() throws Exception + { + //ExStart:AiGrammar + //GistId:c012c14781944ce4cc5e31f35b08060a + //ExFor:AiModel.CheckGrammar(Document, CheckGrammarOptions) + //ExFor:CheckGrammarOptions + //ExSummary:Shows how to check the grammar of a document. + Document doc = new Document(getMyDir() + "Big document.docx"); + + String apiKey = System.getenv("API_KEY"); + // Use OpenAI generative language models. + AiModel model = AiModel.create(AiModelType.GPT_4_O_MINI).withApiKey(apiKey); + + CheckGrammarOptions grammarOptions = new CheckGrammarOptions(); + grammarOptions.setImproveStylistics(true); + + Document proofedDoc = model.checkGrammar(doc, grammarOptions); + proofedDoc.save(getArtifactsDir() + "AI.AiGrammar.docx"); + //ExEnd:AiGrammar + } + + //ExStart:SelfHostedModel + //GistId:2af5a850f2e0a83c3b114274a838c092 + //ExFor:OpenAiModel + //ExSummary:Shows how to use self-hosted AI model based on OpenAiModel. + @Test (enabled = false, description = "This test should be run manually when you are configuring your model") //ExSkip + public void selfHostedModel() throws Exception + { + Document doc = new Document(getMyDir() + "Big document.docx"); + + String apiKey = System.getenv("API_KEY"); + // Use OpenAI generative language models. + AiModel model = new CustomAiModel().withApiKey(apiKey); + + Document translatedDoc = model.translate(doc, Language.RUSSIAN); + translatedDoc.save(getArtifactsDir() + "AI.SelfHostedModel.docx"); + } + + /// + /// Custom self-hosted AI model. + /// + static class CustomAiModel extends OpenAiModel + { + /// + /// Gets custom URL of the model. + /// + protected /*override*/ String getUrl() { return "https://localhost/"; } + + /// + /// Gets model name. + /// + protected /*override*/ String getName() { return "my-model-24b"; } + } + //ExEnd:SelfHostedModel +} + diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExAbsolutePositionTab.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExAbsolutePositionTab.java new file mode 100644 index 00000000..d78acfc7 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExAbsolutePositionTab.java @@ -0,0 +1,93 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +@Test +public class ExAbsolutePositionTab extends ApiExampleBase { + //ExStart + //ExFor:AbsolutePositionTab + //ExFor:AbsolutePositionTab.Accept(DocumentVisitor) + //ExFor:DocumentVisitor.VisitAbsolutePositionTab + //ExFor:Body.Accept(DocumentVisitor) + //ExFor:Body.AcceptStart(DocumentVisitor) + //ExFor:Body.AcceptEnd(DocumentVisitor) + //ExFor:VisitorAction + //ExSummary:Shows how to process absolute position tab characters with a document visitor. + @Test //ExSkip + public void documentToTxt() throws Exception { + Document doc = new Document(getMyDir() + "Absolute position tab.docx"); + + // Extract the text contents of our document by accepting this custom document visitor. + DocTextExtractor myDocTextExtractor = new DocTextExtractor(); + Section fisrtSection = doc.getFirstSection(); + fisrtSection.getBody().accept(myDocTextExtractor); + // Visit only start of the document body. + fisrtSection.getBody().acceptStart(myDocTextExtractor); + // Visit only end of the document body. + fisrtSection.getBody().acceptEnd(myDocTextExtractor); + + // The absolute position tab, which has no equivalent in string form, has been explicitly converted to a tab character. + Assert.assertEquals("Before AbsolutePositionTab\tAfter AbsolutePositionTab", myDocTextExtractor.getText()); + + // An AbsolutePositionTab can accept a DocumentVisitor by itself too. + AbsolutePositionTab absPositionTab = (AbsolutePositionTab) doc.getFirstSection().getBody().getFirstParagraph().getChild(NodeType.SPECIAL_CHAR, 0, true); + + myDocTextExtractor = new DocTextExtractor(); + absPositionTab.accept(myDocTextExtractor); + + Assert.assertEquals("\t", myDocTextExtractor.getText()); + } + + /// + /// Collects the text contents of all runs in the visited document. Replaces all absolute tab characters with ordinary tabs. + /// + public static class DocTextExtractor extends DocumentVisitor { + public DocTextExtractor() { + mBuilder = new StringBuilder(); + } + + /// + /// Called when a Run node is encountered in the document. + /// + public int visitRun(final Run run) { + appendText(run.getText()); + return VisitorAction.CONTINUE; + } + + /// + /// Called when an AbsolutePositionTab node is encountered in the document. + /// + public int visitAbsolutePositionTab(final AbsolutePositionTab tab) { + mBuilder.append("\t"); + + return VisitorAction.CONTINUE; + } + + /// + /// Adds text to the current output. Honors the enabled/disabled output flag. + /// + public void appendText(final String text) { + mBuilder.append(text); + } + + /// + /// Plain text of the document that was accumulated by the visitor. + /// + public String getText() { + return mBuilder.toString(); + } + + private final StringBuilder mBuilder; + } + //ExEnd +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExBookmarks.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExBookmarks.java new file mode 100644 index 00000000..7fdb2303 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExBookmarks.java @@ -0,0 +1,247 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.apache.commons.collections4.IterableUtils; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.text.MessageFormat; +import java.util.Collections; +import java.util.Iterator; + + +@Test +public class ExBookmarks extends ApiExampleBase { + @Test + public void insert() throws Exception { + //ExStart + //ExFor:Bookmark.Name + //ExSummary:Shows how to insert a bookmark. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // A valid bookmark has a name, a BookmarkStart, and a BookmarkEnd node. + // Any whitespace in the names of bookmarks will be converted to underscores if we open the saved document with Microsoft Word. + // If we highlight the bookmark's name in Microsoft Word via Insert -> Links -> Bookmark, and press "Go To", + // the cursor will jump to the text enclosed between the BookmarkStart and BookmarkEnd nodes. + builder.startBookmark("My Bookmark"); + builder.write("Contents of MyBookmark."); + builder.endBookmark("My Bookmark"); + + // Bookmarks are stored in this collection. + Assert.assertEquals("My Bookmark", doc.getRange().getBookmarks().get(0).getName()); + + doc.save(getArtifactsDir() + "Bookmarks.Insert.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Bookmarks.Insert.docx"); + + Assert.assertEquals("My Bookmark", doc.getRange().getBookmarks().get(0).getName()); + } + + //ExStart + //ExFor:Bookmark + //ExFor:Bookmark.Name + //ExFor:Bookmark.Text + //ExFor:Bookmark.BookmarkStart + //ExFor:Bookmark.BookmarkEnd + //ExFor:BookmarkStart + //ExFor:BookmarkStart.#ctor + //ExFor:BookmarkEnd + //ExFor:BookmarkEnd.#ctor + //ExFor:BookmarkStart.Accept(DocumentVisitor) + //ExFor:BookmarkEnd.Accept(DocumentVisitor) + //ExFor:BookmarkStart.Bookmark + //ExFor:BookmarkStart.GetText + //ExFor:BookmarkStart.Name + //ExFor:BookmarkEnd.Name + //ExFor:BookmarkCollection + //ExFor:BookmarkCollection.Item(Int32) + //ExFor:BookmarkCollection.Item(String) + //ExFor:BookmarkCollection.GetEnumerator + //ExFor:Range.Bookmarks + //ExFor:DocumentVisitor.VisitBookmarkStart + //ExFor:DocumentVisitor.VisitBookmarkEnd + //ExSummary:Shows how to add bookmarks and update their contents. + @Test //ExSkip + public void createUpdateAndPrintBookmarks() throws Exception { + // Create a document with three bookmarks, then use a custom document visitor implementation to print their contents. + Document doc = createDocumentWithBookmarks(3); + BookmarkCollection bookmarks = doc.getRange().getBookmarks(); + Assert.assertEquals(3, bookmarks.getCount()); //ExSkip + + printAllBookmarkInfo(bookmarks); + + // Bookmarks can be accessed in the bookmark collection by index or name, and their names can be updated. + bookmarks.get(0).setName("{bookmarks[0].Name}_NewName"); + bookmarks.get("MyBookmark_2").setText("Updated text contents of {bookmarks[1].Name}"); + + // Print all bookmarks again to see updated values. + printAllBookmarkInfo(bookmarks); + } + + /// + /// Create a document with a given number of bookmarks. + /// + private static Document createDocumentWithBookmarks(int numberOfBookmarks) throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + for (int i = 1; i <= numberOfBookmarks; i++) { + String bookmarkName = "MyBookmark_" + i; + + builder.write("Text before bookmark."); + builder.startBookmark(bookmarkName); + builder.write(MessageFormat.format("Text inside {0}.", bookmarkName)); + builder.endBookmark(bookmarkName); + builder.writeln("Text after bookmark."); + } + + return doc; + } + + /// + /// Use an iterator and a visitor to print info of every bookmark in the collection. + /// + private static void printAllBookmarkInfo(BookmarkCollection bookmarks) throws Exception { + BookmarkInfoPrinter bookmarkVisitor = new BookmarkInfoPrinter(); + + // Get each bookmark in the collection to accept a visitor that will print its contents. + Iterator enumerator = bookmarks.iterator(); + + while (enumerator.hasNext()) { + Bookmark currentBookmark = enumerator.next(); + + if (currentBookmark != null) { + currentBookmark.getBookmarkStart().accept(bookmarkVisitor); + currentBookmark.getBookmarkEnd().accept(bookmarkVisitor); + + System.out.println(currentBookmark.getBookmarkStart().getText()); + } + } + } + + /// + /// Prints contents of every visited bookmark to the console. + /// + public static class BookmarkInfoPrinter extends DocumentVisitor { + public int visitBookmarkStart(BookmarkStart bookmarkStart) throws Exception { + System.out.println(MessageFormat.format("BookmarkStart name: \"{0}\", Content: \"{1}\"", bookmarkStart.getName(), + bookmarkStart.getBookmark().getText())); + return VisitorAction.CONTINUE; + } + + public int visitBookmarkEnd(BookmarkEnd bookmarkEnd) { + System.out.println(MessageFormat.format("BookmarkEnd name: \"{0}\"", bookmarkEnd.getName())); + return VisitorAction.CONTINUE; + } + } + //ExEnd + + @Test + public void tableColumnBookmarks() throws Exception { + //ExStart + //ExFor:Bookmark.IsColumn + //ExFor:Bookmark.FirstColumn + //ExFor:Bookmark.LastColumn + //ExSummary:Shows how to get information about table column bookmarks. + Document doc = new Document(getMyDir() + "Table column bookmarks.doc"); + for (Bookmark bookmark : doc.getRange().getBookmarks()) { + // If a bookmark encloses columns of a table, it is a table column bookmark, and its IsColumn flag set to true. + System.out.println(MessageFormat.format("Bookmark: {0}{1}", bookmark.getName(), bookmark.isColumn() ? " (Column)" : "")); + if (bookmark.isColumn()) { + Row row = (Row) bookmark.getBookmarkStart().getAncestor(NodeType.ROW); + if (row != null && bookmark.getFirstColumn() < row.getCells().getCount()) { + // Print the contents of the first and last columns enclosed by the bookmark. + System.out.println(row.getCells().get(bookmark.getFirstColumn()).getText().trim()); + System.out.println(row.getCells().get(bookmark.getLastColumn()).getText().trim()); + } + } + } + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + + Bookmark firstTableColumnBookmark = doc.getRange().getBookmarks().get("FirstTableColumnBookmark"); + Bookmark secondTableColumnBookmark = doc.getRange().getBookmarks().get("SecondTableColumnBookmark"); + + Assert.assertTrue(firstTableColumnBookmark.isColumn()); + Assert.assertEquals(firstTableColumnBookmark.getFirstColumn(), 1); + Assert.assertEquals(firstTableColumnBookmark.getLastColumn(), 3); + + Assert.assertTrue(secondTableColumnBookmark.isColumn()); + Assert.assertEquals(secondTableColumnBookmark.getFirstColumn(), 0); + Assert.assertEquals(secondTableColumnBookmark.getLastColumn(), 3); + } + + @Test + public void remove() throws Exception { + //ExStart + //ExFor:BookmarkCollection.Clear + //ExFor:BookmarkCollection.Count + //ExFor:BookmarkCollection.Remove(Bookmark) + //ExFor:BookmarkCollection.Remove(String) + //ExFor:BookmarkCollection.RemoveAt + //ExFor:Bookmark.Remove + //ExSummary:Shows how to remove bookmarks from a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert five bookmarks with text inside their boundaries. + for (int i = 1; i <= 5; i++) { + String bookmarkName = "MyBookmark_" + i; + + builder.startBookmark(bookmarkName); + builder.write(MessageFormat.format("Text inside {0}.", bookmarkName)); + builder.endBookmark(bookmarkName); + builder.insertBreak(BreakType.PARAGRAPH_BREAK); + } + + // This collection stores bookmarks. + BookmarkCollection bookmarks = doc.getRange().getBookmarks(); + + Assert.assertEquals(5, bookmarks.getCount()); + + // There are several ways of removing bookmarks. + // 1 - Calling the bookmark's Remove method: + bookmarks.get("MyBookmark_1").remove(); + + Assert.assertFalse(IterableUtils.matchesAny(bookmarks, b -> b.getName() == "MyBookmark_1")); + + // 2 - Passing the bookmark to the collection's Remove method: + Bookmark bookmark = doc.getRange().getBookmarks().get(0); + doc.getRange().getBookmarks().remove(bookmark); + + Assert.assertFalse(IterableUtils.matchesAny(bookmarks, b -> b.getName() == "MyBookmark_2")); + + // 3 - Removing a bookmark from the collection by name: + doc.getRange().getBookmarks().remove("MyBookmark_3"); + + Assert.assertFalse(IterableUtils.matchesAny(bookmarks, b -> b.getName() == "MyBookmark_3")); + + // 4 - Removing a bookmark at an index in the bookmark collection: + doc.getRange().getBookmarks().removeAt(0); + + Assert.assertFalse(IterableUtils.matchesAny(bookmarks, b -> b.getName() == "MyBookmark_4")); + + // We can clear the entire bookmark collection. + bookmarks.clear(); + + // The text that was inside the bookmarks is still present in the document. + Assert.assertEquals(bookmarks.getCount(), 0); + Assert.assertEquals("Text inside MyBookmark_1.\r" + + "Text inside MyBookmark_2.\r" + + "Text inside MyBookmark_3.\r" + + "Text inside MyBookmark_4.\r" + + "Text inside MyBookmark_5.", doc.getText().trim()); + //ExEnd + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExBookmarksOutlineLevelCollection.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExBookmarksOutlineLevelCollection.java new file mode 100644 index 00000000..6baa3034 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExBookmarksOutlineLevelCollection.java @@ -0,0 +1,100 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.pdf.facades.Bookmarks; +import com.aspose.pdf.facades.PdfBookmarkEditor; +import com.aspose.words.BookmarksOutlineLevelCollection; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.PdfSaveOptions; +import org.testng.Assert; +import org.testng.annotations.Test; + + +@Test +public class ExBookmarksOutlineLevelCollection extends ApiExampleBase { + @Test + public void bookmarkLevels() throws Exception { + //ExStart + //ExFor:BookmarksOutlineLevelCollection + //ExFor:BookmarksOutlineLevelCollection.Add(String, Int32) + //ExFor:BookmarksOutlineLevelCollection.Clear + //ExFor:BookmarksOutlineLevelCollection.Contains(String) + //ExFor:BookmarksOutlineLevelCollection.Count + //ExFor:BookmarksOutlineLevelCollection.IndexOfKey(String) + //ExFor:BookmarksOutlineLevelCollection.Item(Int32) + //ExFor:BookmarksOutlineLevelCollection.Item(String) + //ExFor:BookmarksOutlineLevelCollection.Remove(String) + //ExFor:BookmarksOutlineLevelCollection.RemoveAt(Int32) + //ExFor:OutlineOptions.BookmarksOutlineLevels + //ExSummary:Shows how to set outline levels for bookmarks. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a bookmark with another bookmark nested inside it. + builder.startBookmark("Bookmark 1"); + builder.writeln("Text inside Bookmark 1."); + + builder.startBookmark("Bookmark 2"); + builder.writeln("Text inside Bookmark 1 and 2."); + builder.endBookmark("Bookmark 2"); + + builder.writeln("Text inside Bookmark 1."); + builder.endBookmark("Bookmark 1"); + + // Insert another bookmark. + builder.startBookmark("Bookmark 3"); + builder.writeln("Text inside Bookmark 3."); + builder.endBookmark("Bookmark 3"); + + // When saving to .pdf, bookmarks can be accessed via a drop-down menu and used as anchors by most readers. + // Bookmarks can also have numeric values for outline levels, + // enabling lower level outline entries to hide higher-level child entries when collapsed in the reader. + PdfSaveOptions pdfSaveOptions = new PdfSaveOptions(); + BookmarksOutlineLevelCollection outlineLevels = pdfSaveOptions.getOutlineOptions().getBookmarksOutlineLevels(); + + outlineLevels.add("Bookmark 1", 1); + outlineLevels.add("Bookmark 2", 2); + outlineLevels.add("Bookmark 3", 3); + + Assert.assertEquals(outlineLevels.getCount(), 3); + Assert.assertTrue(outlineLevels.contains("Bookmark 1")); + Assert.assertEquals(outlineLevels.get(0), 1); + Assert.assertEquals(outlineLevels.get("Bookmark 2"), 2); + Assert.assertEquals(outlineLevels.indexOfKey("Bookmark 3"), 2); + + // We can remove two elements so that only the outline level designation for "Bookmark 1" is left. + outlineLevels.removeAt(2); + outlineLevels.remove("Bookmark 2"); + + // There are nine outline levels. Their numbering will be optimized during the save operation. + // In this case, levels "5" and "9" will become "2" and "3". + outlineLevels.add("Bookmark 2", 5); + outlineLevels.add("Bookmark 3", 9); + + doc.save(getArtifactsDir() + "BookmarksOutlineLevelCollection.BookmarkLevels.pdf", pdfSaveOptions); + + // Emptying this collection will preserve the bookmarks and put them all on the same outline level. + outlineLevels.clear(); + //ExEnd + + PdfBookmarkEditor bookmarkEditor = new PdfBookmarkEditor(); + bookmarkEditor.bindPdf(getArtifactsDir() + "BookmarksOutlineLevelCollection.BookmarkLevels.pdf"); + + Bookmarks bookmarks = bookmarkEditor.extractBookmarks(); + + Assert.assertEquals(3, bookmarks.stream().count()); + Assert.assertEquals("Bookmark 1", bookmarks.get(0).getTitle()); + Assert.assertEquals("Bookmark 2", bookmarks.get(1).getTitle()); + Assert.assertEquals("Bookmark 3", bookmarks.get(2).getTitle()); + + bookmarkEditor.close(); + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExBorder.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExBorder.java new file mode 100644 index 00000000..dad6f49a --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExBorder.java @@ -0,0 +1,267 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.awt.*; +import java.text.MessageFormat; + +public class ExBorder extends ApiExampleBase { + @Test + public void fontBorder() throws Exception { + //ExStart + //ExFor:Border + //ExFor:Border.Color + //ExFor:Border.LineWidth + //ExFor:Border.LineStyle + //ExFor:Font.Border + //ExFor:LineStyle + //ExFor:Font + //ExFor:DocumentBuilder.Font + //ExFor:DocumentBuilder.Write(String) + //ExSummary:Shows how to insert a string surrounded by a border into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().getBorder().setColor(Color.GREEN); + builder.getFont().getBorder().setLineWidth(2.5); + builder.getFont().getBorder().setLineStyle(LineStyle.DASH_DOT_STROKER); + + builder.write("Text surrounded by green border."); + + doc.save(getArtifactsDir() + "Border.FontBorder.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Border.FontBorder.docx"); + Border border = doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0).getFont().getBorder(); + + Assert.assertEquals(Color.GREEN.getRGB(), border.getColor().getRGB()); + Assert.assertEquals(2.5d, border.getLineWidth()); + Assert.assertEquals(LineStyle.DASH_DOT_STROKER, border.getLineStyle()); + } + + @Test + public void paragraphTopBorder() throws Exception { + //ExStart + //ExFor:BorderCollection + //ExFor:Border.ThemeColor + //ExFor:Border.TintAndShade + //ExFor:Border + //ExFor:BorderType + //ExFor:ParagraphFormat.Borders + //ExSummary:Shows how to insert a paragraph with a top border. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Border topBorder = builder.getParagraphFormat().getBorders().getByBorderType(BorderType.TOP); + topBorder.setLineWidth(4.0d); + topBorder.setLineStyle(LineStyle.DASH_SMALL_GAP); + // Set ThemeColor only when LineWidth or LineStyle setted. + topBorder.setThemeColor(ThemeColor.ACCENT_1); + topBorder.setTintAndShade(0.25d); + + builder.writeln("Text with a top border."); + + doc.save(getArtifactsDir() + "Border.ParagraphTopBorder.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Border.ParagraphTopBorder.docx"); + Border border = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat().getBorders().getByBorderType(BorderType.TOP); + + Assert.assertEquals(4.0d, border.getLineWidth()); + Assert.assertEquals(LineStyle.DASH_SMALL_GAP, border.getLineStyle()); + Assert.assertEquals(ThemeColor.ACCENT_1, border.getThemeColor()); + Assert.assertEquals(0.25d, border.getTintAndShade(), 0.01); + } + + @Test + public void clearFormatting() throws Exception { + //ExStart + //ExFor:Border.ClearFormatting + //ExFor:Border.IsVisible + //ExSummary:Shows how to remove borders from a paragraph. + Document doc = new Document(getMyDir() + "Borders.docx"); + + // Each paragraph has an individual set of borders. + // We can access the settings for the appearance of these borders via the paragraph format object. + BorderCollection borders = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat().getBorders(); + + Assert.assertEquals(Color.RED.getRGB(), borders.get(0).getColor().getRGB()); + Assert.assertEquals(3.0d, borders.get(0).getLineWidth()); + Assert.assertEquals(LineStyle.SINGLE, borders.get(0).getLineStyle()); + Assert.assertTrue(borders.get(0).isVisible()); + + // We can remove a border at once by running the ClearFormatting method. + // Running this method on every border of a paragraph will remove all its borders. + for (Border border : borders) + border.clearFormatting(); + + Assert.assertEquals(0, borders.get(0).getColor().getRGB()); + Assert.assertEquals(0.0d, borders.get(0).getLineWidth()); + Assert.assertEquals(LineStyle.NONE, borders.get(0).getLineStyle()); + Assert.assertFalse(borders.get(0).isVisible()); + + doc.save(getArtifactsDir() + "Border.ClearFormatting.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Border.ClearFormatting.docx"); + + for (Border testBorder : doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat().getBorders()) { + Assert.assertEquals(0, testBorder.getColor().getRGB()); + Assert.assertEquals(0.0d, testBorder.getLineWidth()); + Assert.assertEquals(LineStyle.NONE, testBorder.getLineStyle()); + } + } + + @Test + public void sharedElements() throws Exception { + //ExStart + //ExFor:Border.Equals(Object) + //ExFor:Border.Equals(Border) + //ExFor:Border.GetHashCode + //ExFor:BorderCollection.Count + //ExFor:BorderCollection.Equals(BorderCollection) + //ExFor:BorderCollection.Item(Int32) + //ExSummary:Shows how border collections can share elements. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Paragraph 1."); + builder.write("Paragraph 2."); + + // Since we used the same border configuration while creating + // these paragraphs, their border collections share the same elements. + BorderCollection firstParagraphBorders = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat().getBorders(); + BorderCollection secondParagraphBorders = builder.getCurrentParagraph().getParagraphFormat().getBorders(); + Assert.assertEquals(6, firstParagraphBorders.getCount()); //ExSkip + + for (int i = 0; i < firstParagraphBorders.getCount(); i++) { + Assert.assertTrue(firstParagraphBorders.get(i).equals(secondParagraphBorders.get(i))); + Assert.assertEquals(firstParagraphBorders.get(i).hashCode(), secondParagraphBorders.get(i).hashCode()); + Assert.assertFalse(firstParagraphBorders.get(i).isVisible()); + } + + for (Border border : secondParagraphBorders) + border.setLineStyle(LineStyle.DOT_DASH); + + // After changing the line style of the borders in just the second paragraph, + // the border collections no longer share the same elements. + for (int i = 0; i < firstParagraphBorders.getCount(); i++) { + Assert.assertFalse(firstParagraphBorders.get(i).equals(secondParagraphBorders.get(i))); + Assert.assertNotEquals(firstParagraphBorders.get(i).hashCode(), secondParagraphBorders.get(i).hashCode()); + + // Changing the appearance of an empty border makes it visible. + Assert.assertTrue(secondParagraphBorders.get(i).isVisible()); + } + + doc.save(getArtifactsDir() + "Border.SharedElements.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Border.SharedElements.docx"); + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + for (Border testBorder : paragraphs.get(0).getParagraphFormat().getBorders()) + Assert.assertEquals(LineStyle.NONE, testBorder.getLineStyle()); + + for (Border testBorder : paragraphs.get(1).getParagraphFormat().getBorders()) + Assert.assertEquals(LineStyle.DOT_DASH, testBorder.getLineStyle()); + } + + @Test + public void horizontalBorders() throws Exception { + //ExStart + //ExFor:BorderCollection.Horizontal + //ExSummary:Shows how to apply settings to horizontal borders to a paragraph's format. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a red horizontal border for the paragraph. Any paragraphs created afterwards will inherit these border settings. + BorderCollection borders = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat().getBorders(); + borders.getHorizontal().setColor(Color.RED); + borders.getHorizontal().setLineStyle(LineStyle.DASH_SMALL_GAP); + borders.getHorizontal().setLineWidth(3.0); + + // Write text to the document without creating a new paragraph afterward. + // Since there is no paragraph underneath, the horizontal border will not be visible. + builder.write("Paragraph above horizontal border."); + + // Once we add a second paragraph, the border of the first paragraph will become visible. + builder.insertParagraph(); + builder.write("Paragraph below horizontal border."); + + doc.save(getArtifactsDir() + "Border.HorizontalBorders.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Border.HorizontalBorders.docx"); + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + Assert.assertEquals(LineStyle.DASH_SMALL_GAP, paragraphs.get(0).getParagraphFormat().getBorders().getByBorderType(BorderType.HORIZONTAL).getLineStyle()); + Assert.assertEquals(LineStyle.DASH_SMALL_GAP, paragraphs.get(1).getParagraphFormat().getBorders().getByBorderType(BorderType.HORIZONTAL).getLineStyle()); + } + + @Test + public void verticalBorders() throws Exception { + //ExStart + //ExFor:BorderCollection.Horizontal + //ExFor:BorderCollection.Vertical + //ExFor:Cell.LastParagraph + //ExSummary:Shows how to apply settings to vertical borders to a table row's format. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a table with red and blue inner borders. + Table table = builder.startTable(); + + for (int i = 0; i < 3; i++) { + builder.insertCell(); + builder.write(MessageFormat.format("Row {0}, Column 1", i + 1)); + builder.insertCell(); + builder.write(MessageFormat.format("Row {0}, Column 2", i + 1)); + + Row row = builder.endRow(); + BorderCollection borders = row.getRowFormat().getBorders(); + + // Adjust the appearance of borders that will appear between rows. + borders.getHorizontal().setColor(Color.RED); + borders.getHorizontal().setLineStyle(LineStyle.DOT); + borders.getHorizontal().setLineWidth(2.0d); + + // Adjust the appearance of borders that will appear between cells. + borders.getVertical().setColor(Color.BLUE); + borders.getVertical().setLineStyle(LineStyle.DOT); + borders.getVertical().setLineWidth(2.0d); + } + + // A row format, and a cell's inner paragraph use different border settings. + Border border = table.getFirstRow().getFirstCell().getLastParagraph().getParagraphFormat().getBorders().getVertical(); + + Assert.assertEquals(0, border.getColor().getRGB()); + Assert.assertEquals(0.0d, border.getLineWidth()); + Assert.assertEquals(LineStyle.NONE, border.getLineStyle()); + + doc.save(getArtifactsDir() + "Border.VerticalBorders.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Border.VerticalBorders.docx"); + table = doc.getFirstSection().getBody().getTables().get(0); + + for (Row row : (Iterable) table.getChildNodes(NodeType.ROW, true)) { + Assert.assertEquals(Color.RED.getRGB(), row.getRowFormat().getBorders().getHorizontal().getColor().getRGB()); + Assert.assertEquals(LineStyle.DOT, row.getRowFormat().getBorders().getHorizontal().getLineStyle()); + Assert.assertEquals(2.0d, row.getRowFormat().getBorders().getHorizontal().getLineWidth()); + + Assert.assertEquals(Color.BLUE.getRGB(), row.getRowFormat().getBorders().getVertical().getColor().getRGB()); + Assert.assertEquals(LineStyle.DOT, row.getRowFormat().getBorders().getVertical().getLineStyle()); + Assert.assertEquals(2.0d, row.getRowFormat().getBorders().getVertical().getLineWidth()); + } + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExBorderCollection.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExBorderCollection.java new file mode 100644 index 00000000..d2185a28 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExBorderCollection.java @@ -0,0 +1,89 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.awt.*; +import java.util.Iterator; + +public class ExBorderCollection extends ApiExampleBase { + @Test + public void getBordersEnumerator() throws Exception { + //ExStart + //ExFor:BorderCollection.GetEnumerator + //ExSummary:Shows how to iterate over and edit all of the borders in a paragraph format object. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Configure the builder's paragraph format settings to create a green wave border on all sides. + BorderCollection borders = builder.getParagraphFormat().getBorders(); + + Iterator enumerator = borders.iterator(); + while (enumerator.hasNext()) { + Border border = enumerator.next(); + border.setColor(Color.green); + border.setLineStyle(LineStyle.WAVE); + border.setLineWidth(3.0); + } + + // Insert a paragraph. Our border settings will determine the appearance of its border. + builder.writeln("Hello world!"); + + doc.save(getArtifactsDir() + "BorderCollection.GetBordersEnumerator.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "BorderCollection.GetBordersEnumerator.docx"); + + for (Border border : doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat().getBorders()) { + Assert.assertEquals(Color.green.getRGB(), border.getColor().getRGB()); + Assert.assertEquals(LineStyle.WAVE, border.getLineStyle()); + Assert.assertEquals(3.0d, border.getLineWidth()); + } + } + + @Test + public void removeAllBorders() throws Exception { + //ExStart + //ExFor:BorderCollection.ClearFormatting + //ExSummary:Shows how to remove all borders from all paragraphs in a document. + Document doc = new Document(getMyDir() + "Borders.docx"); + + // The first paragraph of this document has visible borders with these settings. + BorderCollection firstParagraphBorders = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat().getBorders(); + + Assert.assertEquals(Color.RED.getRGB(), firstParagraphBorders.getColor().getRGB()); + Assert.assertEquals(LineStyle.SINGLE, firstParagraphBorders.getLineStyle()); + Assert.assertEquals(3.0d, firstParagraphBorders.getLineWidth()); + + // Use the "ClearFormatting" method on each paragraph to remove all borders. + for (Paragraph paragraph : doc.getFirstSection().getBody().getParagraphs()) { + paragraph.getParagraphFormat().getBorders().clearFormatting(); + + for (Border border : paragraph.getParagraphFormat().getBorders()) { + Assert.assertEquals(0, border.getColor().getRGB()); + Assert.assertEquals(LineStyle.NONE, border.getLineStyle()); + Assert.assertEquals(0.0d, border.getLineWidth()); + } + } + + doc.save(getArtifactsDir() + "BorderCollection.RemoveAllBorders.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "BorderCollection.RemoveAllBorders.docx"); + + for (Border border : doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat().getBorders()) { + Assert.assertEquals(0, border.getColor().getRGB()); + Assert.assertEquals(LineStyle.NONE, border.getLineStyle()); + Assert.assertEquals(0.0d, border.getLineWidth()); + } + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExBuildVersion.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExBuildVersion.java new file mode 100644 index 00000000..409bfb7b --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExBuildVersion.java @@ -0,0 +1,32 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.BuildVersionInfo; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.text.MessageFormat; +import java.util.regex.Pattern; + +public class ExBuildVersion extends ApiExampleBase { + @Test + public void printBuildVersionInfo() { + //ExStart + //ExFor:BuildVersionInfo + //ExFor:BuildVersionInfo.Product + //ExFor:BuildVersionInfo.Version + //ExSummary:Shows how to display information about your installed version of Aspose.Words. + System.out.println(MessageFormat.format("I am currently using {0}, version number {1}!", BuildVersionInfo.getProduct(), BuildVersionInfo.getVersion())); + //ExEnd + + Assert.assertEquals("Aspose.Words for Java", BuildVersionInfo.getProduct()); + Assert.assertTrue(Pattern.compile("[0-9]{2}.[0-9]{1,2}").matcher(BuildVersionInfo.getVersion()).find()); + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExBuildingBlocks.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExBuildingBlocks.java new file mode 100644 index 00000000..576e6000 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExBuildingBlocks.java @@ -0,0 +1,249 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.UUID; + +@Test +public class ExBuildingBlocks extends ApiExampleBase { + //ExStart + //ExFor:Document.GlossaryDocument + //ExFor:BuildingBlock + //ExFor:BuildingBlock.#ctor(GlossaryDocument) + //ExFor:BuildingBlock.Accept(DocumentVisitor) + //ExFor:BuildingBlock.AcceptStart(DocumentVisitor) + //ExFor:BuildingBlock.AcceptEnd(DocumentVisitor) + //ExFor:BuildingBlock.Behavior + //ExFor:BuildingBlock.Category + //ExFor:BuildingBlock.Description + //ExFor:BuildingBlock.FirstSection + //ExFor:BuildingBlock.Gallery + //ExFor:BuildingBlock.Guid + //ExFor:BuildingBlock.LastSection + //ExFor:BuildingBlock.Name + //ExFor:BuildingBlock.Sections + //ExFor:BuildingBlock.Type + //ExFor:BuildingBlockBehavior + //ExFor:BuildingBlockType + //ExSummary:Shows how to add a custom building block to a document. + @Test //ExSkip + public void createAndInsert() throws Exception { + // A document's glossary document stores building blocks. + Document doc = new Document(); + GlossaryDocument glossaryDoc = new GlossaryDocument(); + doc.setGlossaryDocument(glossaryDoc); + + // Create a building block, name it, and then add it to the glossary document. + BuildingBlock block = new BuildingBlock(glossaryDoc); + block.setName("Custom Block"); + + glossaryDoc.appendChild(block); + + // All new building block GUIDs have the same zero value by default, and we can give them a new unique value. + Assert.assertEquals(block.getGuid().toString(), "00000000-0000-0000-0000-000000000000"); + + block.setGuid(UUID.randomUUID()); + + // The following properties categorize building blocks + // in the menu we can access in Microsoft Word via "Insert" -> "Quick Parts" -> "Building Blocks Organizer". + Assert.assertEquals(block.getCategory(), "(Empty Category)"); + Assert.assertEquals(block.getType(), BuildingBlockType.NONE); + Assert.assertEquals(block.getGallery(), BuildingBlockGallery.ALL); + Assert.assertEquals(block.getBehavior(), BuildingBlockBehavior.CONTENT); + + // Before we can add this building block to our document, we will need to give it some contents, + // which we will do using a document visitor. This visitor will also set a category, gallery, and behavior. + BuildingBlockVisitor visitor = new BuildingBlockVisitor(glossaryDoc); + // Visit start/end of the BuildingBlock. + block.accept(visitor); + + // We can access the block that we just made from the glossary document. + BuildingBlock customBlock = glossaryDoc.getBuildingBlock(BuildingBlockGallery.QUICK_PARTS, + "My custom building blocks", "Custom Block"); + + // The block itself is a section that contains the text. + Assert.assertEquals(MessageFormat.format("Text inside {0}\f", customBlock.getName()), customBlock.getFirstSection().getBody().getFirstParagraph().getText()); + Assert.assertEquals(customBlock.getFirstSection(), customBlock.getLastSection()); + Assert.assertEquals("My custom building blocks", customBlock.getCategory()); //ExSkip + Assert.assertEquals(BuildingBlockType.NONE, customBlock.getType()); //ExSkip + Assert.assertEquals(BuildingBlockGallery.QUICK_PARTS, customBlock.getGallery()); //ExSkip + Assert.assertEquals(BuildingBlockBehavior.PARAGRAPH, customBlock.getBehavior()); //ExSkip + + // Now, we can insert it into the document as a new section. + doc.appendChild(doc.importNode(customBlock.getFirstSection(), true)); + + // We can also find it in Microsoft Word's Building Blocks Organizer and place it manually. + doc.save(getArtifactsDir() + "BuildingBlocks.CreateAndInsert.dotx"); + } + + /// + /// Sets up a visited building block to be inserted into the document as a quick part and adds text to its contents. + /// + public static class BuildingBlockVisitor extends DocumentVisitor { + public BuildingBlockVisitor(final GlossaryDocument ownerGlossaryDoc) { + mBuilder = new StringBuilder(); + mGlossaryDoc = ownerGlossaryDoc; + } + + public int visitBuildingBlockStart(final BuildingBlock block) { + // Configure the building block as a quick part, and add properties used by Building Blocks Organizer. + block.setBehavior(BuildingBlockBehavior.PARAGRAPH); + block.setCategory("My custom building blocks"); + block.setDescription("Using this block in the Quick Parts section of word will place its contents at the cursor."); + block.setGallery(BuildingBlockGallery.QUICK_PARTS); + + // Add a section with text. + // Inserting the block into the document will append this section with its child nodes at the location. + Section section = new Section(mGlossaryDoc); + block.appendChild(section); + block.getFirstSection().ensureMinimum(); + + Run run = new Run(mGlossaryDoc, "Text inside " + block.getName()); + block.getFirstSection().getBody().getFirstParagraph().appendChild(run); + + return VisitorAction.CONTINUE; + } + + public int visitBuildingBlockEnd(final BuildingBlock block) { + mBuilder.append("Visited " + block.getName() + "\r\n"); + return VisitorAction.CONTINUE; + } + + private final StringBuilder mBuilder; + private final GlossaryDocument mGlossaryDoc; + } + //ExEnd + + //ExStart + //ExFor:GlossaryDocument + //ExFor:GlossaryDocument.Accept(DocumentVisitor) + //ExFor:GlossaryDocument.AcceptStart(DocumentVisitor) + //ExFor:GlossaryDocument.AcceptEnd(DocumentVisitor) + //ExFor:GlossaryDocument.BuildingBlocks + //ExFor:GlossaryDocument.FirstBuildingBlock + //ExFor:GlossaryDocument.GetBuildingBlock(BuildingBlockGallery,String,String) + //ExFor:GlossaryDocument.LastBuildingBlock + //ExFor:BuildingBlockCollection + //ExFor:BuildingBlockCollection.Item(Int32) + //ExFor:BuildingBlockCollection.ToArray + //ExFor:BuildingBlockGallery + //ExFor:DocumentVisitor.VisitBuildingBlockEnd(BuildingBlock) + //ExFor:DocumentVisitor.VisitBuildingBlockStart(BuildingBlock) + //ExFor:DocumentVisitor.VisitGlossaryDocumentEnd(GlossaryDocument) + //ExFor:DocumentVisitor.VisitGlossaryDocumentStart(GlossaryDocument) + //ExSummary:Shows ways of accessing building blocks in a glossary document. + @Test //ExSkip + public void glossaryDocument() throws Exception { + Document doc = new Document(); + GlossaryDocument glossaryDoc = new GlossaryDocument(); + + glossaryDoc.appendChild(createNewBuildingBlock(glossaryDoc, "Block 1")); + glossaryDoc.appendChild(createNewBuildingBlock(glossaryDoc, "Block 2")); + glossaryDoc.appendChild(createNewBuildingBlock(glossaryDoc, "Block 3")); + glossaryDoc.appendChild(createNewBuildingBlock(glossaryDoc, "Block 4")); + glossaryDoc.appendChild(createNewBuildingBlock(glossaryDoc, "Block 5")); + + Assert.assertEquals(glossaryDoc.getBuildingBlocks().getCount(), 5); + + doc.setGlossaryDocument(glossaryDoc); + + // There are various ways of accessing building blocks. + // 1 - Get the first/last building blocks in the collection: + Assert.assertEquals("Block 1", glossaryDoc.getFirstBuildingBlock().getName()); + Assert.assertEquals("Block 5", glossaryDoc.getLastBuildingBlock().getName()); + + // 2 - Get a building block by index: + Assert.assertEquals("Block 2", glossaryDoc.getBuildingBlocks().get(1).getName()); + Assert.assertEquals("Block 3", glossaryDoc.getBuildingBlocks().toArray()[2].getName()); + + // 3 - Get the first building block that matches a gallery, name and category: + Assert.assertEquals("Block 4", + glossaryDoc.getBuildingBlock(BuildingBlockGallery.ALL, "(Empty Category)", "Block 4").getName()); + + // We will do that using a custom visitor, + // which will give every BuildingBlock in the GlossaryDocument a unique GUID + GlossaryDocVisitor visitor = new GlossaryDocVisitor(); + // Visit start/end of the Glossary document. + glossaryDoc.accept(visitor); + // Visit only start of the Glossary document. + glossaryDoc.acceptStart(visitor); + // Visit only end of the Glossary document. + glossaryDoc.acceptEnd(visitor); + Assert.assertEquals(5, visitor.getDictionary().size()); //ExSkip + + System.out.println(visitor.getText()); + + // In Microsoft Word, we can access the building blocks via "Insert" -> "Quick Parts" -> "Building Blocks Organizer". + doc.save(getArtifactsDir() + "BuildingBlocks.GlossaryDocument.dotx"); + } + + public static BuildingBlock createNewBuildingBlock(final GlossaryDocument glossaryDoc, final String buildingBlockName) { + BuildingBlock buildingBlock = new BuildingBlock(glossaryDoc); + buildingBlock.setName(buildingBlockName); + + return buildingBlock; + } + + /// + /// Gives each building block in a visited glossary document a unique GUID. + /// Stores the GUID-building block pairs in a dictionary. + /// + public static class GlossaryDocVisitor extends DocumentVisitor { + public GlossaryDocVisitor() { + mBlocksByGuid = new HashMap<>(); + mBuilder = new StringBuilder(); + } + + public String getText() { + return mBuilder.toString(); + } + + public HashMap getDictionary() { + return mBlocksByGuid; + } + + public int visitGlossaryDocumentStart(final GlossaryDocument glossary) { + mBuilder.append("Glossary document found!\n"); + return VisitorAction.CONTINUE; + } + + public int visitGlossaryDocumentEnd(final GlossaryDocument glossary) { + mBuilder.append("Reached end of glossary!\n"); + mBuilder.append("BuildingBlocks found: " + mBlocksByGuid.size() + "\r\n"); + return VisitorAction.CONTINUE; + } + + public int visitBuildingBlockStart(final BuildingBlock block) { + Assert.assertEquals("00000000-0000-0000-0000-000000000000", block.getGuid().toString()); //ExSkip + block.setGuid(UUID.randomUUID()); + mBlocksByGuid.put(block.getGuid(), block); + return VisitorAction.CONTINUE; + } + + public int visitBuildingBlockEnd(final BuildingBlock block) { + mBuilder.append("\tVisited block \"" + block.getName() + "\"" + "\r\n"); + mBuilder.append("\t Type: " + block.getType() + "\r\n"); + mBuilder.append("\t Gallery: " + block.getGallery() + "\r\n"); + mBuilder.append("\t Behavior: " + block.getBehavior() + "\r\n"); + mBuilder.append("\t Description: " + block.getDescription() + "\r\n"); + + return VisitorAction.CONTINUE; + } + + private final HashMap mBlocksByGuid; + private final StringBuilder mBuilder; + } + //ExEnd +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExCellFormat.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExCellFormat.java new file mode 100644 index 00000000..88dbc081 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExCellFormat.java @@ -0,0 +1,137 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.apache.commons.lang.StringUtils; +import org.testng.Assert; +import org.testng.annotations.Test; + +public class ExCellFormat extends ApiExampleBase { + @Test + public void verticalMerge() throws Exception { + //ExStart + //ExFor:DocumentBuilder.EndRow + //ExFor:CellMerge + //ExFor:CellFormat.VerticalMerge + //ExSummary:Shows how to merge table cells vertically. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a cell into the first column of the first row. + // This cell will be the first in a range of vertically merged cells. + builder.insertCell(); + builder.getCellFormat().setVerticalMerge(CellMerge.FIRST); + builder.write("Text in merged cells."); + + // Insert a cell into the second column of the first row, then end the row. + // Also, configure the builder to disable vertical merging in created cells. + builder.insertCell(); + builder.getCellFormat().setVerticalMerge(CellMerge.NONE); + builder.write("Text in unmerged cell."); + builder.endRow(); + + // Insert a cell into the first column of the second row. + // Instead of adding text contents, we will merge this cell with the first cell that we added directly above. + builder.insertCell(); + builder.getCellFormat().setVerticalMerge(CellMerge.PREVIOUS); + + // Insert another independent cell in the second column of the second row. + builder.insertCell(); + builder.getCellFormat().setVerticalMerge(CellMerge.NONE); + builder.write("Text in unmerged cell."); + builder.endRow(); + builder.endTable(); + + doc.save(getArtifactsDir() + "CellFormat.VerticalMerge.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "CellFormat.VerticalMerge.docx"); + Table table = doc.getFirstSection().getBody().getTables().get(0); + + Assert.assertEquals(CellMerge.FIRST, table.getRows().get(0).getCells().get(0).getCellFormat().getVerticalMerge()); + Assert.assertEquals(CellMerge.PREVIOUS, table.getRows().get(1).getCells().get(0).getCellFormat().getVerticalMerge()); + Assert.assertEquals("Text in merged cells.", StringUtils.strip(table.getRows().get(0).getCells().get(0).getText(), String.valueOf('\u0007'))); + Assert.assertNotEquals(table.getRows().get(0).getCells().get(0).getText(), table.getRows().get(1).getCells().get(0).getText()); + } + + @Test + public void horizontalMerge() throws Exception { + //ExStart + //ExFor:CellMerge + //ExFor:CellFormat.HorizontalMerge + //ExSummary:Shows how to merge table cells horizontally. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a cell into the first column of the first row. + // This cell will be the first in a range of horizontally merged cells. + builder.insertCell(); + builder.getCellFormat().setHorizontalMerge(CellMerge.FIRST); + builder.write("Text in merged cells."); + + // Insert a cell into the second column of the first row. Instead of adding text contents, + // we will merge this cell with the first cell that we added directly to the left. + builder.insertCell(); + builder.getCellFormat().setHorizontalMerge(CellMerge.PREVIOUS); + builder.endRow(); + + // Insert two more unmerged cells to the second row. + builder.getCellFormat().setHorizontalMerge(CellMerge.NONE); + builder.insertCell(); + builder.write("Text in unmerged cell."); + builder.insertCell(); + builder.write("Text in unmerged cell."); + builder.endRow(); + builder.endTable(); + + doc.save(getArtifactsDir() + "CellFormat.HorizontalMerge.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "CellFormat.HorizontalMerge.docx"); + Table table = doc.getFirstSection().getBody().getTables().get(0); + + Assert.assertEquals(1, table.getRows().get(0).getCells().getCount()); + Assert.assertEquals(CellMerge.NONE, table.getRows().get(0).getCells().get(0).getCellFormat().getHorizontalMerge()); + + Assert.assertEquals("Text in merged cells.", StringUtils.strip(table.getRows().get(0).getCells().get(0).getText(), String.valueOf('\u0007'))); + } + + @Test + public void padding() throws Exception { + //ExStart + //ExFor:CellFormat.SetPaddings + //ExSummary:Shows how to pad the contents of a cell with whitespace. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Set a padding distance (in points) between the border and the text contents + // of each table cell we create with the document builder. + builder.getCellFormat().setPaddings(5.0, 10.0, 40.0, 50.0); + + // Create a table with one cell whose contents will have whitespace padding. + builder.startTable(); + builder.insertCell(); + builder.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " + + "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."); + + doc.save(getArtifactsDir() + "CellFormat.Padding.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "CellFormat.Padding.docx"); + + Table table = doc.getFirstSection().getBody().getTables().get(0); + Cell cell = table.getRows().get(0).getCells().get(0); + + Assert.assertEquals(cell.getCellFormat().getLeftPadding(), 5.0); + Assert.assertEquals(cell.getCellFormat().getTopPadding(), 10.0); + Assert.assertEquals(cell.getCellFormat().getRightPadding(), 40.0); + Assert.assertEquals(cell.getCellFormat().getBottomPadding(), 50.0); + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExCertificateHolder.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExCertificateHolder.java new file mode 100644 index 00000000..87b7e2e2 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExCertificateHolder.java @@ -0,0 +1,37 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.CertificateHolder; +import org.testng.annotations.Test; + +import java.io.FileInputStream; + +@Test +public class ExCertificateHolder extends ApiExampleBase { + @Test + public void create() throws Exception { + //ExStart + //ExFor:CertificateHolder.Create(Byte[], SecureString) + //ExFor:CertificateHolder.Create(Byte[], String) + //ExFor:CertificateHolder.Create(String, String, String) + //ExSummary:Shows how to create CertificateHolder objects. + // Below are four ways of creating CertificateHolder objects. + // 1 - Load a PKCS #12 file into a byte array and apply its password: + byte[] certBytes = DocumentHelper.getBytesFromStream(new FileInputStream(getMyDir() + "morzal.pfx")); + CertificateHolder.create(certBytes, "aw"); + + // 2 - Use a valid alias: + CertificateHolder.create(getMyDir() + "morzal.pfx", "aw", "c20be521-11ea-4976-81ed-865fbbfc9f24"); + + // 3 - Pass "null" as the alias in order to use the first available alias that returns a private key: + CertificateHolder.create(getMyDir() + "morzal.pfx", "aw", null); + //ExEnd + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExCharts.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExCharts.java new file mode 100644 index 00000000..64d592f7 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExCharts.java @@ -0,0 +1,2604 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import com.aspose.words.Shape; +import org.apache.commons.collections4.IterableUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.awt.*; +import java.text.DecimalFormatSymbols; +import java.text.MessageFormat; +import java.text.NumberFormat; +import java.util.Date; +import java.util.Iterator; +import java.util.Locale; + +@Test +public class ExCharts extends ApiExampleBase { + @Test + public void chartTitle() throws Exception { + //ExStart:ChartTitle + //GistId:6d898be16b796fcf7448ad3bfe18e51c + //ExFor:Chart + //ExFor:Chart.Title + //ExFor:ChartTitle + //ExFor:ChartTitle.Overlay + //ExFor:ChartTitle.Show + //ExFor:ChartTitle.Text + //ExFor:ChartTitle.Font + //ExSummary:Shows how to insert a chart and set a title. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a chart shape with a document builder and get its chart. + Shape chartShape = builder.insertChart(ChartType.BAR, 400.0, 300.0); + Chart chart = chartShape.getChart(); + + // Use the "Title" property to give our chart a title, which appears at the top center of the chart area. + ChartTitle title = chart.getTitle(); + title.setText("My Chart"); + title.getFont().setSize(15.0); + title.getFont().setColor(Color.BLUE); + + // Set the "Show" property to "true" to make the title visible. + title.setShow(true); + + // Set the "Overlay" property to "true" Give other chart elements more room by allowing them to overlap the title + title.setOverlay(true); + + doc.save(getArtifactsDir() + "Charts.ChartTitle.docx"); + //ExEnd:ChartTitle + + doc = new Document(getArtifactsDir() + "Charts.ChartTitle.docx"); + chartShape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(ShapeType.NON_PRIMITIVE, chartShape.getShapeType()); + Assert.assertTrue(chartShape.hasChart()); + + title = chartShape.getChart().getTitle(); + + Assert.assertEquals("My Chart", title.getText()); + Assert.assertTrue(title.getOverlay()); + Assert.assertTrue(title.getShow()); + } + + @Test + public void dataLabelNumberFormat() throws Exception { + //ExStart + //ExFor:ChartDataLabelCollection.NumberFormat + //ExFor:ChartDataLabelCollection.Font + //ExFor:ChartNumberFormat.FormatCode + //ExFor:ChartSeries.HasDataLabels + //ExSummary:Shows how to enable and configure data labels for a chart series. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Add a line chart, then clear its demo data series to start with a clean chart, + // and then set a title. + Shape shape = builder.insertChart(ChartType.LINE, 500.0, 300.0); + Chart chart = shape.getChart(); + chart.getSeries().clear(); + chart.getTitle().setText("Monthly sales report"); + + // Insert a custom chart series with months as categories for the X-axis, + // and respective decimal amounts for the Y-axis. + ChartSeries series = chart.getSeries().add("Revenue", + new String[]{"January", "February", "March"}, + new double[]{25.611d, 21.439d, 33.750d}); + + // Enable data labels, and then apply a custom number format for values displayed in the data labels. + // This format will treat displayed decimal values as millions of US Dollars. + series.hasDataLabels(true); + ChartDataLabelCollection dataLabels = series.getDataLabels(); + dataLabels.setShowValue(true); + dataLabels.getNumberFormat().setFormatCode("\"US$\" #,##0.000\"M\""); + dataLabels.getFont().setSize(12.0); + + doc.save(getArtifactsDir() + "Charts.DataLabelNumberFormat.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Charts.DataLabelNumberFormat.docx"); + series = ((Shape) doc.getChild(NodeType.SHAPE, 0, true)).getChart().getSeries().get(0); + + Assert.assertTrue(series.hasDataLabels()); + Assert.assertTrue(series.getDataLabels().getShowValue()); + Assert.assertEquals("\"US$\" #,##0.000\"M\"", series.getDataLabels().getNumberFormat().getFormatCode()); + } + + @Test + public void axisProperties() throws Exception { + //ExStart + //ExFor:ChartAxis + //ExFor:ChartAxis.CategoryType + //ExFor:ChartAxis.Crosses + //ExFor:ChartAxis.ReverseOrder + //ExFor:ChartAxis.MajorTickMark + //ExFor:ChartAxis.MinorTickMark + //ExFor:ChartAxis.MajorUnit + //ExFor:ChartAxis.MinorUnit + //ExFor:ChartAxis.Document + //ExFor:ChartAxis.TickLabels + //ExFor:ChartAxis.Format + //ExFor:AxisTickLabels + //ExFor:AxisTickLabels.Offset + //ExFor:AxisTickLabels.Position + //ExFor:AxisTickLabels.IsAutoSpacing + //ExFor:AxisTickLabels.Alignment + //ExFor:AxisTickLabels.Font + //ExFor:AxisTickLabels.Spacing + //ExFor:ChartAxis.TickMarkSpacing + //ExFor:AxisCategoryType + //ExFor:AxisCrosses + //ExFor:Chart.AxisX + //ExFor:Chart.AxisY + //ExFor:Chart.AxisZ + //ExSummary:Shows how to insert a chart and modify the appearance of its axes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 500.0, 300.0); + Chart chart = shape.getChart(); + + // Clear the chart's demo data series to start with a clean chart. + chart.getSeries().clear(); + + // Insert a chart series with categories for the X-axis and respective numeric values for the Y-axis. + chart.getSeries().add("Aspose Test Series", + new String[]{"Word", "PDF", "Excel", "GoogleDocs", "Note"}, + new double[]{640.0, 320.0, 280.0, 120.0, 150.0}); + + // Chart axes have various options that can change their appearance, + // such as their direction, major/minor unit ticks, and tick marks. + ChartAxis xAxis = chart.getAxisX(); + xAxis.setCategoryType(AxisCategoryType.CATEGORY); + xAxis.setCrosses(AxisCrosses.MINIMUM); + xAxis.setReverseOrder(false); + xAxis.setMajorTickMark(AxisTickMark.INSIDE); + xAxis.setMinorTickMark(AxisTickMark.CROSS); + xAxis.setMajorUnit(10.0d); + xAxis.setMinorUnit(15.0d); + xAxis.getTickLabels().setOffset(50); + xAxis.getTickLabels().setPosition(AxisTickLabelPosition.LOW); + xAxis.getTickLabels().isAutoSpacing(false); + xAxis.setTickMarkSpacing(1); + + Assert.assertEquals(doc, xAxis.getDocument()); + + ChartAxis yAxis = chart.getAxisY(); + yAxis.setCategoryType(AxisCategoryType.AUTOMATIC); + yAxis.setCrosses(AxisCrosses.MAXIMUM); + yAxis.setReverseOrder(true); + yAxis.setMajorTickMark(AxisTickMark.INSIDE); + yAxis.setMinorTickMark(AxisTickMark.CROSS); + yAxis.setMajorUnit(100.0d); + yAxis.setMinorUnit(20.0d); + yAxis.getTickLabels().setPosition(AxisTickLabelPosition.NEXT_TO_AXIS); + yAxis.getTickLabels().setAlignment(ParagraphAlignment.CENTER); + yAxis.getTickLabels().getFont().setColor(Color.RED); + yAxis.getTickLabels().setSpacing(1); + + // Column charts do not have a Z-axis. + Assert.assertNull(chart.getAxisZ()); + + doc.save(getArtifactsDir() + "Charts.AxisProperties.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Charts.AxisProperties.docx"); + chart = ((Shape) doc.getChild(NodeType.SHAPE, 0, true)).getChart(); + + Assert.assertEquals(AxisCategoryType.CATEGORY, chart.getAxisX().getCategoryType()); + Assert.assertEquals(AxisCrosses.MINIMUM, chart.getAxisX().getCrosses()); + Assert.assertFalse(chart.getAxisX().getReverseOrder()); + Assert.assertEquals(AxisTickMark.INSIDE, chart.getAxisX().getMajorTickMark()); + Assert.assertEquals(AxisTickMark.CROSS, chart.getAxisX().getMinorTickMark()); + Assert.assertEquals(1.0d, chart.getAxisX().getMajorUnit()); + Assert.assertEquals(0.5d, chart.getAxisX().getMinorUnit()); + Assert.assertEquals(50, chart.getAxisX().getTickLabels().getOffset()); + Assert.assertEquals(AxisTickLabelPosition.LOW, chart.getAxisX().getTickLabels().getPosition()); + Assert.assertFalse(chart.getAxisX().getTickLabels().isAutoSpacing()); + Assert.assertEquals(1, chart.getAxisX().getTickMarkSpacing()); + Assert.assertTrue(chart.getAxisX().getFormat().isDefined()); + + Assert.assertEquals(AxisCategoryType.CATEGORY, chart.getAxisY().getCategoryType()); + Assert.assertEquals(AxisCrosses.MAXIMUM, chart.getAxisY().getCrosses()); + Assert.assertTrue(chart.getAxisY().getReverseOrder()); + Assert.assertEquals(AxisTickMark.INSIDE, chart.getAxisY().getMajorTickMark()); + Assert.assertEquals(AxisTickMark.CROSS, chart.getAxisY().getMinorTickMark()); + Assert.assertEquals(100.0d, chart.getAxisY().getMajorUnit()); + Assert.assertEquals(20.0d, chart.getAxisY().getMinorUnit()); + Assert.assertEquals(AxisTickLabelPosition.NEXT_TO_AXIS, chart.getAxisY().getTickLabels().getPosition()); + Assert.assertEquals(ParagraphAlignment.CENTER, chart.getAxisY().getTickLabels().getAlignment()); + Assert.assertEquals(Color.RED.getRGB(), chart.getAxisY().getTickLabels().getFont().getColor().getRGB()); + Assert.assertEquals(1, chart.getAxisY().getTickLabels().getSpacing()); + Assert.assertTrue(chart.getAxisY().getFormat().isDefined()); + } + + @Test + public void axisCollection() throws Exception + { + //ExStart + //ExFor:ChartAxisCollection + //ExFor:Chart.Axes + //ExSummary:Shows how to work with axes collection. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 500.0, 300.0); + Chart chart = shape.getChart(); + + // Hide the major grid lines on the primary and secondary Y axes. + for (ChartAxis axis : chart.getAxes()) + { + if (axis.getType() == ChartAxisType.VALUE) + axis.hasMajorGridlines(false); + } + + doc.save(getArtifactsDir() + "Charts.AxisCollection.docx"); + //ExEnd + } + + @Test + public void dateTimeValues() throws Exception { + //ExStart + //ExFor:AxisBound + //ExFor:AxisBound.#ctor(Double) + //ExFor:AxisBound.#ctor(DateTime) + //ExFor:AxisScaling.Minimum + //ExFor:AxisScaling.Maximum + //ExFor:ChartAxis.Scaling + //ExFor:AxisTickMark + //ExFor:AxisTickLabelPosition + //ExFor:AxisTimeUnit + //ExFor:ChartAxis.BaseTimeUnit + //ExFor:ChartAxis.HasMajorGridlines + //ExFor:ChartAxis.HasMinorGridlines + //ExSummary:Shows how to insert chart with date/time values. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.LINE, 500.0, 300.0); + Chart chart = shape.getChart(); + + // Clear the chart's demo data series to start with a clean chart. + chart.getSeries().clear(); + + // Add a custom series containing date/time values for the X-axis, and respective decimal values for the Y-axis. + chart.getSeries().add("Aspose Test Series", + new Date[] + { + DocumentHelper.createDate(2017, 11, 6), DocumentHelper.createDate(2017, 11, 9), DocumentHelper.createDate(2017, 11, 15), + DocumentHelper.createDate(2017, 11, 21), DocumentHelper.createDate(2017, 11, 25), DocumentHelper.createDate(2017, 11, 29) + }, + new double[]{1.2, 0.3, 2.1, 2.9, 4.2, 5.3}); + + + // Set lower and upper bounds for the X-axis. + ChartAxis xAxis = chart.getAxisX(); + Date datetimeMin = DocumentHelper.createDate(2017, 11, 5); + xAxis.getScaling().setMinimum(new AxisBound(datetimeMin)); + Date datetimeMax = DocumentHelper.createDate(2017, 12, 3); + xAxis.getScaling().setMaximum(new AxisBound(datetimeMax)); + + // Set the major units of the X-axis to a week, and the minor units to a day. + xAxis.setBaseTimeUnit(AxisTimeUnit.DAYS); + xAxis.setMajorUnit(7.0d); + xAxis.setMajorTickMark(AxisTickMark.CROSS); + xAxis.setMinorUnit(1.0d); + xAxis.setMinorTickMark(AxisTickMark.OUTSIDE); + xAxis.hasMajorGridlines(true); + xAxis.hasMinorGridlines(true); + + // Define Y-axis properties for decimal values. + ChartAxis yAxis = chart.getAxisY(); + yAxis.getTickLabels().setPosition(AxisTickLabelPosition.HIGH); + yAxis.setMajorUnit(100.0d); + yAxis.setMinorUnit(50.0d); + yAxis.getDisplayUnit().setUnit(AxisBuiltInUnit.HUNDREDS); + yAxis.getScaling().setMinimum(new AxisBound(100.0)); + yAxis.getScaling().setMaximum(new AxisBound(700.0)); + yAxis.hasMajorGridlines(true); + yAxis.hasMinorGridlines(true); + + doc.save(getArtifactsDir() + "Charts.DateTimeValues.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Charts.DateTimeValues.docx"); + chart = ((Shape) doc.getChild(NodeType.SHAPE, 0, true)).getChart(); + + Assert.assertEquals(datetimeMin, chart.getAxisX().getScaling().getMinimum().getValueAsDate()); + Assert.assertEquals(datetimeMax, chart.getAxisX().getScaling().getMaximum().getValueAsDate()); + Assert.assertEquals(AxisTimeUnit.DAYS, chart.getAxisX().getBaseTimeUnit()); + Assert.assertEquals(7.0d, chart.getAxisX().getMajorUnit()); + Assert.assertEquals(1.0d, chart.getAxisX().getMinorUnit()); + Assert.assertEquals(AxisTickMark.CROSS, chart.getAxisX().getMajorTickMark()); + Assert.assertEquals(AxisTickMark.OUTSIDE, chart.getAxisX().getMinorTickMark()); + Assert.assertEquals(true, chart.getAxisX().hasMajorGridlines()); + Assert.assertEquals(true, chart.getAxisX().hasMinorGridlines()); + + Assert.assertEquals(AxisTickLabelPosition.HIGH, chart.getAxisY().getTickLabels().getPosition()); + Assert.assertEquals(100.0d, chart.getAxisY().getMajorUnit()); + Assert.assertEquals(50.0d, chart.getAxisY().getMinorUnit()); + Assert.assertEquals(AxisBuiltInUnit.HUNDREDS, chart.getAxisY().getDisplayUnit().getUnit()); + Assert.assertEquals(new AxisBound(100.0), chart.getAxisY().getScaling().getMinimum()); + Assert.assertEquals(new AxisBound(700.0), chart.getAxisY().getScaling().getMaximum()); + Assert.assertEquals(true, chart.getAxisY().hasMajorGridlines()); + Assert.assertEquals(true, chart.getAxisY().hasMinorGridlines()); + } + + @Test + public void hideChartAxis() throws Exception { + //ExStart + //ExFor:ChartAxis.Hidden + //ExSummary:Shows how to hide chart axes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.LINE, 500.0, 300.0); + Chart chart = shape.getChart(); + + // Clear the chart's demo data series to start with a clean chart. + chart.getSeries().clear(); + + // Add a custom series with categories for the X-axis, and respective decimal values for the Y-axis. + chart.getSeries().add("AW Series 1", + new String[]{"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"}, + new double[]{1.2, 0.3, 2.1, 2.9, 4.2}); + + // Hide the chart axes to simplify the appearance of the chart. + chart.getAxisX().setHidden(true); + chart.getAxisY().setHidden(true); + + doc.save(getArtifactsDir() + "Charts.HideChartAxis.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Charts.HideChartAxis.docx"); + chart = ((Shape) doc.getChild(NodeType.SHAPE, 0, true)).getChart(); + + Assert.assertEquals(chart.getAxisX().getHidden(), true); + Assert.assertEquals(chart.getAxisY().getHidden(), true); + } + + @Test + public void setNumberFormatToChartAxis() throws Exception { + //ExStart + //ExFor:ChartAxis.NumberFormat + //ExFor:ChartNumberFormat + //ExFor:ChartNumberFormat.FormatCode + //ExFor:ChartNumberFormat.IsLinkedToSource + //ExSummary:Shows how to set formatting for chart values. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 500.0, 300.0); + Chart chart = shape.getChart(); + + // Clear the chart's demo data series to start with a clean chart. + chart.getSeries().clear(); + + // Add a custom series to the chart with categories for the X-axis, + // and large respective numeric values for the Y-axis. + chart.getSeries().add("Aspose Test Series", + new String[]{"Word", "PDF", "Excel", "GoogleDocs", "Note"}, + new double[]{1900000.0, 850000.0, 2100000.0, 600000.0, 1500000.0}); + + // Set the number format of the Y-axis tick labels to not group digits with commas. + chart.getAxisY().getNumberFormat().setFormatCode("#,##0"); + + // This flag can override the above value and draw the number format from the source cell. + Assert.assertFalse(chart.getAxisY().getNumberFormat().isLinkedToSource()); + + doc.save(getArtifactsDir() + "Charts.SetNumberFormatToChartAxis.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Charts.SetNumberFormatToChartAxis.docx"); + chart = ((Shape) doc.getChild(NodeType.SHAPE, 0, true)).getChart(); + + Assert.assertEquals("#,##0", chart.getAxisY().getNumberFormat().getFormatCode()); + } + + @Test (dataProvider = "testDisplayChartsWithConversionDataProvider") + public void testDisplayChartsWithConversion(int chartType) throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(chartType, 500.0, 300.0); + Chart chart = shape.getChart(); + chart.getSeries().clear(); + + chart.getSeries().add("Aspose Test Series", + new String[] { "Word", "PDF", "Excel", "GoogleDocs", "Note" }, + new double[] { 1900000.0, 850000.0, 2100000.0, 600000.0, 1500000.0 }); + + doc.save(getArtifactsDir() + "Charts.TestDisplayChartsWithConversion.docx"); + doc.save(getArtifactsDir() + "Charts.TestDisplayChartsWithConversion.pdf"); + } + + //JAVA-added data provider for test method + @DataProvider(name = "testDisplayChartsWithConversionDataProvider") + public static Object[][] testDisplayChartsWithConversionDataProvider() throws Exception + { + return new Object[][] + { + {ChartType.COLUMN}, + {ChartType.LINE}, + {ChartType.PIE}, + {ChartType.BAR}, + {ChartType.AREA}, + }; + } + + @Test + public void surface3DChart() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.SURFACE_3_D, 500.0, 300.0); + Chart chart = shape.getChart(); + chart.getSeries().clear(); + + chart.getSeries().add("Aspose Test Series 1", + new String[] { "Word", "PDF", "Excel", "GoogleDocs", "Note" }, + new double[] { 1900000.0, 850000.0, 2100000.0, 600000.0, 1500000.0 }); + + chart.getSeries().add("Aspose Test Series 2", + new String[] { "Word", "PDF", "Excel", "GoogleDocs", "Note" }, + new double[] { 900000.0, 50000.0, 1100000.0, 400000.0, 2500000.0 }); + + chart.getSeries().add("Aspose Test Series 3", + new String[] { "Word", "PDF", "Excel", "GoogleDocs", "Note" }, + new double[] { 500000.0, 820000.0, 1500000.0, 400000.0, 100000.0 }); + + doc.save(getArtifactsDir() + "Charts.SurfaceChart.docx"); + doc.save(getArtifactsDir() + "Charts.SurfaceChart.pdf"); + } + + @Test + public void dataLabelsBubbleChart() throws Exception { + //ExStart + //ExFor:ChartDataLabelCollection.Separator + //ExFor:ChartDataLabelCollection.ShowBubbleSize + //ExFor:ChartDataLabelCollection.ShowCategoryName + //ExFor:ChartDataLabelCollection.ShowSeriesName + //ExSummary:Shows how to work with data labels of a bubble chart. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Chart chart = builder.insertChart(ChartType.BUBBLE, 500.0, 300.0).getChart(); + + // Clear the chart's demo data series to start with a clean chart. + chart.getSeries().clear(); + + // Add a custom series with X/Y coordinates and diameter of each of the bubbles. + ChartSeries series = chart.getSeries().add("Aspose Test Series", + new double[]{2.9, 3.5, 1.1, 4.0, 4.0}, + new double[]{1.9, 8.5, 2.1, 6.0, 1.5}, + new double[]{9.0, 4.5, 2.5, 8.0, 5.0}); + + // Enable data labels, and then modify their appearance. + series.hasDataLabels(true); + ChartDataLabelCollection dataLabels = series.getDataLabels(); + dataLabels.setShowBubbleSize(true); + dataLabels.setShowCategoryName(true); + dataLabels.setShowSeriesName(true); + dataLabels.setSeparator(" & "); + + doc.save(getArtifactsDir() + "Charts.DataLabelsBubbleChart.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Charts.DataLabelsBubbleChart.docx"); + dataLabels = ((Shape) doc.getChild(NodeType.SHAPE, 0, true)).getChart().getSeries().get(0).getDataLabels(); + + Assert.assertTrue(dataLabels.getShowBubbleSize()); + Assert.assertTrue(dataLabels.getShowCategoryName()); + Assert.assertTrue(dataLabels.getShowSeriesName()); + Assert.assertEquals(" & ", dataLabels.getSeparator()); + } + + @Test + public void dataLabelsPieChart() throws Exception { + //ExStart + //ExFor:ChartDataLabelCollection.Separator + //ExFor:ChartDataLabelCollection.ShowLeaderLines + //ExFor:ChartDataLabelCollection.ShowLegendKey + //ExFor:ChartDataLabelCollection.ShowPercentage + //ExFor:ChartDataLabelCollection.ShowValue + //ExSummary:Shows how to work with data labels of a pie chart. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Chart chart = builder.insertChart(ChartType.PIE, 500.0, 300.0).getChart(); + + // Clear the chart's demo data series to start with a clean chart. + chart.getSeries().clear(); + + // Insert a custom chart series with a category name for each of the sectors, and their frequency table. + ChartSeries series = chart.getSeries().add("Aspose Test Series", + new String[]{"Word", "PDF", "Excel"}, + new double[]{2.7, 3.2, 0.8}); + + // Enable data labels that will display both percentage and frequency of each sector, and modify their appearance. + series.hasDataLabels(true); + ChartDataLabelCollection dataLabels = series.getDataLabels(); + dataLabels.setShowLeaderLines(true); + dataLabels.setShowLegendKey(true); + dataLabels.setShowPercentage(true); + dataLabels.setShowValue(true); + dataLabels.setSeparator("; "); + + doc.save(getArtifactsDir() + "Charts.DataLabelsPieChart.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Charts.DataLabelsPieChart.docx"); + dataLabels = ((Shape) doc.getChild(NodeType.SHAPE, 0, true)).getChart().getSeries().get(0).getDataLabels(); + + Assert.assertTrue(dataLabels.getShowLeaderLines()); + Assert.assertTrue(dataLabels.getShowLegendKey()); + Assert.assertTrue(dataLabels.getShowPercentage()); + Assert.assertTrue(dataLabels.getShowValue()); + Assert.assertEquals("; ", dataLabels.getSeparator()); + } + + //ExStart + //ExFor:ChartSeries + //ExFor:ChartSeries.DataLabels + //ExFor:ChartSeries.DataPoints + //ExFor:ChartSeries.Name + //ExFor:ChartSeries.Explosion + //ExFor:ChartDataLabel + //ExFor:ChartDataLabel.Index + //ExFor:ChartDataLabel.IsVisible + //ExFor:ChartDataLabel.NumberFormat + //ExFor:ChartDataLabel.Separator + //ExFor:ChartDataLabel.ShowCategoryName + //ExFor:ChartDataLabel.ShowDataLabelsRange + //ExFor:ChartDataLabel.ShowLeaderLines + //ExFor:ChartDataLabel.ShowLegendKey + //ExFor:ChartDataLabel.ShowPercentage + //ExFor:ChartDataLabel.ShowSeriesName + //ExFor:ChartDataLabel.ShowValue + //ExFor:ChartDataLabel.IsHidden + //ExFor:ChartDataLabel.Format + //ExFor:ChartDataLabel.ClearFormat + //ExFor:ChartDataLabelCollection + //ExFor:ChartDataLabelCollection.ShowDataLabelsRange + //ExFor:ChartDataLabelCollection.ClearFormat + //ExFor:ChartDataLabelCollection.Count + //ExFor:ChartDataLabelCollection.GetEnumerator + //ExFor:ChartDataLabelCollection.Item(Int32) + //ExSummary:Shows how to apply labels to data points in a line chart. + @Test //ExSkip + public void dataLabels() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape chartShape = builder.insertChart(ChartType.LINE, 400.0, 300.0); + Chart chart = chartShape.getChart(); + + Assert.assertEquals(3, chart.getSeries().getCount()); + Assert.assertEquals("Series 1", chart.getSeries().get(0).getName()); + Assert.assertEquals("Series 2", chart.getSeries().get(1).getName()); + Assert.assertEquals("Series 3", chart.getSeries().get(2).getName()); + + // Apply data labels to every series in the chart. + // These labels will appear next to each data point in the graph and display its value. + for (ChartSeries series : chart.getSeries()) { + applyDataLabels(series, 4, "000.0", ", "); + Assert.assertEquals(series.getDataLabels().getCount(), 4); + } + + // Change the separator string for every data label in a series. + Iterator enumerator = chart.getSeries().get(0).getDataLabels().iterator(); + while (enumerator.hasNext()) { + Assert.assertEquals(enumerator.next().getSeparator(), ", "); + enumerator.next().setSeparator(" & "); + } + + ChartDataLabel dataLabel = chart.getSeries().get(1).getDataLabels().get(2); + dataLabel.getFormat().getFill().setColor(Color.RED); + + // For a cleaner looking graph, we can remove data labels individually. + dataLabel.clearFormat(); + + // We can also strip an entire series of its data labels at once. + chart.getSeries().get(2).getDataLabels().clearFormat(); + + doc.save(getArtifactsDir() + "Charts.DataLabels.docx"); + } + + /// + /// Apply data labels with custom number format and separator to several data points in a series. + /// + private static void applyDataLabels(ChartSeries series, int labelsCount, String numberFormat, String separator) { + series.hasDataLabels(true); + series.setExplosion(40); + + for (int i = 0; i < labelsCount; i++) { + Assert.assertFalse(series.getDataLabels().get(i).isVisible()); + + series.getDataLabels().get(i).setShowCategoryName(true); + series.getDataLabels().get(i).setShowSeriesName(true); + series.getDataLabels().get(i).setShowValue(true); + series.getDataLabels().get(i).setShowLeaderLines(true); + series.getDataLabels().get(i).setShowLegendKey(true); + series.getDataLabels().get(i).setShowPercentage(false); + Assert.assertFalse(series.getDataLabels().get(i).isHidden()); + Assert.assertFalse(series.getDataLabels().get(i).getShowDataLabelsRange()); + + series.getDataLabels().get(i).getNumberFormat().setFormatCode(numberFormat); + series.getDataLabels().get(i).setSeparator(separator); + + Assert.assertFalse(series.getDataLabels().get(i).getShowDataLabelsRange()); + Assert.assertTrue(series.getDataLabels().get(i).isVisible()); + Assert.assertFalse(series.getDataLabels().get(i).isHidden()); + } + } + //ExEnd + + //ExStart + //ExFor:ChartSeries.Smooth + //ExFor:ChartSeries.InvertIfNegative + //ExFor:ChartDataPoint + //ExFor:ChartDataPoint.Format + //ExFor:ChartDataPoint.ClearFormat + //ExFor:ChartDataPoint.Index + //ExFor:ChartDataPointCollection + //ExFor:ChartDataPointCollection.ClearFormat + //ExFor:ChartDataPointCollection.Count + //ExFor:ChartDataPointCollection.GetEnumerator + //ExFor:ChartDataPointCollection.Item(Int32) + //ExFor:ChartMarker + //ExFor:ChartMarker.Size + //ExFor:ChartMarker.Symbol + //ExFor:IChartDataPoint + //ExFor:IChartDataPoint.InvertIfNegative + //ExFor:ChartDataPoint.InvertIfNegative + //ExFor:IChartDataPoint.Marker + //ExFor:MarkerSymbol + //ExSummary:Shows how to work with data points on a line chart. + @Test//ExSkip + public void chartDataPoint() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.LINE, 500.0, 350.0); + Chart chart = shape.getChart(); + + Assert.assertEquals(3, chart.getSeries().getCount()); + Assert.assertEquals("Series 1", chart.getSeries().get(0).getName()); + Assert.assertEquals("Series 2", chart.getSeries().get(1).getName()); + Assert.assertEquals("Series 3", chart.getSeries().get(2).getName()); + + // Emphasize the chart's data points by making them appear as diamond shapes. + for (ChartSeries series : chart.getSeries()) + applyDataPoints(series, 4, MarkerSymbol.DIAMOND, 15); + + // Smooth out the line that represents the first data series. + chart.getSeries().get(0).setSmooth(true); + + // Verify that data points for the first series will not invert their colors if the value is negative. + Iterator enumerator = chart.getSeries().get(0).getDataPoints().iterator(); + while (enumerator.hasNext()) { + Assert.assertFalse(enumerator.next().getInvertIfNegative()); + } + + ChartDataPoint dataPoint = chart.getSeries().get(1).getDataPoints().get(2); + dataPoint.getFormat().getFill().setColor(Color.RED); + + // For a cleaner looking graph, we can clear format individually. + dataPoint.clearFormat(); + + // We can also strip an entire series of data points at once. + chart.getSeries().get(2).getDataPoints().clearFormat(); + + doc.save(getArtifactsDir() + "Charts.ChartDataPoint.docx"); + } + + /// + /// Applies a number of data points to a series. + /// + private static void applyDataPoints(ChartSeries series, int dataPointsCount, int markerSymbol, int dataPointSize) { + for (int i = 0; i < dataPointsCount; i++) { + ChartDataPoint point = series.getDataPoints().get(i); + point.getMarker().setSymbol(markerSymbol); + point.getMarker().setSize(dataPointSize); + + Assert.assertEquals(point.getIndex(), i); + } + } + //ExEnd + + @Test + public void pieChartExplosion() throws Exception { + //ExStart + //ExFor:IChartDataPoint.Explosion + //ExFor:ChartDataPoint.Explosion + //ExSummary:Shows how to move the slices of a pie chart away from the center. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.PIE, 500.0, 350.0); + Chart chart = shape.getChart(); + + Assert.assertEquals(1, chart.getSeries().getCount()); + Assert.assertEquals("Sales", chart.getSeries().get(0).getName()); + + // "Slices" of a pie chart may be moved away from the center by a distance via the respective data point's Explosion attribute. + // Add a data point to the first portion of the pie chart and move it away from the center by 10 points. + // Aspose.Words create data points automatically if them does not exist. + ChartDataPoint dataPoint = chart.getSeries().get(0).getDataPoints().get(0); + dataPoint.setExplosion(10); + + // Displace the second portion by a greater distance. + dataPoint = chart.getSeries().get(0).getDataPoints().get(1); + dataPoint.setExplosion(40); + + doc.save(getArtifactsDir() + "Charts.PieChartExplosion.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Charts.PieChartExplosion.docx"); + ChartSeries series = ((Shape) doc.getChild(NodeType.SHAPE, 0, true)).getChart().getSeries().get(0); + + Assert.assertEquals(10, series.getDataPoints().get(0).getExplosion()); + Assert.assertEquals(40, series.getDataPoints().get(1).getExplosion()); + } + + @Test + public void bubble3D() throws Exception { + //ExStart + //ExFor:ChartDataLabel.ShowBubbleSize + //ExFor:ChartDataLabel.Font + //ExFor:IChartDataPoint.Bubble3D + //ExFor:ChartSeries.Bubble3D + //ExSummary:Shows how to use 3D effects with bubble charts. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.BUBBLE_3_D, 500.0, 350.0); + Chart chart = shape.getChart(); + + Assert.assertEquals(1, chart.getSeries().getCount()); + Assert.assertEquals("Y-Values", chart.getSeries().get(0).getName()); + Assert.assertTrue(chart.getSeries().get(0).getBubble3D()); + + // Apply a data label to each bubble that displays its diameter. + for (int i = 0; i < 3; i++) { + chart.getSeries().get(0).hasDataLabels(true); + ChartDataLabel cdl = chart.getSeries().get(0).getDataLabels().get(i); + chart.getSeries().get(0).getDataLabels().get(i).getFont().setSize(12.0); + cdl.setShowBubbleSize(true); + } + + doc.save(getArtifactsDir() + "Charts.Bubble3D.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Charts.Bubble3D.docx"); + ChartSeries series = ((Shape) doc.getChild(NodeType.SHAPE, 0, true)).getChart().getSeries().get(0); + + for (int i = 0; i < 3; i++) { + Assert.assertTrue(series.getDataLabels().get(i).getShowBubbleSize()); + Assert.assertTrue(series.getDataLabels().get(i).getShowBubbleSize()); + } + } + + //ExStart + //ExFor:ChartAxis.Type + //ExFor:ChartAxisType + //ExFor:ChartType + //ExFor:Chart.Series + //ExFor:ChartSeriesCollection.Add(String,DateTime[],Double[]) + //ExFor:ChartSeriesCollection.Add(String,Double[],Double[]) + //ExFor:ChartSeriesCollection.Add(String,Double[],Double[],Double[]) + //ExFor:ChartSeriesCollection.Add(String,String[],Double[]) + //ExSummary:Shows how to create an appropriate type of chart series for a graph type. + @Test //ExSkip + public void chartSeriesCollection() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // There are several ways of populating a chart's series collection. + // Different series schemas are intended for different chart types. + // 1 - Column chart with columns grouped and banded along the X-axis by category: + Chart chart = appendChart(builder, ChartType.COLUMN, 500.0, 300.0); + + String[] categories = {"Category 1", "Category 2", "Category 3"}; + + // Insert two series of decimal values containing a value for each respective category. + // This column chart will have three groups, each with two columns. + chart.getSeries().add("Series 1", categories, new double[]{76.6, 82.1, 91.6}); + chart.getSeries().add("Series 2", categories, new double[]{64.2, 79.5, 94.0}); + + // Categories are distributed along the X-axis, and values are distributed along the Y-axis. + Assert.assertEquals(ChartAxisType.CATEGORY, chart.getAxisX().getType()); + Assert.assertEquals(ChartAxisType.VALUE, chart.getAxisY().getType()); + + // 2 - Area chart with dates distributed along the X-axis: + chart = appendChart(builder, ChartType.AREA, 500.0, 300.0); + + Date[] dates = {DocumentHelper.createDate(2014, 3, 31), + DocumentHelper.createDate(2017, 1, 23), + DocumentHelper.createDate(2017, 6, 18), + DocumentHelper.createDate(2019, 11, 22), + DocumentHelper.createDate(2020, 9, 7) + }; + + // Insert a series with a decimal value for each respective date. + // The dates will be distributed along a linear X-axis, + // and the values added to this series will create data points. + chart.getSeries().add("Series 1", dates, new double[]{15.8, 21.5, 22.9, 28.7, 33.1}); + + Assert.assertEquals(ChartAxisType.CATEGORY, chart.getAxisX().getType()); + Assert.assertEquals(ChartAxisType.VALUE, chart.getAxisY().getType()); + + // 3 - 2D scatter plot: + chart = appendChart(builder, ChartType.SCATTER, 500.0, 300.0); + + // Each series will need two decimal arrays of equal length. + // The first array contains X-values, and the second contains corresponding Y-values + // of data points on the chart's graph. + chart.getSeries().add("Series 1", + new double[]{3.1, 3.5, 6.3, 4.1, 2.2, 8.3, 1.2, 3.6}, + new double[]{3.1, 6.3, 4.6, 0.9, 8.5, 4.2, 2.3, 9.9}); + chart.getSeries().add("Series 2", + new double[]{2.6, 7.3, 4.5, 6.6, 2.1, 9.3, 0.7, 3.3}, + new double[]{7.1, 6.6, 3.5, 7.8, 7.7, 9.5, 1.3, 4.6}); + + Assert.assertEquals(ChartAxisType.VALUE, chart.getAxisX().getType()); + Assert.assertEquals(ChartAxisType.VALUE, chart.getAxisY().getType()); + + // 4 - Bubble chart: + chart = appendChart(builder, ChartType.BUBBLE, 500.0, 300.0); + + // Each series will need three decimal arrays of equal length. + // The first array contains X-values, the second contains corresponding Y-values, + // and the third contains diameters for each of the graph's data points. + chart.getSeries().add("Series 1", + new double[]{1.1, 5.0, 9.8}, + new double[]{1.2, 4.9, 9.9}, + new double[]{2.0, 4.0, 8.0}); + + doc.save(getArtifactsDir() + "Charts.ChartSeriesCollection.docx"); + } + + /// + /// Insert a chart using a document builder of a specified ChartType, width and height, and remove its demo data. + /// + private static Chart appendChart(DocumentBuilder builder, /*ChartType*/int chartType, double width, double height) throws Exception { + Shape chartShape = builder.insertChart(chartType, width, height); + Chart chart = chartShape.getChart(); + chart.getSeries().clear(); + Assert.assertEquals(0, chart.getSeries().getCount()); //ExSkip + + return chart; + } + //ExEnd + + @Test + public void chartSeriesCollectionModify() throws Exception { + //ExStart + //ExFor:ChartSeriesCollection + //ExFor:ChartSeriesCollection.Clear + //ExFor:ChartSeriesCollection.Count + //ExFor:ChartSeriesCollection.GetEnumerator + //ExFor:ChartSeriesCollection.Item(Int32) + //ExFor:ChartSeriesCollection.RemoveAt(Int32) + //ExSummary:Shows how to add and remove series data in a chart. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a column chart that will contain three series of demo data by default. + Shape chartShape = builder.insertChart(ChartType.COLUMN, 400.0, 300.0); + Chart chart = chartShape.getChart(); + + // Each series has four decimal values: one for each of the four categories. + // Four clusters of three columns will represent this data. + ChartSeriesCollection chartData = chart.getSeries(); + + Assert.assertEquals(3, chartData.getCount()); + + // Print the name of every series in the chart. + Iterator enumerator = chart.getSeries().iterator(); + while (enumerator.hasNext()) { + System.out.println(enumerator.next().getName()); + } + + // These are the names of the categories in the chart. + String[] categories = {"Category 1", "Category 2", "Category 3", "Category 4"}; + + // We can add a series with new values for existing categories. + // This chart will now contain four clusters of four columns. + chart.getSeries().add("Series 4", categories, new double[]{4.4, 7.0, 3.5, 2.1}); + Assert.assertEquals(4, chartData.getCount()); //ExSkip + Assert.assertEquals("Series 4", chartData.get(3).getName()); //ExSkip + + // A chart series can also be removed by index, like this. + // This will remove one of the three demo series that came with the chart. + chartData.removeAt(2); + + Assert.assertFalse(IterableUtils.matchesAny(chartData, s -> s.getName() == "Series 3")); + Assert.assertEquals(3, chartData.getCount()); //ExSkip + Assert.assertEquals("Series 4", chartData.get(2).getName()); //ExSkip + + // We can also clear all the chart's data at once with this method. + // When creating a new chart, this is the way to wipe all the demo data + // before we can begin working on a blank chart. + chartData.clear(); + Assert.assertEquals(0, chartData.getCount()); //ExSkip + + //ExEnd + } + + @Test + public void axisScaling() throws Exception { + //ExStart + //ExFor:AxisScaleType + //ExFor:AxisScaling + //ExFor:AxisScaling.LogBase + //ExFor:AxisScaling.Type + //ExSummary:Shows how to apply logarithmic scaling to a chart axis. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape chartShape = builder.insertChart(ChartType.SCATTER, 450.0, 300.0); + Chart chart = chartShape.getChart(); + + // Clear the chart's demo data series to start with a clean chart. + chart.getSeries().clear(); + + // Insert a series with X/Y coordinates for five points. + chart.getSeries().add("Series 1", + new double[]{1.0, 2.0, 3.0, 4.0, 5.0}, + new double[]{1.0, 20.0, 400.0, 8000.0, 160000.0}); + + // The scaling of the X-axis is linear by default, + // displaying evenly incrementing values that cover our X-value range (0, 1, 2, 3...). + // A linear axis is not ideal for our Y-values + // since the points with the smaller Y-values will be harder to read. + // A logarithmic scaling with a base of 20 (1, 20, 400, 8000...) + // will spread the plotted points, allowing us to read their values on the chart more easily. + chart.getAxisY().getScaling().setType(AxisScaleType.LOGARITHMIC); + chart.getAxisY().getScaling().setLogBase(20.0); + + doc.save(getArtifactsDir() + "Charts.AxisScaling.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Charts.AxisScaling.docx"); + chart = ((Shape) doc.getChild(NodeType.SHAPE, 0, true)).getChart(); + + Assert.assertEquals(AxisScaleType.LINEAR, chart.getAxisX().getScaling().getType()); + Assert.assertEquals(AxisScaleType.LOGARITHMIC, chart.getAxisY().getScaling().getType()); + Assert.assertEquals(20.0d, chart.getAxisY().getScaling().getLogBase()); + } + + @Test + public void axisBound() throws Exception { + //ExStart + //ExFor:AxisBound.#ctor + //ExFor:AxisBound.IsAuto + //ExFor:AxisBound.Value + //ExFor:AxisBound.ValueAsDate + //ExSummary:Shows how to set custom axis bounds. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape chartShape = builder.insertChart(ChartType.SCATTER, 450.0, 300.0); + Chart chart = chartShape.getChart(); + + // Clear the chart's demo data series to start with a clean chart. + chart.getSeries().clear(); + + // Add a series with two decimal arrays. The first array contains the X-values, + // and the second contains corresponding Y-values for points in the scatter chart. + chart.getSeries().add("Series 1", + new double[]{1.1, 5.4, 7.9, 3.5, 2.1, 9.7}, + new double[]{2.1, 0.3, 0.6, 3.3, 1.4, 1.9}); + + // By default, default scaling is applied to the graph's X and Y-axes, + // so that both their ranges are big enough to encompass every X and Y-value of every series. + Assert.assertTrue(chart.getAxisX().getScaling().getMinimum().isAuto()); + + // We can define our own axis bounds. + // In this case, we will make both the X and Y-axis rulers show a range of 0 to 10. + chart.getAxisX().getScaling().setMinimum(new AxisBound(0.0)); + chart.getAxisX().getScaling().setMaximum(new AxisBound(10.0)); + chart.getAxisY().getScaling().setMinimum(new AxisBound(0.0)); + chart.getAxisY().getScaling().setMaximum(new AxisBound(10.0)); + + Assert.assertFalse(chart.getAxisX().getScaling().getMinimum().isAuto()); + Assert.assertFalse(chart.getAxisY().getScaling().getMinimum().isAuto()); + + // Create a line chart with a series requiring a range of dates on the X-axis, and decimal values for the Y-axis. + chartShape = builder.insertChart(ChartType.LINE, 450.0, 300.0); + chart = chartShape.getChart(); + chart.getSeries().clear(); + + Date[] dates = {DocumentHelper.createDate(1973, 5, 11), + DocumentHelper.createDate(1981, 2, 4), + DocumentHelper.createDate(1985, 9, 23), + DocumentHelper.createDate(1989, 6, 28), + DocumentHelper.createDate(1994, 12, 15) + }; + + chart.getSeries().add("Series 1", dates, new double[]{3.0, 4.7, 5.9, 7.1, 8.9}); + + // We can set axis bounds in the form of dates as well, limiting the chart to a period. + // Setting the range to 1980-1990 will omit the two of the series values + // that are outside of the range from the graph. + + Date datetimeMin = DocumentHelper.createDate(1980, 1, 1); + chart.getAxisX().getScaling().setMinimum(new AxisBound(datetimeMin)); + Date datetimeMax = DocumentHelper.createDate(1980, 1, 1); + chart.getAxisX().getScaling().setMaximum(new AxisBound(datetimeMax)); + + doc.save(getArtifactsDir() + "Charts.AxisBound.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Charts.AxisBound.docx"); + chart = ((Shape) doc.getChild(NodeType.SHAPE, 0, true)).getChart(); + + Assert.assertFalse(chart.getAxisX().getScaling().getMinimum().isAuto()); + Assert.assertEquals(0.0d, chart.getAxisX().getScaling().getMinimum().getValue()); + Assert.assertEquals(10.0d, chart.getAxisX().getScaling().getMaximum().getValue()); + + Assert.assertFalse(chart.getAxisY().getScaling().getMinimum().isAuto()); + Assert.assertEquals(0.0d, chart.getAxisY().getScaling().getMinimum().getValue()); + Assert.assertEquals(10.0d, chart.getAxisY().getScaling().getMaximum().getValue()); + + chart = ((Shape) doc.getChild(NodeType.SHAPE, 1, true)).getChart(); + + Assert.assertFalse(chart.getAxisX().getScaling().getMinimum().isAuto()); + Assert.assertEquals(datetimeMin, chart.getAxisX().getScaling().getMinimum().getValueAsDate()); + Assert.assertEquals(datetimeMax, chart.getAxisX().getScaling().getMaximum().getValueAsDate()); + + Assert.assertTrue(chart.getAxisY().getScaling().getMinimum().isAuto()); + } + + @Test + public void chartLegend() throws Exception { + //ExStart + //ExFor:Chart.Legend + //ExFor:ChartLegend + //ExFor:ChartLegend.Overlay + //ExFor:ChartLegend.Position + //ExFor:LegendPosition + //ExSummary:Shows how to edit the appearance of a chart's legend. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.LINE, 450.0, 300.0); + Chart chart = shape.getChart(); + + Assert.assertEquals(3, chart.getSeries().getCount()); + Assert.assertEquals("Series 1", chart.getSeries().get(0).getName()); + Assert.assertEquals("Series 2", chart.getSeries().get(1).getName()); + Assert.assertEquals("Series 3", chart.getSeries().get(2).getName()); + + // Move the chart's legend to the top right corner. + ChartLegend legend = chart.getLegend(); + legend.setPosition(LegendPosition.TOP_RIGHT); + + // Give other chart elements, such as the graph, more room by allowing them to overlap the legend. + legend.setOverlay(true); + + doc.save(getArtifactsDir() + "Charts.ChartLegend.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Charts.ChartLegend.docx"); + + legend = ((Shape) doc.getChild(NodeType.SHAPE, 0, true)).getChart().getLegend(); + + Assert.assertTrue(legend.getOverlay()); + Assert.assertEquals(LegendPosition.TOP_RIGHT, legend.getPosition()); + } + + @Test + public void axisCross() throws Exception { + //ExStart + //ExFor:ChartAxis.AxisBetweenCategories + //ExFor:ChartAxis.CrossesAt + //ExSummary:Shows how to get a graph axis to cross at a custom location. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 450.0, 250.0); + Chart chart = shape.getChart(); + + Assert.assertEquals(3, chart.getSeries().getCount()); + Assert.assertEquals("Series 1", chart.getSeries().get(0).getName()); + Assert.assertEquals("Series 2", chart.getSeries().get(1).getName()); + Assert.assertEquals("Series 3", chart.getSeries().get(2).getName()); + + // For column charts, the Y-axis crosses at zero by default, + // which means that columns for all values below zero point down to represent negative values. + // We can set a different value for the Y-axis crossing. In this case, we will set it to 3. + ChartAxis axis = chart.getAxisX(); + axis.setCrosses(AxisCrosses.CUSTOM); + axis.setCrossesAt(3.0); + axis.setAxisBetweenCategories(true); + + doc.save(getArtifactsDir() + "Charts.AxisCross.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Charts.AxisCross.docx"); + axis = ((Shape) doc.getChild(NodeType.SHAPE, 0, true)).getChart().getAxisX(); + + Assert.assertTrue(axis.getAxisBetweenCategories()); + Assert.assertEquals(AxisCrosses.CUSTOM, axis.getCrosses()); + Assert.assertEquals(3.0, axis.getCrossesAt()); + } + + @Test + public void axisDisplayUnit() throws Exception { + //ExStart + //ExFor:AxisBuiltInUnit + //ExFor:ChartAxis.DisplayUnit + //ExFor:ChartAxis.MajorUnitIsAuto + //ExFor:ChartAxis.MajorUnitScale + //ExFor:ChartAxis.MinorUnitIsAuto + //ExFor:ChartAxis.MinorUnitScale + //ExFor:AxisDisplayUnit + //ExFor:AxisDisplayUnit.CustomUnit + //ExFor:AxisDisplayUnit.Unit + //ExFor:AxisDisplayUnit.Document + //ExSummary:Shows how to manipulate the tick marks and displayed values of a chart axis. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.SCATTER, 450.0, 250.0); + Chart chart = shape.getChart(); + + Assert.assertEquals(1, chart.getSeries().getCount()); + Assert.assertEquals("Y-Values", chart.getSeries().get(0).getName()); + + // Set the minor tick marks of the Y-axis to point away from the plot area, + // and the major tick marks to cross the axis. + ChartAxis axis = chart.getAxisY(); + axis.setMajorTickMark(AxisTickMark.CROSS); + axis.setMinorTickMark(AxisTickMark.OUTSIDE); + + // Set they Y-axis to show a major tick every 10 units, and a minor tick every 1 unit. + axis.setMajorUnit(10.0); + axis.setMinorUnit(1.0); + + // Set the Y-axis bounds to -10 and 20. + // This Y-axis will now display 4 major tick marks and 27 minor tick marks. + axis.getScaling().setMinimum(new AxisBound(-10)); + axis.getScaling().setMaximum(new AxisBound(20.0)); + + // For the X-axis, set the major tick marks at every 10 units, + // every minor tick mark at 2.5 units. + axis = chart.getAxisX(); + axis.setMajorUnit(10.0); + axis.setMinorUnit(2.5); + + // Configure both types of tick marks to appear inside the graph plot area. + axis.setMajorTickMark(AxisTickMark.INSIDE); + axis.setMinorTickMark(AxisTickMark.INSIDE); + + // Set the X-axis bounds so that the X-axis spans 5 major tick marks and 12 minor tick marks. + axis.getScaling().setMinimum(new AxisBound(-10)); + axis.getScaling().setMaximum(new AxisBound(30.0)); + axis.getTickLabels().setAlignment(ParagraphAlignment.RIGHT); + + Assert.assertEquals(1, axis.getTickLabels().getSpacing()); + Assert.assertEquals(doc, axis.getDisplayUnit().getDocument()); + + // Set the tick labels to display their value in millions. + axis.getDisplayUnit().setUnit(AxisBuiltInUnit.MILLIONS); + + // We can set a more specific value by which tick labels will display their values. + // This statement is equivalent to the one above. + axis.getDisplayUnit().setCustomUnit(1000000.0); + Assert.assertEquals(AxisBuiltInUnit.CUSTOM, axis.getDisplayUnit().getUnit()); //ExSkip + + doc.save(getArtifactsDir() + "Charts.AxisDisplayUnit.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Charts.AxisDisplayUnit.docx"); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(450.0d, shape.getWidth()); + Assert.assertEquals(250.0d, shape.getHeight()); + + axis = shape.getChart().getAxisX(); + + Assert.assertEquals(AxisTickMark.INSIDE, axis.getMajorTickMark()); + Assert.assertEquals(AxisTickMark.INSIDE, axis.getMinorTickMark()); + Assert.assertEquals(10.0d, axis.getMajorUnit()); + Assert.assertEquals(-10.0d, axis.getScaling().getMinimum().getValue()); + Assert.assertEquals(30.0d, axis.getScaling().getMaximum().getValue()); + Assert.assertEquals(1, axis.getTickLabels().getSpacing()); + Assert.assertEquals(ParagraphAlignment.RIGHT, axis.getTickLabels().getAlignment()); + Assert.assertEquals(AxisBuiltInUnit.CUSTOM, axis.getDisplayUnit().getUnit()); + Assert.assertEquals(1000000.0d, axis.getDisplayUnit().getCustomUnit()); + + axis = shape.getChart().getAxisY(); + + Assert.assertEquals(AxisTickMark.CROSS, axis.getMajorTickMark()); + Assert.assertEquals(AxisTickMark.OUTSIDE, axis.getMinorTickMark()); + Assert.assertEquals(10.0d, axis.getMajorUnit()); + Assert.assertEquals(1.0d, axis.getMinorUnit()); + Assert.assertEquals(-10.0d, axis.getScaling().getMinimum().getValue()); + Assert.assertEquals(20.0d, axis.getScaling().getMaximum().getValue()); + } + + @Test + public void markerFormatting() throws Exception + { + //ExStart + //ExFor:ChartDataPoint.Marker + //ExFor:ChartMarker.Format + //ExFor:ChartFormat.Fill + //ExFor:ChartSeries.Marker + //ExFor:ChartFormat.Stroke + //ExFor:Stroke.ForeColor + //ExFor:Stroke.BackColor + //ExFor:Stroke.Visible + //ExFor:Stroke.Transparency + //ExFor:PresetTexture + //ExFor:Fill.PresetTextured(PresetTexture) + //ExSummary:Show how to set marker formatting. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.SCATTER, 432.0, 252.0); + Chart chart = shape.getChart(); + + // Delete default generated series. + chart.getSeries().clear(); + ChartSeries series = chart.getSeries().add("AW Series 1", new double[] { 0.7, 1.8, 2.6, 3.9 }, + new double[] { 2.7, 3.2, 0.8, 1.7 }); + + // Set marker formatting. + series.getMarker().setSize(40); + series.getMarker().setSymbol(MarkerSymbol.SQUARE); + ChartDataPointCollection dataPoints = series.getDataPoints(); + dataPoints.get(0).getMarker().getFormat().getFill().presetTextured(PresetTexture.DENIM); + dataPoints.get(0).getMarker().getFormat().getStroke().setForeColor(Color.YELLOW); + dataPoints.get(0).getMarker().getFormat().getStroke().setBackColor(Color.RED); + dataPoints.get(1).getMarker().getFormat().getFill().presetTextured(PresetTexture.WATER_DROPLETS); + dataPoints.get(1).getMarker().getFormat().getStroke().setForeColor(Color.YELLOW); + dataPoints.get(1).getMarker().getFormat().getStroke().setVisible(false); + dataPoints.get(2).getMarker().getFormat().getFill().presetTextured(PresetTexture.GREEN_MARBLE); + dataPoints.get(2).getMarker().getFormat().getStroke().setForeColor(Color.YELLOW); + dataPoints.get(3).getMarker().getFormat().getFill().presetTextured(PresetTexture.OAK); + dataPoints.get(3).getMarker().getFormat().getStroke().setForeColor(Color.YELLOW); + dataPoints.get(3).getMarker().getFormat().getStroke().setTransparency(0.5); + + doc.save(getArtifactsDir() + "Charts.MarkerFormatting.docx"); + //ExEnd + } + + @Test + public void seriesColor() throws Exception + { + //ExStart + //ExFor:ChartSeries.Format + //ExSummary:Sows how to set series color. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + + Chart chart = shape.getChart(); + ChartSeriesCollection seriesColl = chart.getSeries(); + + // Delete default generated series. + seriesColl.clear(); + + // Create category names array. + String[] categories = new String[] { "Category 1", "Category 2" }; + + // Adding new series. Value and category arrays must be the same size. + ChartSeries series1 = seriesColl.add("Series 1", categories, new double[] { 1.0, 2.0 }); + ChartSeries series2 = seriesColl.add("Series 2", categories, new double[] { 3.0, 4.0 }); + ChartSeries series3 = seriesColl.add("Series 3", categories, new double[] { 5.0, 6.0 }); + + // Set series color. + series1.getFormat().getFill().setForeColor(Color.RED); + series2.getFormat().getFill().setForeColor(Color.YELLOW); + series3.getFormat().getFill().setForeColor(Color.BLUE); + + doc.save(getArtifactsDir() + "Charts.SeriesColor.docx"); + //ExEnd + } + + @Test + public void dataPointsFormatting() throws Exception + { + //ExStart + //ExFor:ChartDataPoint.Format + //ExSummary:Shows how to set individual formatting for categories of a column chart. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + Chart chart = shape.getChart(); + + // Delete default generated series. + chart.getSeries().clear(); + + // Adding new series. + ChartSeries series = chart.getSeries().add("Series 1", + new String[] { "Category 1", "Category 2", "Category 3", "Category 4" }, + new double[] { 1.0, 2.0, 3.0, 4.0 }); + + // Set column formatting. + ChartDataPointCollection dataPoints = series.getDataPoints(); + dataPoints.get(0).getFormat().getFill().presetTextured(PresetTexture.DENIM); + dataPoints.get(1).getFormat().getFill().setForeColor(Color.RED); + dataPoints.get(2).getFormat().getFill().setForeColor(Color.YELLOW); + dataPoints.get(3).getFormat().getFill().setForeColor(Color.BLUE); + + doc.save(getArtifactsDir() + "Charts.DataPointsFormatting.docx"); + //ExEnd + } + + @Test + public void legendEntries() throws Exception + { + //ExStart + //ExFor:ChartLegendEntryCollection + //ExFor:ChartLegend.LegendEntries + //ExFor:ChartLegendEntry.IsHidden + //ExSummary:Shows how to work with a legend entry for chart series. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + + Chart chart = shape.getChart(); + ChartSeriesCollection series = chart.getSeries(); + series.clear(); + + String[] categories = new String[] { "AW Category 1", "AW Category 2" }; + + ChartSeries series1 = series.add("Series 1", categories, new double[] { 1.0, 2.0 }); + series.add("Series 2", categories, new double[] { 3.0, 4.0 }); + series.add("Series 3", categories, new double[] { 5.0, 6.0 }); + series.add("Series 4", categories, new double[] { 0.0, 0.0 }); + + ChartLegendEntryCollection legendEntries = chart.getLegend().getLegendEntries(); + legendEntries.get(3).isHidden(true); + + doc.save(getArtifactsDir() + "Charts.LegendEntries.docx"); + //ExEnd + } + + @Test + public void legendFont() throws Exception + { + //ExStart:LegendFont + //GistId:66dd22f0854357e394a013b536e2181b + //ExFor:ChartLegendEntry + //ExFor:ChartLegendEntry.Font + //ExFor:ChartLegend.Font + //ExFor:ChartSeries.LegendEntry + //ExSummary:Shows how to work with a legend font. + Document doc = new Document(getMyDir() + "Reporting engine template - Chart series (Java).docx"); + Chart chart = ((Shape)doc.getChild(NodeType.SHAPE, 0, true)).getChart(); + + ChartLegend chartLegend = chart.getLegend(); + // Set default font size all legend entries. + chartLegend.getFont().setSize(14.0); + // Change font for specific legend entry. + chartLegend.getLegendEntries().get(1).getFont().setItalic(true); + chartLegend.getLegendEntries().get(1).getFont().setSize(12.0); + // Get legend entry for chart series. + ChartLegendEntry legendEntry = chart.getSeries().get(0).getLegendEntry(); + + doc.save(getArtifactsDir() + "Charts.LegendFont.docx"); + //ExEnd:LegendFont + } + + @Test + public void removeSpecificChartSeries() throws Exception + { + //ExStart + //ExFor:ChartSeries.SeriesType + //ExFor:ChartSeriesType + //ExSummary:Shows how to remove specific chart serie. + Document doc = new Document(getMyDir() + "Reporting engine template - Chart series (Java).docx"); + Chart chart = ((Shape)doc.getChild(NodeType.SHAPE, 0, true)).getChart(); + + // Remove all series of the Column type. + for (int i = chart.getSeries().getCount() - 1; i >= 0; i--) + { + if (chart.getSeries().get(i).getSeriesType() == ChartSeriesType.COLUMN) + chart.getSeries().removeAt(i); + } + + chart.getSeries().add( + "Aspose Series", + new String[] { "Category 1", "Category 2", "Category 3", "Category 4" }, + new double[] { 5.6, 7.1, 2.9, 8.9 }); + + doc.save(getArtifactsDir() + "Charts.RemoveSpecificChartSeries.docx"); + //ExEnd + } + + @Test + public void populateChartWithData() throws Exception + { + //ExStart + //ExFor:ChartXValue + //ExFor:ChartXValue.FromDouble(Double) + //ExFor:ChartYValue.FromDouble(Double) + //ExFor:ChartSeries.Add(ChartXValue) + //ExFor:ChartSeries.Add(ChartXValue, ChartYValue) + //ExFor:ChartSeries.Add(ChartXValue, ChartYValue, double) + //ExFor:ChartSeries.ClearValues + //ExFor:ChartSeries.Clear + //ExSummary:Shows how to populate chart series with data. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + Chart chart = shape.getChart(); + ChartSeries series1 = chart.getSeries().get(0); + + // Clear X and Y values of the first series. + series1.clearValues(); + + // Populate the series with data. + series1.add(ChartXValue.fromDouble(3.0), ChartYValue.fromDouble(10.0), 10.0); + series1.add(ChartXValue.fromDouble(5.0), ChartYValue.fromDouble(5.0)); + series1.add(ChartXValue.fromDouble(7.0), ChartYValue.fromDouble(11.0)); + series1.add(ChartXValue.fromDouble(9.0)); + + ChartSeries series2 = chart.getSeries().get(1); + + // Clear X and Y values of the second series. + series2.clear(); + + // Populate the series with data. + series2.add(ChartXValue.fromDouble(2.0), ChartYValue.fromDouble(4.0)); + series2.add(ChartXValue.fromDouble(4.0), ChartYValue.fromDouble(7.0)); + series2.add(ChartXValue.fromDouble(6.0), ChartYValue.fromDouble(14.0)); + series2.add(ChartXValue.fromDouble(8.0), ChartYValue.fromDouble(7.0)); + + doc.save(getArtifactsDir() + "Charts.PopulateChartWithData.docx"); + //ExEnd + } + + @Test + public void getChartSeriesData() throws Exception + { + //ExStart + //ExFor:ChartXValueCollection + //ExFor:ChartYValueCollection + //ExSummary:Shows how to get chart series data. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + Chart chart = shape.getChart(); + ChartSeries series = chart.getSeries().get(0); + + double minValue = Double.MAX_VALUE; + int minValueIndex = 0; + double maxValue = -Double.MAX_VALUE; + int maxValueIndex = 0; + + for (int i = 0; i < series.getYValues().getCount(); i++) + { + // Clear individual format of all data points. + // Data points and data values are one-to-one in column charts. + series.getDataPoints().get(i).clearFormat(); + + // Get Y value. + double yValue = series.getYValues().get(i).getDoubleValue(); + + if (yValue < minValue) + { + minValue = yValue; + minValueIndex = i; + } + + if (yValue > maxValue) + { + maxValue = yValue; + maxValueIndex = i; + } + } + + // Change colors of the max and min values. + series.getDataPoints().get(minValueIndex).getFormat().getFill().setForeColor(Color.RED); + series.getDataPoints().get(maxValueIndex).getFormat().getFill().setForeColor(Color.GREEN); + + doc.save(getArtifactsDir() + "Charts.GetChartSeriesData.docx"); + //ExEnd + } + + @Test + public void chartDataValues() throws Exception + { + //ExStart + //ExFor:ChartXValue.FromString(String) + //ExFor:ChartSeries.Remove(Int32) + //ExFor:ChartSeries.Add(ChartXValue, ChartYValue) + //ExSummary:Shows how to add/remove chart data values. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + Chart chart = shape.getChart(); + ChartSeries department1Series = chart.getSeries().get(0); + ChartSeries department2Series = chart.getSeries().get(1); + + // Remove the first value in the both series. + department1Series.remove(0); + department2Series.remove(0); + + // Add new values to the both series. + ChartXValue newXCategory = ChartXValue.fromString("Q1, 2023"); + department1Series.add(newXCategory, ChartYValue.fromDouble(10.3)); + department2Series.add(newXCategory, ChartYValue.fromDouble(5.7)); + + doc.save(getArtifactsDir() + "Charts.ChartDataValues.docx"); + //ExEnd + } + + @Test + public void formatDataLables() throws Exception + { + //ExStart + //ExFor:ChartDataLabelCollection.Format + //ExFor:ChartFormat.ShapeType + //ExFor:ChartShapeType + //ExSummary:Shows how to set fill, stroke and callout formatting for chart data labels. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + Chart chart = shape.getChart(); + + // Delete default generated series. + chart.getSeries().clear(); + + // Add new series. + ChartSeries series = chart.getSeries().add("AW Series 1", + new String[] { "AW Category 1", "AW Category 2", "AW Category 3", "AW Category 4" }, + new double[] { 100.0, 200.0, 300.0, 400.0 }); + + // Show data labels. + series.hasDataLabels(true); + series.getDataLabels().setShowValue(true); + + // Format data labels as callouts. + ChartFormat format = series.getDataLabels().getFormat(); + format.setShapeType(ChartShapeType.WEDGE_RECT_CALLOUT); + format.getStroke().setColor(Color.lightGray); + format.getFill().solid(Color.GREEN); + series.getDataLabels().getFont().setColor(Color.YELLOW); + + // Change fill and stroke of an individual data label. + ChartFormat labelFormat = series.getDataLabels().get(0).getFormat(); + labelFormat.getStroke().setColor(Color.BLUE); + labelFormat.getFill().solid(Color.BLUE); + + doc.save(getArtifactsDir() + "Charts.FormatDataLables.docx"); + //ExEnd + } + + @Test + public void chartAxisTitle() throws Exception + { + //ExStart:ChartAxisTitle + //GistId:6d898be16b796fcf7448ad3bfe18e51c + //ExFor:ChartAxis.Title + //ExFor:ChartAxisTitle + //ExFor:ChartAxisTitle.Text + //ExFor:ChartAxisTitle.Show + //ExFor:ChartAxisTitle.Overlay + //ExFor:ChartAxisTitle.Font + //ExSummary:Shows how to set chart axis title. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + + Chart chart = shape.getChart(); + ChartSeriesCollection seriesColl = chart.getSeries(); + // Delete default generated series. + seriesColl.clear(); + + seriesColl.add("AW Series 1", new String[] { "AW Category 1", "AW Category 2" }, new double[] { 1.0, 2.0 }); + + // Set axis title. + ChartAxisTitle chartAxisXTitle = chart.getAxisX().getTitle(); + chartAxisXTitle.setText("Categories"); + chartAxisXTitle.setShow(true); + ChartAxisTitle chartAxisYTitle = chart.getAxisY().getTitle(); + chartAxisYTitle.setText("Values"); + chartAxisYTitle.setShow(true); + chartAxisYTitle.setOverlay(true); + chartAxisYTitle.getFont().setSize(12.0); + chartAxisYTitle.getFont().setColor(Color.BLUE); + + doc.save(getArtifactsDir() + "Charts.ChartAxisTitle.docx"); + //ExEnd:ChartAxisTitle + } + + @Test (dataProvider = "dataArraysWrongSizeDataProvider") + public void dataArraysWrongSize(double[] seriesValue, Class exception) throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.LINE, 500.0, 300.0); + ChartSeriesCollection seriesColl = shape.getChart().getSeries(); + seriesColl.clear(); + + String[] categories = { "Word", null, "Excel", "GoogleDocs", "Note", null }; + if (exception == null) + seriesColl.add("AW Series", categories, seriesValue); + else + Assert.assertThrows(exception, () -> seriesColl.add("AW Series", categories, seriesValue)); + } + + @DataProvider(name = "dataArraysWrongSizeDataProvider") + public static Object[][] dataArraysWrongSizeDataProvider() throws Exception + { + return new Object[][] + { + {new double[] { 1.0, 2.0, Double.NaN, 4.0, 5.0, 6.0 }, null}, + {new double[] { Double.NaN, 4.0, 5.0, Double.NaN, 7.0, 8.0 }, null}, + {new double[] { Double.NaN, Double.NaN, Double.NaN, Double.NaN, Double.NaN, 9.0 }, null}, + {new double[] { Double.NaN, 4.0, 5.0, Double.NaN, Double.NaN }, IllegalArgumentException.class}, + {new double[] { Double.NaN, Double.NaN, Double.NaN, Double.NaN, Double.NaN }, IllegalArgumentException.class}, + }; + } + + @Test + public void copyDataPointFormat() throws Exception + { + //ExStart:CopyDataPointFormat + //GistId:6d898be16b796fcf7448ad3bfe18e51c + //ExFor:ChartSeries.CopyFormatFrom(int) + //ExFor:ChartDataPointCollection.HasDefaultFormat(int) + //ExFor:ChartDataPointCollection.CopyFormat(int, int) + //ExSummary:Shows how to copy data point format. + Document doc = new Document(getMyDir() + "DataPoint format.docx"); + + // Get the chart and series to update format. + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + ChartSeries series = shape.getChart().getSeries().get(0); + ChartDataPointCollection dataPoints = series.getDataPoints(); + + Assert.assertTrue(dataPoints.hasDefaultFormat(0)); + Assert.assertFalse(dataPoints.hasDefaultFormat(1)); + + // Copy format of the data point with index 1 to the data point with index 2 + // so that the data point 2 looks the same as the data point 1. + dataPoints.copyFormat(0, 1); + + Assert.assertTrue(dataPoints.hasDefaultFormat(0)); + Assert.assertTrue(dataPoints.hasDefaultFormat(1)); + + // Copy format of the data point with index 0 to the series defaults so that all data points + // in the series that have the default format look the same as the data point 0. + series.copyFormatFrom(1); + + Assert.assertTrue(dataPoints.hasDefaultFormat(0)); + Assert.assertTrue(dataPoints.hasDefaultFormat(1)); + + doc.save(getArtifactsDir() + "Charts.CopyDataPointFormat.docx"); + //ExEnd:CopyDataPointFormat + } + + @Test + public void resetDataPointFill() throws Exception + { + //ExStart:ResetDataPointFill + //GistId:6d898be16b796fcf7448ad3bfe18e51c + //ExFor:ChartFormat.IsDefined + //ExFor:ChartFormat.SetDefaultFill + //ExSummary:Shows how to reset the fill to the default value defined in the series. + Document doc = new Document(getMyDir() + "DataPoint format.docx"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + ChartSeries series = shape.getChart().getSeries().get(0); + ChartDataPoint dataPoint = series.getDataPoints().get(1); + + Assert.assertTrue(dataPoint.getFormat().isDefined()); + + dataPoint.getFormat().setDefaultFill(); + + doc.save(getArtifactsDir() + "Charts.ResetDataPointFill.docx"); + //ExEnd:ResetDataPointFill + } + + @Test + public void dataTable() throws Exception + { + //ExStart:DataTable + //GistId:9c17d666c47318436785490829a3984f + //ExFor:Chart.DataTable + //ExFor:ChartDataTable + //ExFor:ChartDataTable.Show + //ExFor:ChartDataTable.Format + //ExFor:ChartDataTable.Font + //ExFor:ChartDataTable.HasLegendKeys + //ExFor:ChartDataTable.HasHorizontalBorder + //ExFor:ChartDataTable.HasVerticalBorder + //ExFor:ChartDataTable.HasOutlineBorder + //ExSummary:Shows how to show data table with chart series data. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + Chart chart = shape.getChart(); + + ChartSeriesCollection series = chart.getSeries(); + series.clear(); + double[] xValues = new double[] { 2020.0, 2021.0, 2022.0, 2023.0 }; + series.add("Series1", xValues, new double[] { 5.0, 11.0, 2.0, 7.0 }); + series.add("Series2", xValues, new double[] { 6.0, 5.5, 7.0, 7.8 }); + series.add("Series3", xValues, new double[] { 10.0, 8.0, 7.0, 9.0 }); + + ChartDataTable dataTable = chart.getDataTable(); + dataTable.setShow(true); + + dataTable.hasLegendKeys(false); + dataTable.hasHorizontalBorder(false); + dataTable.hasVerticalBorder(false); + dataTable.hasOutlineBorder(false); + + dataTable.getFont().setItalic(true); + dataTable.getFormat().getStroke().setWeight(1.0); + dataTable.getFormat().getStroke().setDashStyle(DashStyle.SHORT_DOT); + dataTable.getFormat().getStroke().setColor(Color.BLUE); + + doc.save(getArtifactsDir() + "Charts.DataTable.docx"); + //ExEnd:DataTable + } + + @Test + public void chartFormat() throws Exception + { + //ExStart:ChartFormat + //GistId:31b7350f8d91d4b12eb43978940d566a + //ExFor:ChartFormat + //ExFor:Chart.Format + //ExFor:ChartTitle.Format + //ExFor:ChartAxisTitle.Format + //ExFor:ChartLegend.Format + //ExFor:Fill.Solid(Color) + //ExSummary:Shows how to use chart formating. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + Chart chart = shape.getChart(); + + // Delete series generated by default. + ChartSeriesCollection series = chart.getSeries(); + series.clear(); + + String[] categories = new String[] { "Category 1", "Category 2" }; + series.add("Series 1", categories, new double[] { 1.0, 2.0 }); + series.add("Series 2", categories, new double[] { 3.0, 4.0 }); + + // Format chart background. + chart.getFormat().getFill().solid(Color.darkGray); + + // Hide axis tick labels. + chart.getAxisX().getTickLabels().setPosition(AxisTickLabelPosition.NONE); + chart.getAxisY().getTickLabels().setPosition(AxisTickLabelPosition.NONE); + + // Format chart title. + chart.getTitle().getFormat().getFill().solid(Color.yellow); + + // Format axis title. + chart.getAxisX().getTitle().setShow(true); + chart.getAxisX().getTitle().getFormat().getFill().solid(Color.yellow); + + // Format legend. + chart.getLegend().getFormat().getFill().solid(Color.yellow); + + doc.save(getArtifactsDir() + "Charts.ChartFormat.docx"); + //ExEnd:ChartFormat + + doc = new Document(getArtifactsDir() + "Charts.ChartFormat.docx"); + + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + chart = shape.getChart(); + + Assert.assertEquals(Color.darkGray.getRGB(), chart.getFormat().getFill().getColor().getRGB()); + Assert.assertEquals(Color.yellow.getRGB(), chart.getTitle().getFormat().getFill().getColor().getRGB()); + Assert.assertEquals(Color.yellow.getRGB(), chart.getAxisX().getTitle().getFormat().getFill().getColor().getRGB()); + Assert.assertEquals(Color.yellow.getRGB(), chart.getLegend().getFormat().getFill().getColor().getRGB()); + } + + @Test + public void secondaryAxis() throws Exception + { + //ExStart:SecondaryAxis + //GistId:f99d87e10ab87a581c52206321d8b617 + //ExFor:ChartSeriesGroup + //ExFor:ChartSeriesGroup.SeriesType + //ExFor:ChartSeriesGroup.AxisGroup + //ExFor:ChartSeriesGroup.AxisX + //ExFor:ChartSeriesGroup.AxisY + //ExFor:ChartSeriesGroup.Series + //ExFor:ChartSeriesGroupCollection + //ExFor:ChartSeriesGroupCollection.Add(ChartSeriesType) + //ExFor:AxisGroup + //ExSummary:Shows how to work with the secondary axis of chart. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.LINE, 450.0, 250.0); + Chart chart = shape.getChart(); + ChartSeriesCollection series = chart.getSeries(); + + // Delete default generated series. + series.clear(); + + String[] categories = new String[] { "Category 1", "Category 2", "Category 3" }; + series.add("Series 1 of primary series group", categories, new double[] { 2.0, 3.0, 4.0 }); + series.add("Series 2 of primary series group", categories, new double[] { 5.0, 2.0, 3.0 }); + + // Create an additional series group, also of the line type. + ChartSeriesGroup newSeriesGroup = chart.getSeriesGroups().add(ChartSeriesType.LINE); + // Specify the use of secondary axes for the new series group. + newSeriesGroup.setAxisGroup(AxisGroup.SECONDARY); + // Hide the secondary X axis. + newSeriesGroup.getAxisX().setHidden(true); + // Define title of the secondary Y axis. + newSeriesGroup.getAxisY().getTitle().setShow(true); + newSeriesGroup.getAxisY().getTitle().setText("Secondary Y axis"); + + Assert.assertEquals(ChartSeriesType.LINE, newSeriesGroup.getSeriesType()); + + // Add a series to the new series group. + ChartSeries series3 = + newSeriesGroup.getSeries().add("Series of secondary series group", categories, new double[] { 13.0, 11.0, 16.0 }); + series3.getFormat().getStroke().setWeight(3.5); + + doc.save(getArtifactsDir() + "Charts.SecondaryAxis.docx"); + //ExEnd:SecondaryAxis + } + + @Test + public void configureGapOverlap() throws Exception + { + //ExStart:ConfigureGapOverlap + //GistId:f99d87e10ab87a581c52206321d8b617 + //ExFor:Chart.SeriesGroups + //ExFor:ChartSeriesGroup.GapWidth + //ExFor:ChartSeriesGroup.Overlap + //ExSummary:Show how to configure gap width and overlap. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 450.0, 250.0); + ChartSeriesGroup seriesGroup = shape.getChart().getSeriesGroups().get(0); + + // Set column gap width and overlap. + seriesGroup.setGapWidth(450); + seriesGroup.setOverlap(-75); + + doc.save(getArtifactsDir() + "Charts.ConfigureGapOverlap.docx"); + //ExEnd:ConfigureGapOverlap + } + + @Test + public void bubbleScale() throws Exception + { + //ExStart:BubbleScale + //GistId:f99d87e10ab87a581c52206321d8b617 + //ExFor:ChartSeriesGroup.BubbleScale + //ExSummary:Show how to set size of the bubbles. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a bubble 3D chart. + Shape shape = builder.insertChart(ChartType.BUBBLE_3_D, 450.0, 250.0); + ChartSeriesGroup seriesGroup = shape.getChart().getSeriesGroups().get(0); + + // Set bubble scale to 200%. + seriesGroup.setBubbleScale(200); + + doc.save(getArtifactsDir() + "Charts.BubbleScale.docx"); + //ExEnd:BubbleScale + } + + @Test + public void removeSecondaryAxis() throws Exception + { + //ExStart:RemoveSecondaryAxis + //GistId:f99d87e10ab87a581c52206321d8b617 + //ExFor:ChartSeriesGroupCollection.Count + //ExFor:ChartSeriesGroupCollection.Item(Int32) + //ExFor:ChartSeriesGroupCollection.RemoveAt(Int32) + //ExSummary:Show how to remove secondary axis. + Document doc = new Document(getMyDir() + "Combo chart.docx"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + Chart chart = shape.getChart(); + ChartSeriesGroupCollection seriesGroups = chart.getSeriesGroups(); + + // Find secondary axis and remove from the collection. + for (int i = 0; i < seriesGroups.getCount(); i++) + if (seriesGroups.get(i).getAxisGroup() == AxisGroup.SECONDARY) + seriesGroups.removeAt(i); + //ExEnd:RemoveSecondaryAxis + } + + @Test + public void treemapChart() throws Exception + { + //ExStart:TreemapChart + //GistId:a76df4b18bee76d169e55cdf6af8129c + //ExFor:ChartSeriesCollection.Add(String, ChartMultilevelValue[], double[]) + //ExFor:ChartMultilevelValue + //ExFor:ChartMultilevelValue.#ctor(String, String, String) + //ExFor:ChartMultilevelValue.#ctor(String, String) + //ExFor:ChartMultilevelValue.#ctor(String) + //ExSummary:Shows how to create treemap chart. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a Treemap chart. + Shape shape = builder.insertChart(ChartType.TREEMAP, 450.0, 280.0); + Chart chart = shape.getChart(); + chart.getTitle().setText("World Population"); + + // Delete default generated series. + chart.getSeries().clear(); + + // Add a series. + ChartSeries series = chart.getSeries().add( + "Population by Region", + new ChartMultilevelValue[] + { + new ChartMultilevelValue("Asia", "China"), + new ChartMultilevelValue("Asia", "India"), + new ChartMultilevelValue("Asia", "Indonesia"), + new ChartMultilevelValue("Asia", "Pakistan"), + new ChartMultilevelValue("Asia", "Bangladesh"), + new ChartMultilevelValue("Asia", "Japan"), + new ChartMultilevelValue("Asia", "Philippines"), + new ChartMultilevelValue("Asia", "Other"), + new ChartMultilevelValue("Africa", "Nigeria"), + new ChartMultilevelValue("Africa", "Ethiopia"), + new ChartMultilevelValue("Africa", "Egypt"), + new ChartMultilevelValue("Africa", "Other"), + new ChartMultilevelValue("Europe", "Russia"), + new ChartMultilevelValue("Europe", "Germany"), + new ChartMultilevelValue("Europe", "Other"), + new ChartMultilevelValue("Latin America", "Brazil"), + new ChartMultilevelValue("Latin America", "Mexico"), + new ChartMultilevelValue("Latin America", "Other"), + new ChartMultilevelValue("Northern America", "United States", "Other"), + new ChartMultilevelValue("Northern America", "Other"), + new ChartMultilevelValue("Oceania") + }, + new double[] + { + 1409670000.0, 1400744000.0, 279118866.0, 241499431.0, 169828911.0, 123930000.0, 112892781.0, 764000000.0, + 223800000.0, 107334000.0, 105914499.0, 903000000.0, + 146150789.0, 84607016.0, 516000000.0, + 203080756.0, 129713690.0, 310000000.0, + 335893238.0, 35000000.0, + 42000000.0 + }); + + // Show data labels. + series.hasDataLabels(true); + series.getDataLabels().setShowValue(true); + series.getDataLabels().setShowCategoryName(true); + DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.getDefault()); + String thousandSeparator = Character.toString(symbols.getGroupingSeparator()); + series.getDataLabels().getNumberFormat().setFormatCode(String.format("#{0}0", thousandSeparator)); + + doc.save(getArtifactsDir() + "Charts.Treemap.docx"); + //ExEnd:TreemapChart + } + + @Test + public void sunburstChart() throws Exception + { + //ExStart:SunburstChart + //GistId:a76df4b18bee76d169e55cdf6af8129c + //ExFor:ChartSeriesCollection.Add(String, ChartMultilevelValue[], double[]) + //ExSummary:Shows how to create sunburst chart. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a Sunburst chart. + Shape shape = builder.insertChart(ChartType.SUNBURST, 450.0, 450.0); + Chart chart = shape.getChart(); + chart.getTitle().setText("Sales"); + + // Delete default generated series. + chart.getSeries().clear(); + + // Add a series. + ChartSeries series = chart.getSeries().add( + "Sales", + new ChartMultilevelValue[] + { + new ChartMultilevelValue("Sales - Europe", "UK", "London Dep."), + new ChartMultilevelValue("Sales - Europe", "UK", "Liverpool Dep."), + new ChartMultilevelValue("Sales - Europe", "UK", "Manchester Dep."), + new ChartMultilevelValue("Sales - Europe", "France", "Paris Dep."), + new ChartMultilevelValue("Sales - Europe", "France", "Lyon Dep."), + new ChartMultilevelValue("Sales - NA", "USA", "Denver Dep."), + new ChartMultilevelValue("Sales - NA", "USA", "Seattle Dep."), + new ChartMultilevelValue("Sales - NA", "USA", "Detroit Dep."), + new ChartMultilevelValue("Sales - NA", "USA", "Houston Dep."), + new ChartMultilevelValue("Sales - NA", "Canada", "Toronto Dep."), + new ChartMultilevelValue("Sales - NA", "Canada", "Montreal Dep."), + new ChartMultilevelValue("Sales - Oceania", "Australia", "Sydney Dep."), + new ChartMultilevelValue("Sales - Oceania", "New Zealand", "Auckland Dep.") + }, + new double[] { 1236.0, 851.0, 536.0, 468.0, 179.0, 527.0, 799.0, 1148.0, 921.0, 457.0, 482.0, 761.0, 694.0 }); + + // Show data labels. + series.hasDataLabels(true); + series.getDataLabels().setShowValue(false); + series.getDataLabels().setShowCategoryName(true); + + doc.save(getArtifactsDir() + "Charts.Sunburst.docx"); + //ExEnd:SunburstChart + } + + @Test + public void histogramChart() throws Exception + { + //ExStart:HistogramChart + //GistId:a76df4b18bee76d169e55cdf6af8129c + //ExFor:ChartSeriesCollection.Add(String, double[]) + //ExSummary:Shows how to create histogram chart. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a Histogram chart. + Shape shape = builder.insertChart(ChartType.HISTOGRAM, 450.0, 450.0); + Chart chart = shape.getChart(); + chart.getTitle().setText("Avg Temperature since 1991"); + + // Delete default generated series. + chart.getSeries().clear(); + + // Add a series. + chart.getSeries().add( + "Avg Temperature", + new double[] + { + 51.8, 53.6, 50.3, 54.7, 53.9, 54.3, 53.4, 52.9, 53.3, 53.7, 53.8, 52.0, 55.0, 52.1, 53.4, + 53.8, 53.8, 51.9, 52.1, 52.7, 51.8, 56.6, 53.3, 55.6, 56.3, 56.2, 56.1, 56.2, 53.6, 55.7, + 56.3, 55.9, 55.6 + }); + + doc.save(getArtifactsDir() + "Charts.Histogram.docx"); + //ExEnd:HistogramChart + } + + @Test + public void paretoChart() throws Exception + { + //ExStart:ParetoChart + //GistId:a76df4b18bee76d169e55cdf6af8129c + //ExFor:ChartSeriesCollection.Add(String, String[], double[]) + //ExSummary:Shows how to create pareto chart. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a Pareto chart. + Shape shape = builder.insertChart(ChartType.PARETO, 450.0, 450.0); + Chart chart = shape.getChart(); + chart.getTitle().setText("Best-Selling Car"); + + // Delete default generated series. + chart.getSeries().clear(); + + // Add a series. + chart.getSeries().add( + "Best-Selling Car", + new String[] { "Tesla Model Y", "Toyota Corolla", "Toyota RAV4", "Ford F-Series", "Honda CR-V" }, + new double[] { 1.43, 0.91, 1.17, 0.98, 0.85 }); + + doc.save(getArtifactsDir() + "Charts.Pareto.docx"); + //ExEnd:ParetoChart + } + + @Test + public void boxAndWhiskerChart() throws Exception + { + //ExStart:BoxAndWhiskerChart + //GistId:a76df4b18bee76d169e55cdf6af8129c + //ExFor:ChartSeriesCollection.Add(String, String[], double[]) + //ExSummary:Shows how to create box and whisker chart. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a Box & Whisker chart. + Shape shape = builder.insertChart(ChartType.BOX_AND_WHISKER, 450.0, 450.0); + Chart chart = shape.getChart(); + chart.getTitle().setText("Points by Years"); + + // Delete default generated series. + chart.getSeries().clear(); + + // Add a series. + ChartSeries series = chart.getSeries().add( + "Points by Years", + new String[] + { + "WC", "WC", "WC", "WC", "WC", "WC", "WC", "WC", "WC", "WC", + "NR", "NR", "NR", "NR", "NR", "NR", "NR", "NR", "NR", "NR", + "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA" + }, + new double[] + { + 91.0, 80.0, 100.0, 77.0, 90.0, 104.0, 105.0, 118.0, 120.0, 101.0, + 114.0, 107.0, 110.0, 60.0, 79.0, 78.0, 77.0, 102.0, 101.0, 113.0, + 94.0, 93.0, 84.0, 71.0, 80.0, 103.0, 80.0, 94.0, 100.0, 101.0 + }); + + // Show data labels. + series.hasDataLabels(true); + + doc.save(getArtifactsDir() + "Charts.BoxAndWhisker.docx"); + //ExEnd:BoxAndWhiskerChart + } + + @Test + public void waterfallChart() throws Exception + { + //ExStart:WaterfallChart + //GistId:a76df4b18bee76d169e55cdf6af8129c + //ExFor:ChartSeriesCollection.Add(String, String[], double[], bool[]) + //ExSummary:Shows how to create waterfall chart. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a Waterfall chart. + Shape shape = builder.insertChart(ChartType.WATERFALL, 450.0, 450.0); + Chart chart = shape.getChart(); + chart.getTitle().setText("New Zealand GDP"); + + // Delete default generated series. + chart.getSeries().clear(); + + // Add a series. + ChartSeries series = chart.getSeries().add( + "New Zealand GDP", + new String[] { "2018", "2019 growth", "2020 growth", "2020", "2021 growth", "2022 growth", "2022" }, + new double[] { 100.0, 0.57, -0.25, 100.32, 20.22, -2.92, 117.62 }, + new boolean[] { true, false, false, true, false, false, true }); + + // Show data labels. + series.hasDataLabels(true); + + doc.save(getArtifactsDir() + "Charts.Waterfall.docx"); + //ExEnd:WaterfallChart + } + + @Test + public void funnelChart() throws Exception + { + //ExStart:FunnelChart + //GistId:a76df4b18bee76d169e55cdf6af8129c + //ExFor:ChartSeriesCollection.Add(String, String[], double[]) + //ExSummary:Shows how to create funnel chart. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a Funnel chart. + Shape shape = builder.insertChart(ChartType.FUNNEL, 450.0, 450.0); + Chart chart = shape.getChart(); + chart.getTitle().setText("Population by Age Group"); + + // Delete default generated series. + chart.getSeries().clear(); + + // Add a series. + ChartSeries series = chart.getSeries().add( + "Population by Age Group", + new String[] { "0-9", "10-19", "20-29", "30-39", "40-49", "50-59", "60-69", "70-79", "80-89", "90-" }, + new double[] { 0.121, 0.128, 0.132, 0.146, 0.124, 0.124, 0.111, 0.075, 0.032, 0.007 }); + + // Show data labels. + series.hasDataLabels(true); + DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.getDefault()); + String decimalSeparator = Character.toString(symbols.getGroupingSeparator()); + series.getDataLabels().getNumberFormat().setFormatCode("0" + decimalSeparator + "0%"); + + doc.save(getArtifactsDir() + "Charts.Funnel.docx"); + //ExEnd:FunnelChart + } + + @Test + public void labelOrientationRotation() throws Exception + { + //ExStart:LabelOrientationRotation + //GistId:67585b023474b7f73b0066dd022cf938 + //ExFor:ChartDataLabelCollection.Orientation + //ExFor:ChartDataLabelCollection.Rotation + //ExFor:ChartDataLabel.Rotation + //ExFor:ChartDataLabel.Orientation + //ExFor:ShapeTextOrientation + //ExSummary:Shows how to change orientation and rotation for data labels. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + ChartSeries series = shape.getChart().getSeries().get(0); + ChartDataLabelCollection dataLabels = series.getDataLabels(); + + // Show data labels. + series.hasDataLabels(true); + dataLabels.setShowValue(true); + dataLabels.setShowCategoryName(true); + + // Define data label shape. + dataLabels.getFormat().setShapeType(ChartShapeType.UP_ARROW); + dataLabels.getFormat().getStroke().getFill().solid(Color.blue); + + // Set data label orientation and rotation for the entire series. + dataLabels.setOrientation(ShapeTextOrientation.VERTICAL_FAR_EAST); + dataLabels.setRotation(-45); + + // Change orientation and rotation of the first data label. + dataLabels.get(0).setOrientation(ShapeTextOrientation.HORIZONTAL); + dataLabels.get(0).setRotation(45); + + doc.save(getArtifactsDir() + "Charts.LabelOrientationRotation.docx"); + //ExEnd:LabelOrientationRotation + } + + @Test + public void tickLabelsOrientationRotation() throws Exception + { + //ExStart:TickLabelsOrientationRotation + //GistId:0ede368e82d1e97d02e615a76923846b + //ExFor:AxisTickLabels.Rotation + //ExFor:AxisTickLabels.Orientation + //ExSummary:Shows how to change orientation and rotation for axis tick labels. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a column chart. + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + AxisTickLabels xTickLabels = shape.getChart().getAxisX().getTickLabels(); + AxisTickLabels yTickLabels = shape.getChart().getAxisY().getTickLabels(); + + // Set axis tick label orientation and rotation. + xTickLabels.setOrientation(ShapeTextOrientation.VERTICAL_FAR_EAST); + xTickLabels.setRotation(-30); + yTickLabels.setOrientation(ShapeTextOrientation.HORIZONTAL); + yTickLabels.setRotation(45); + + doc.save(getArtifactsDir() + "Charts.TickLabelsOrientationRotation.docx"); + //ExEnd:TickLabelsOrientationRotation + } + + @Test + public void doughnutChart() throws Exception + { + //ExStart:DoughnutChart + //GistId:3f058a176ba0e9f656c60c6d60d757a1 + //ExFor:ChartSeriesGroup.DoughnutHoleSize + //ExFor:ChartSeriesGroup.FirstSliceAngle + //ExSummary:Shows how to create and format Doughnut chart. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.DOUGHNUT, 400.0, 400.0); + Chart chart = shape.getChart(); + // Delete the default generated series. + chart.getSeries().clear(); + + String[] categories = new String[] { "Category 1", "Category 2", "Category 3" }; + chart.getSeries().add("Series 1", categories, new double[] { 4.0, 2.0, 5.0 }); + + // Format the Doughnut chart. + ChartSeriesGroup seriesGroup = chart.getSeriesGroups().get(0); + seriesGroup.setDoughnutHoleSize(10); + seriesGroup.setFirstSliceAngle(270); + + doc.save(getArtifactsDir() + "Charts.DoughnutChart.docx"); + //ExEnd:DoughnutChart + } + + @Test + public void pieOfPieChart() throws Exception + { + //ExStart:PieOfPieChart + //GistId:3f058a176ba0e9f656c60c6d60d757a1 + //ExFor:ChartSeriesGroup.SecondSectionSize + //ExSummary:Shows how to create and format pie of Pie chart. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.PIE_OF_PIE, 440.0, 300.0); + Chart chart = shape.getChart(); + // Delete the default generated series. + chart.getSeries().clear(); + + String[] categories = new String[] { "Category 1", "Category 2", "Category 3", "Category 4" }; + chart.getSeries().add("Series 1", categories, new double[] { 11.0, 8.0, 4.0, 3.0 }); + + // Format the Pie of Pie chart. + ChartSeriesGroup seriesGroup = chart.getSeriesGroups().get(0); + seriesGroup.setGapWidth(10); + seriesGroup.setSecondSectionSize(77); + + doc.save(getArtifactsDir() + "Charts.PieOfPieChart.docx"); + //ExEnd:PieOfPieChart + } + + @Test + public void formatCode() throws Exception + { + //ExStart:FormatCode + //GistId:72d57eeddb7fb342fd51b26e5fcf9642 + //ExFor:ChartXValueCollection.FormatCode + //ExFor:ChartYValueCollection.FormatCode + //ExFor:BubbleSizeCollection.FormatCode + //ExFor:ChartSeries.BubbleSizes + //ExFor:ChartSeries.XValues + //ExFor:ChartSeries.YValues + //ExSummary:Shows how to work with the format code of the chart data. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a Bubble chart. + Shape shape = builder.insertChart(ChartType.BUBBLE, 432.0, 252.0); + Chart chart = shape.getChart(); + + // Delete default generated series. + chart.getSeries().clear(); + + ChartSeries series = chart.getSeries().add( + "Series1", + new double[] { 1.0, 1.9, 2.45, 3.0 }, + new double[] { 1.0, -0.9, 1.82, 0.0 }, + new double[] { 2.0, 1.1, 2.95, 2.0 }); + + // Show data labels. + series.hasDataLabels(true); + series.getDataLabels().setShowCategoryName(true); + series.getDataLabels().setShowValue(true); + series.getDataLabels().setShowBubbleSize(true); + + // Set data format codes. + series.getXValues().setFormatCode("#,##0.0#"); + series.getYValues().setFormatCode("#,##0.0#;[Red]\\-#,##0.0#"); + series.getBubbleSizes().setFormatCode("#,##0.0#"); + + doc.save(getArtifactsDir() + "Charts.FormatCode.docx"); + //ExEnd:FormatCode + + doc = new Document(getArtifactsDir() + "Charts.FormatCode.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + chart = shape.getChart(); + + ChartSeriesCollection seriesCollection = chart.getSeries(); + for (ChartSeries seriesProperties : seriesCollection) + { + Assert.assertEquals("#,##0.0#", seriesProperties.getXValues().getFormatCode()); + Assert.assertEquals("#,##0.0#;[Red]\\-#,##0.0#", seriesProperties.getYValues().getFormatCode()); + Assert.assertEquals("#,##0.0#", seriesProperties.getBubbleSizes().getFormatCode()); + } + } + + @Test + public void dataLablePosition() throws Exception + { + //ExStart:DataLablePosition + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:ChartDataLabelCollection.Position + //ExFor:ChartDataLabel.Position + //ExFor:ChartDataLabelPosition + //ExSummary:Shows how to set the position of the data label. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert column chart. + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + Chart chart = shape.getChart(); + ChartSeriesCollection seriesColl = chart.getSeries(); + + // Delete default generated series. + seriesColl.clear(); + + // Add series. + ChartSeries series = seriesColl.add( + "Series 1", + new String[] { "Category 1", "Category 2", "Category 3" }, + new double[] { 4.0, 5.0, 6.0 }); + + // Show data labels and set font color. + series.hasDataLabels(true); + ChartDataLabelCollection dataLabels = series.getDataLabels(); + dataLabels.setShowValue(true); + dataLabels.getFont().setColor(Color.WHITE); + + // Set data label position. + dataLabels.setPosition(ChartDataLabelPosition.INSIDE_BASE); + dataLabels.get(0).setPosition(ChartDataLabelPosition.OUTSIDE_END); + dataLabels.get(0).getFont().setColor(Color.RED); + + doc.save(getArtifactsDir() + "Charts.LabelPosition.docx"); + //ExEnd:DataLablePosition + } + + @Test + public void doughnutChartLabelPosition() throws Exception + { + //ExStart:DoughnutChartLabelPosition + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:ChartDataLabel.Left + //ExFor:ChartDataLabel.LeftMode + //ExFor:ChartDataLabel.Top + //ExFor:ChartDataLabel.TopMode + //ExFor:ChartDataLabelLocationMode + //ExSummary:Shows how to place data labels of doughnut chart outside doughnut. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + final int CHART_WIDTH = 432; + final int CHART_HEIGHT = 252; + Shape shape = builder.insertChart(ChartType.DOUGHNUT, CHART_WIDTH, CHART_HEIGHT); + Chart chart = shape.getChart(); + ChartSeriesCollection seriesColl = chart.getSeries(); + // Delete default generated series. + seriesColl.clear(); + + // Hide the legend. + chart.getLegend().setPosition(LegendPosition.NONE); + + // Generate data. + final int DATA_LENGTH = 20; + double totalValue = 0.0; + String[] categories = new String[DATA_LENGTH]; + double[] values = new double[DATA_LENGTH]; + for (int i = 0; i < DATA_LENGTH; i++) + { + categories[i] = MessageFormat.format("Category {0}", i); + values[i] = DATA_LENGTH - i; + totalValue += values[i]; + } + + ChartSeries series = seriesColl.add("Series 1", categories, values); + series.hasDataLabels(true); + + ChartDataLabelCollection dataLabels = series.getDataLabels(); + dataLabels.setShowValue(true); + dataLabels.setShowLeaderLines(true); + + // The Position property cannot be used for doughnut charts. Let's place data labels using the Left and Top + // properties around a circle outside of the chart doughnut. + // The origin is in the upper left corner of the chart. + + final double TITLE_AREA_HEIGHT = 25.5; // This can be calculated using title text and font. + final double DOUGHNUT_CENTER_Y = TITLE_AREA_HEIGHT + (CHART_HEIGHT - TITLE_AREA_HEIGHT) / 2.0; + final double DOUGHNUT_CENTER_X = CHART_WIDTH / 2d; + final double LABEL_HEIGHT = 16.5; // This can be calculated using label font. + final double ONE_CHAR_LABEL_WIDTH = 12.75; // This can be calculated for each label using its text and font. + final double TWO_CHAR_LABEL_WIDTH = 17.25; // This can be calculated for each label using its text and font. + final double Y_MARGIN = 0.75; + final double LABEL_MARGIN = 1.5; + final double LABEL_CIRCLE_RADIUS = CHART_HEIGHT - DOUGHNUT_CENTER_Y - Y_MARGIN - LABEL_HEIGHT / 2.0; + + // Because the data points start at the top, the X coordinates used in the Left and Top properties of + // the data labels point to the right and the Y coordinates point down, the starting angle is -PI/2. + double totalAngle = -Math.PI / 2f; + ChartDataLabel previousLabel = null; + + for (int i = 0; i < series.getYValues().getCount(); i++) + { + ChartDataLabel dataLabel = dataLabels.get(i); + + double value = series.getYValues().get(i).getDoubleValue(); + double labelWidth; + if (value < 10) + labelWidth = ONE_CHAR_LABEL_WIDTH; + else + labelWidth = TWO_CHAR_LABEL_WIDTH; + double labelSegmentAngle = value / totalValue * 2.0 * Math.PI; + double labelAngle = labelSegmentAngle / 2.0 + totalAngle; + double labelCenterX = LABEL_CIRCLE_RADIUS * Math.cos(labelAngle) + DOUGHNUT_CENTER_X; + double labelCenterY = LABEL_CIRCLE_RADIUS * Math.sin(labelAngle) + DOUGHNUT_CENTER_Y; + double labelLeft = labelCenterX - labelWidth / 2.0; + double labelTop = labelCenterY - LABEL_HEIGHT / 2.0; + + // If the current data label overlaps other labels, move it horizontally. + if ((previousLabel != null) && + (Math.abs(previousLabel.getTop() - labelTop) < LABEL_HEIGHT) && + (Math.abs(previousLabel.getLeft() - labelLeft) < labelWidth)) + { + // Move right on the top, left on the bottom. + boolean isOnTop = (totalAngle < 0) || (totalAngle >= Math.PI); + int factor; + if (isOnTop) + factor = 1; + else + factor = -1; + + labelLeft = previousLabel.getLeft() + labelWidth * factor + LABEL_MARGIN; + } + + dataLabel.setLeft(labelLeft); + dataLabel.setLeftMode(ChartDataLabelLocationMode.ABSOLUTE); + dataLabel.setTop(labelTop); + dataLabel.setTopMode(ChartDataLabelLocationMode.ABSOLUTE); + + totalAngle += labelSegmentAngle; + previousLabel = dataLabel; + } + + doc.save(getArtifactsDir() + "Charts.DoughnutChartLabelPosition.docx"); + //ExEnd:DoughnutChartLabelPosition + } + + @Test + public void insertChartSeries() throws Exception + { + //ExStart + //ExFor:ChartSeries.Insert(Int32, ChartXValue) + //ExFor:ChartSeries.Insert(Int32, ChartXValue, ChartYValue) + //ExFor:ChartSeries.Insert(Int32, ChartXValue, ChartYValue, double) + //ExSummary:Shows how to insert data into a chart series. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.LINE, 432.0, 252.0); + Chart chart = shape.getChart(); + ChartSeries series1 = chart.getSeries().get(0); + + // Clear X and Y values of the first series. + series1.clearValues(); + // Populate the series with data. + series1.insert(0, ChartXValue.fromDouble(3.0)); + series1.insert(1, ChartXValue.fromDouble(3.0), ChartYValue.fromDouble(10.0)); + series1.insert(2, ChartXValue.fromDouble(3.0), ChartYValue.fromDouble(10.0)); + series1.insert(3, ChartXValue.fromDouble(3.0), ChartYValue.fromDouble(10.0), 10.0); + + doc.save(getArtifactsDir() + "Charts.PopulateChartWithData.docx"); + //ExEnd + } + + @Test + public void setChartStyle() throws Exception + { + //ExStart:SetChartStyle + //GistId:b62c3f2b553726aa85992f50f6d39aaa + //ExFor:ChartStyle + //ExSummary:Shows how to set and get chart style. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a chart in the Black style. + builder.insertChart(ChartType.COLUMN, 400.0, 250.0, ChartStyle.BLACK); + + doc.save(getArtifactsDir() + "Charts.SetChartStyle.docx"); + + doc = new Document(getArtifactsDir() + "Charts.SetChartStyle.docx"); + + // Get a chart to update. + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + Chart chart = shape.getChart(); + + // Get the chart style. + Assert.assertEquals(ChartStyle.BLACK, chart.getStyle()); + //ExEnd:SetChartStyle + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExChmLoadOptions.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExChmLoadOptions.java new file mode 100644 index 00000000..47c99279 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExChmLoadOptions.java @@ -0,0 +1,42 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import org.testng.annotations.Test; +import com.aspose.words.ChmLoadOptions; +import com.aspose.words.Document; + +import java.io.ByteArrayInputStream; +import java.nio.file.Files; +import java.nio.file.Paths; + +@Test +public class ExChmLoadOptions extends ApiExampleBase +{ + @Test + public void originalFileName() throws Exception + { + //ExStart + //ExFor:ChmLoadOptions + //ExFor:ChmLoadOptions.#ctor + //ExFor:ChmLoadOptions.OriginalFileName + //ExSummary:Shows how to resolve URLs like "ms-its:myfile.chm::/index.htm". + // Our document contains URLs like "ms-its:amhelp.chm::....htm", but it has a different name, + // so file links don't work after saving it to HTML. + // We need to define the original filename in 'ChmLoadOptions' to avoid this behavior. + ChmLoadOptions loadOptions = new ChmLoadOptions(); { loadOptions.setOriginalFileName("amhelp.chm"); } + + Document doc = new Document(new ByteArrayInputStream(Files.readAllBytes(Paths.get(getMyDir() + "Document with ms-its links.chm"))), + loadOptions); + + doc.save(getArtifactsDir() + "ExChmLoadOptions.OriginalFileName.html"); + //ExEnd + } +} + diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExCleanupOptions.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExCleanupOptions.java new file mode 100644 index 00000000..6f767c72 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExCleanupOptions.java @@ -0,0 +1,117 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.List; +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.awt.*; + +public class ExCleanupOptions extends ApiExampleBase { + @Test + public void removeUnusedResources() throws Exception { + //ExStart + //ExFor:Document.Cleanup(CleanupOptions) + //ExFor:CleanupOptions + //ExFor:CleanupOptions.UnusedLists + //ExFor:CleanupOptions.UnusedStyles + //ExFor:CleanupOptions.UnusedBuiltinStyles + //ExSummary:Shows how to remove all unused custom styles from a document. + Document doc = new Document(); + + doc.getStyles().add(StyleType.LIST, "MyListStyle1"); + doc.getStyles().add(StyleType.LIST, "MyListStyle2"); + doc.getStyles().add(StyleType.CHARACTER, "MyParagraphStyle1"); + doc.getStyles().add(StyleType.CHARACTER, "MyParagraphStyle2"); + + // Combined with the built-in styles, the document now has eight styles. + // A custom style is marked as "used" while there is any text within the document + // formatted in that style. This means that the 4 styles we added are currently unused. + Assert.assertEquals(8, doc.getStyles().getCount()); + + // Apply a custom character style, and then a custom list style. Doing so will mark them as "used". + DocumentBuilder builder = new DocumentBuilder(doc); + builder.getFont().setStyle(doc.getStyles().get("MyParagraphStyle1")); + builder.writeln("Hello world!"); + + List docList = doc.getLists().add(doc.getStyles().get("MyListStyle1")); + builder.getListFormat().setList(docList); + builder.writeln("Item 1"); + builder.writeln("Item 2"); + + // Now, there is one unused character style and one unused list style. + // The Cleanup() method, when configured with a CleanupOptions object, can target unused styles and remove them. + CleanupOptions cleanupOptions = new CleanupOptions(); + cleanupOptions.setUnusedLists(true); + cleanupOptions.setUnusedStyles(true); + cleanupOptions.setUnusedBuiltinStyles(true); + + doc.cleanup(cleanupOptions); + + Assert.assertEquals(4, doc.getStyles().getCount()); + + // Removing every node that a custom style is applied to marks it as "unused" again. + // Rerun the Cleanup method to remove them. + doc.getFirstSection().getBody().removeAllChildren(); + doc.cleanup(cleanupOptions); + + Assert.assertEquals(2, doc.getStyles().getCount()); + //ExEnd + } + + @Test + public void removeDuplicateStyles() throws Exception { + //ExStart + //ExFor:CleanupOptions.DuplicateStyle + //ExSummary:Shows how to remove duplicated styles from the document. + Document doc = new Document(); + + // Add two styles to the document with identical properties, + // but different names. The second style is considered a duplicate of the first. + Style myStyle = doc.getStyles().add(StyleType.PARAGRAPH, "MyStyle1"); + myStyle.getFont().setSize(14.0); + myStyle.getFont().setName("Courier New"); + myStyle.getFont().setColor(Color.BLUE); + + Style duplicateStyle = doc.getStyles().add(StyleType.PARAGRAPH, "MyStyle2"); + duplicateStyle.getFont().setSize(14.0); + duplicateStyle.getFont().setName("Courier New"); + duplicateStyle.getFont().setColor(Color.BLUE); + + Assert.assertEquals(6, doc.getStyles().getCount()); + + // Apply both styles to different paragraphs within the document. + DocumentBuilder builder = new DocumentBuilder(doc); + builder.getParagraphFormat().setStyleName(myStyle.getName()); + builder.writeln("Hello world!"); + + builder.getParagraphFormat().setStyleName(duplicateStyle.getName()); + builder.writeln("Hello again!"); + + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + Assert.assertEquals(myStyle, paragraphs.get(0).getParagraphFormat().getStyle()); + Assert.assertEquals(duplicateStyle, paragraphs.get(1).getParagraphFormat().getStyle()); + + // Configure a CleanOptions object, then call the Cleanup method to substitute all duplicate styles + // with the original and remove the duplicates from the document. + CleanupOptions cleanupOptions = new CleanupOptions(); + cleanupOptions.setDuplicateStyle(true); + + doc.cleanup(cleanupOptions); + + Assert.assertEquals(5, doc.getStyles().getCount()); + Assert.assertEquals(myStyle, paragraphs.get(0).getParagraphFormat().getStyle()); + Assert.assertEquals(myStyle, paragraphs.get(1).getParagraphFormat().getStyle()); + //ExEnd + } +} + diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExComment.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExComment.java new file mode 100644 index 00000000..c5caf9bb --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExComment.java @@ -0,0 +1,349 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.text.MessageFormat; +import java.util.Date; + +public class ExComment extends ApiExampleBase { + @Test + public void addCommentWithReply() throws Exception { + //ExStart + //ExFor:Comment + //ExFor:Comment.SetText(String) + //ExFor:Comment.AddReply(String, String, DateTime, String) + //ExSummary:Shows how to add a comment to a document, and then reply to it. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Comment comment = new Comment(doc, "John Doe", "J.D.", new Date()); + comment.setText("My comment."); + + // Place the comment at a node in the document's body. + // This comment will show up at the location of its paragraph, + // outside the right-side margin of the page, and with a dotted line connecting it to its paragraph. + builder.getCurrentParagraph().appendChild(comment); + + // Add a reply, which will show up under its parent comment. + comment.addReply("Joe Bloggs", "J.B.", new Date(), "New reply"); + + // Comments and replies are both Comment nodes. + Assert.assertEquals(2, doc.getChildNodes(NodeType.COMMENT, true).getCount()); + + // Comments that do not reply to other comments are "top-level". They have no ancestor comments. + Assert.assertNull(comment.getAncestor()); + + // Replies have an ancestor top-level comment. + Assert.assertEquals(comment, comment.getReplies().get(0).getAncestor()); + + doc.save(getArtifactsDir() + "Comment.AddCommentWithReply.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Comment.AddCommentWithReply.docx"); + Comment docComment = (Comment) doc.getChild(NodeType.COMMENT, 0, true); + + Assert.assertEquals(1, docComment.getCount()); + Assert.assertEquals(1, comment.getReplies().getCount()); + + Assert.assertEquals("\u0005My comment.\r", docComment.getText()); + Assert.assertEquals("\u0005New reply\r", docComment.getReplies().get(0).getText()); + } + + @Test + public void printAllComments() throws Exception { + //ExStart + //ExFor:Comment.Ancestor + //ExFor:Comment.Author + //ExFor:Comment.Replies + //ExFor:CompositeNode.GetEnumerator + //ExFor:CompositeNode.GetChildNodes(NodeType, Boolean) + //ExSummary:Shows how to print all of a document's comments and their replies. + Document doc = new Document(getMyDir() + "Comments.docx"); + + NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true); + Assert.assertEquals(12, comments.getCount()); //ExSkip + + // If a comment has no ancestor, it is a "top-level" comment as opposed to a reply-type comment. + // Print all top-level comments along with any replies they may have. + for (Comment comment : (Iterable) comments) { + if (comment.getAncestor() == null) { + System.out.println("Top-level comment:"); + System.out.println("\t\"{comment.GetText().Trim()}\", by {comment.Author}"); + System.out.println("Has {comment.Replies.Count} replies"); + for (Comment commentReply : comment.getReplies()) { + System.out.println("\t\"{commentReply.GetText().Trim()}\", by {commentReply.Author}"); + } + System.out.println(); + } + } + //ExEnd + } + + @Test + public void removeCommentReplies() throws Exception { + //ExStart + //ExFor:Comment.RemoveAllReplies + //ExFor:Comment.RemoveReply(Comment) + //ExFor:CommentCollection.Item(Int32) + //ExSummary:Shows how to remove comment replies. + Document doc = new Document(); + + Comment comment = new Comment(doc, "John Doe", "J.D.", new Date()); + comment.setText("My comment."); + + doc.getFirstSection().getBody().getFirstParagraph().appendChild(comment); + + comment.addReply("Joe Bloggs", "J.B.", new Date(), "New reply"); + comment.addReply("Joe Bloggs", "J.B.", new Date(), "Another reply"); + + Assert.assertEquals(2, comment.getReplies().getCount()); + + // Below are two ways of removing replies from a comment. + // 1 - Use the "RemoveReply" method to remove replies from a comment individually: + comment.removeReply(comment.getReplies().get(0)); + + Assert.assertEquals(1, comment.getReplies().getCount()); + + // 2 - Use the "RemoveAllReplies" method to remove all replies from a comment at once: + comment.removeAllReplies(); + + Assert.assertEquals(0, comment.getReplies().getCount()); + //ExEnd + } + + @Test + public void done() throws Exception { + //ExStart + //ExFor:Comment.Done + //ExFor:CommentCollection + //ExSummary:Shows how to mark a comment as "done". + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Helo world!"); + + // Insert a comment to point out an error. + Comment comment = new Comment(doc, "John Doe", "J.D.", new Date()); + comment.setText("Fix the spelling error!"); + doc.getFirstSection().getBody().getFirstParagraph().appendChild(comment); + + // Comments have a "Done" flag, which is set to "false" by default. + // If a comment suggests that we make a change within the document, + // we can apply the change, and then also set the "Done" flag afterwards to indicate the correction. + Assert.assertFalse(comment.getDone()); + + doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0).setText("Hello world!"); + comment.setDone(true); + + // Comments that are "done" will differentiate themselves + // from ones that are not "done" with a faded text color. + comment = new Comment(doc, "John Doe", "J.D.", new Date()); + comment.setText("Add text to this paragraph."); + builder.getCurrentParagraph().appendChild(comment); + + doc.save(getArtifactsDir() + "Comment.Done.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Comment.Done.docx"); + comment = (Comment) doc.getChildNodes(NodeType.COMMENT, true).get(0); + + Assert.assertTrue(comment.getDone()); + Assert.assertEquals("Fix the spelling error!", comment.getText().trim()); + Assert.assertEquals("Hello world!", doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0).getText()); + } + + //ExStart + //ExFor:Comment.Done + //ExFor:Comment.#ctor(DocumentBase) + //ExFor:Comment.Accept(DocumentVisitor) + //ExFor:Comment.AcceptStart(DocumentVisitor) + //ExFor:Comment.AcceptEnd(DocumentVisitor) + //ExFor:Comment.DateTime + //ExFor:Comment.Id + //ExFor:Comment.Initial + //ExFor:CommentRangeEnd + //ExFor:CommentRangeEnd.#ctor(DocumentBase,Int32) + //ExFor:CommentRangeEnd.Accept(DocumentVisitor) + //ExFor:CommentRangeEnd.Id + //ExFor:CommentRangeStart + //ExFor:CommentRangeStart.#ctor(DocumentBase,Int32) + //ExFor:CommentRangeStart.Accept(DocumentVisitor) + //ExFor:CommentRangeStart.Id + //ExSummary:Shows how print the contents of all comments and their comment ranges using a document visitor. + @Test //ExSkip + public void createCommentsAndPrintAllInfo() throws Exception { + Document doc = new Document(); + + Comment newComment = new Comment(doc); + { + newComment.setAuthor("VDeryushev"); + newComment.setInitial("VD"); + newComment.setDateTime(new Date()); + } + + newComment.setText("Comment regarding text."); + + // Add text to the document, warp it in a comment range, and then add your comment. + Paragraph para = doc.getFirstSection().getBody().getFirstParagraph(); + para.appendChild(new CommentRangeStart(doc, newComment.getId())); + para.appendChild(new Run(doc, "Commented text.")); + para.appendChild(new CommentRangeEnd(doc, newComment.getId())); + para.appendChild(newComment); + + // Add two replies to the comment. + newComment.addReply("John Doe", "JD", new Date(), "New reply."); + newComment.addReply("John Doe", "JD", new Date(), "Another reply."); + + printAllCommentInfo(doc.getChildNodes(NodeType.COMMENT, true)); + } + + /// + /// Iterates over every top-level comment and prints its comment range, contents, and replies. + /// + private static void printAllCommentInfo(NodeCollection comments) throws Exception { + CommentInfoPrinter commentVisitor = new CommentInfoPrinter(); + + // Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor. + for (Comment comment : (Iterable) comments) { + if (comment.getAncestor() == null) { + // First, visit the start of the comment range. + CommentRangeStart commentRangeStart = (CommentRangeStart) comment.getPreviousSibling().getPreviousSibling().getPreviousSibling(); + commentRangeStart.accept(commentVisitor); + + // Then, visit the comment, and any replies that it may have. + comment.accept(commentVisitor); + + for (Comment reply : comment.getReplies()) + reply.accept(commentVisitor); + + // Finally, visit the end of the comment range, and then print the visitor's text contents. + CommentRangeEnd commentRangeEnd = (CommentRangeEnd) comment.getPreviousSibling(); + commentRangeEnd.accept(commentVisitor); + + System.out.println(commentVisitor.getText()); + } + } + } + + /// + /// Prints information and contents of all comments and comment ranges encountered in the document. + /// + public static class CommentInfoPrinter extends DocumentVisitor { + public CommentInfoPrinter() { + mBuilder = new StringBuilder(); + mVisitorIsInsideComment = false; + } + + /// + /// Gets the plain text of the document that was accumulated by the visitor. + /// + public String getText() { + return mBuilder.toString(); + } + + /// + /// Called when a Run node is encountered in the document. + /// + public int visitRun(Run run) { + if (mVisitorIsInsideComment) indentAndAppendLine("[Run] \"" + run.getText() + "\""); + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a CommentRangeStart node is encountered in the document. + /// + public int visitCommentRangeStart(CommentRangeStart commentRangeStart) { + indentAndAppendLine("[Comment range start] ID: " + commentRangeStart.getId()); + mDocTraversalDepth++; + mVisitorIsInsideComment = true; + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a CommentRangeEnd node is encountered in the document. + /// + public int visitCommentRangeEnd(CommentRangeEnd commentRangeEnd) { + mDocTraversalDepth--; + indentAndAppendLine("[Comment range end] ID: " + commentRangeEnd.getId() + "\n"); + mVisitorIsInsideComment = false; + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a Comment node is encountered in the document. + /// + public int visitCommentStart(Comment comment) { + indentAndAppendLine(MessageFormat.format("[Comment start] For comment range ID {0}, By {1} on {2}", comment.getId(), + comment.getAuthor(), comment.getDateTime())); + mDocTraversalDepth++; + mVisitorIsInsideComment = true; + + return VisitorAction.CONTINUE; + } + + /// + /// Called when the visiting of a Comment node is ended in the document. + /// + public int visitCommentEnd(Comment comment) { + mDocTraversalDepth--; + indentAndAppendLine("[Comment end]"); + mVisitorIsInsideComment = false; + + return VisitorAction.CONTINUE; + } + + /// + /// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree. + /// + /// + private void indentAndAppendLine(String text) { + for (int i = 0; i < mDocTraversalDepth; i++) { + mBuilder.append("| "); + } + + mBuilder.append(text + "\r\n"); + } + + private boolean mVisitorIsInsideComment; + private int mDocTraversalDepth; + private final StringBuilder mBuilder; + } + //ExEnd + + @Test + public void utcDateTime() throws Exception + { + //ExStart:UtcDateTime + //GistId:a76df4b18bee76d169e55cdf6af8129c + //ExFor:Comment.DateTimeUtc + //ExSummary:Shows how to get UTC date and time. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Date dateTime = new Date(); + Comment comment = new Comment(doc, "John Doe", "J.D.", dateTime); + comment.setText("My comment."); + + builder.getCurrentParagraph().appendChild(comment); + + doc.save(getArtifactsDir() + "Comment.UtcDateTime.docx"); + doc = new Document(getArtifactsDir() + "Comment.UtcDateTime.docx"); + + comment = (Comment)doc.getChild(NodeType.COMMENT, 0, true); + // DateTimeUtc return data without milliseconds. + Assert.assertEquals(dateTime.toString(), comment.getDateTimeUtc().toString()); + //ExEnd:UtcDateTime + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExCompatibilityOptions.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExCompatibilityOptions.java new file mode 100644 index 00000000..5f08ea1e --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExCompatibilityOptions.java @@ -0,0 +1,391 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.CompatibilityOptions; +import com.aspose.words.Document; +import com.aspose.words.MsWordVersion; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.ArrayList; + +@Test +public class ExCompatibilityOptions extends ApiExampleBase +{ + //ExStart + //ExFor:Compatibility + //ExFor:CompatibilityOptions + //ExFor:CompatibilityOptions.OptimizeFor(MsWordVersion) + //ExFor:Document.CompatibilityOptions + //ExFor:MsWordVersion + //ExFor:CompatibilityOptions.AdjustLineHeightInTable + //ExFor:CompatibilityOptions.AlignTablesRowByRow + //ExFor:CompatibilityOptions.AllowSpaceOfSameStyleInTable + //ExFor:CompatibilityOptions.ApplyBreakingRules + //ExFor:CompatibilityOptions.AutofitToFirstFixedWidthCell + //ExFor:CompatibilityOptions.AutoSpaceLikeWord95 + //ExFor:CompatibilityOptions.BalanceSingleByteDoubleByteWidth + //ExFor:CompatibilityOptions.CachedColBalance + //ExFor:CompatibilityOptions.ConvMailMergeEsc + //ExFor:CompatibilityOptions.DisableOpenTypeFontFormattingFeatures + //ExFor:CompatibilityOptions.DisplayHangulFixedWidth + //ExFor:CompatibilityOptions.DoNotAutofitConstrainedTables + //ExFor:CompatibilityOptions.DoNotBreakConstrainedForcedTable + //ExFor:CompatibilityOptions.DoNotBreakWrappedTables + //ExFor:CompatibilityOptions.DoNotExpandShiftReturn + //ExFor:CompatibilityOptions.DoNotLeaveBackslashAlone + //ExFor:CompatibilityOptions.DoNotSnapToGridInCell + //ExFor:CompatibilityOptions.DoNotSuppressIndentation + //ExFor:CompatibilityOptions.DoNotSuppressParagraphBorders + //ExFor:CompatibilityOptions.DoNotUseEastAsianBreakRules + //ExFor:CompatibilityOptions.DoNotUseHTMLParagraphAutoSpacing + //ExFor:CompatibilityOptions.DoNotUseIndentAsNumberingTabStop + //ExFor:CompatibilityOptions.DoNotVertAlignCellWithSp + //ExFor:CompatibilityOptions.DoNotVertAlignInTxbx + //ExFor:CompatibilityOptions.DoNotWrapTextWithPunct + //ExFor:CompatibilityOptions.FootnoteLayoutLikeWW8 + //ExFor:CompatibilityOptions.ForgetLastTabAlignment + //ExFor:CompatibilityOptions.GrowAutofit + //ExFor:CompatibilityOptions.LayoutRawTableWidth + //ExFor:CompatibilityOptions.LayoutTableRowsApart + //ExFor:CompatibilityOptions.LineWrapLikeWord6 + //ExFor:CompatibilityOptions.MWSmallCaps + //ExFor:CompatibilityOptions.NoColumnBalance + //ExFor:CompatibilityOptions.NoExtraLineSpacing + //ExFor:CompatibilityOptions.NoLeading + //ExFor:CompatibilityOptions.NoSpaceRaiseLower + //ExFor:CompatibilityOptions.NoTabHangInd + //ExFor:CompatibilityOptions.OverrideTableStyleFontSizeAndJustification + //ExFor:CompatibilityOptions.PrintBodyTextBeforeHeader + //ExFor:CompatibilityOptions.PrintColBlack + //ExFor:CompatibilityOptions.SelectFldWithFirstOrLastChar + //ExFor:CompatibilityOptions.ShapeLayoutLikeWW8 + //ExFor:CompatibilityOptions.ShowBreaksInFrames + //ExFor:CompatibilityOptions.SpaceForUL + //ExFor:CompatibilityOptions.SpacingInWholePoints + //ExFor:CompatibilityOptions.SplitPgBreakAndParaMark + //ExFor:CompatibilityOptions.SubFontBySize + //ExFor:CompatibilityOptions.SuppressBottomSpacing + //ExFor:CompatibilityOptions.SuppressSpacingAtTopOfPage + //ExFor:CompatibilityOptions.SuppressSpBfAfterPgBrk + //ExFor:CompatibilityOptions.SuppressTopSpacing + //ExFor:CompatibilityOptions.SuppressTopSpacingWP + //ExFor:CompatibilityOptions.SwapBordersFacingPgs + //ExFor:CompatibilityOptions.SwapInsideAndOutsideForMirrorIndentsAndRelativePositioning + //ExFor:CompatibilityOptions.TransparentMetafiles + //ExFor:CompatibilityOptions.TruncateFontHeightsLikeWP6 + //ExFor:CompatibilityOptions.UICompat97To2003 + //ExFor:CompatibilityOptions.UlTrailSpace + //ExFor:CompatibilityOptions.UnderlineTabInNumList + //ExFor:CompatibilityOptions.UseAltKinsokuLineBreakRules + //ExFor:CompatibilityOptions.UseAnsiKerningPairs + //ExFor:CompatibilityOptions.UseFELayout + //ExFor:CompatibilityOptions.UseNormalStyleForList + //ExFor:CompatibilityOptions.UsePrinterMetrics + //ExFor:CompatibilityOptions.UseSingleBorderforContiguousCells + //ExFor:CompatibilityOptions.UseWord2002TableStyleRules + //ExFor:CompatibilityOptions.UseWord2010TableStyleRules + //ExFor:CompatibilityOptions.UseWord97LineBreakRules + //ExFor:CompatibilityOptions.WPJustification + //ExFor:CompatibilityOptions.WPSpaceWidth + //ExFor:CompatibilityOptions.WrapTrailSpaces + //ExSummary:Shows how to optimize the document for different versions of Microsoft Word. + @Test //ExSkip + public void optimizeFor() throws Exception + { + Document doc = new Document(); + + // This object contains an extensive list of flags unique to each document + // that allow us to facilitate backward compatibility with older versions of Microsoft Word. + CompatibilityOptions options = doc.getCompatibilityOptions(); + + // Print the default settings for a blank document. + System.out.println("\nDefault optimization settings:"); + printCompatibilityOptions(options); + + // We can access these settings in Microsoft Word via "File" -> "Options" -> "Advanced" -> "Compatibility options for...". + doc.save(getArtifactsDir() + "CompatibilityOptions.OptimizeFor.DefaultSettings.docx"); + + // We can use the OptimizeFor method to ensure optimal compatibility with a specific Microsoft Word version. + doc.getCompatibilityOptions().optimizeFor(MsWordVersion.WORD_2010); + System.out.println("\nOptimized for Word 2010:"); + printCompatibilityOptions(options); + + doc.getCompatibilityOptions().optimizeFor(MsWordVersion.WORD_2000); + System.out.println("\nOptimized for Word 2000:"); + printCompatibilityOptions(options); + } + + /// + /// Groups all flags in a document's compatibility options object by state, then prints each group. + /// + private static void printCompatibilityOptions(CompatibilityOptions options) + { + ArrayList enabledOptions = new ArrayList(); + ArrayList disabledOptions = new ArrayList(); + addOptionName(options.getAdjustLineHeightInTable(), "AdjustLineHeightInTable", enabledOptions, disabledOptions); + addOptionName(options.getAlignTablesRowByRow(), "AlignTablesRowByRow", enabledOptions, disabledOptions); + addOptionName(options.getAllowSpaceOfSameStyleInTable(), "AllowSpaceOfSameStyleInTable", enabledOptions, disabledOptions); + addOptionName(options.getApplyBreakingRules(), "ApplyBreakingRules", enabledOptions, disabledOptions); + addOptionName(options.getAutoSpaceLikeWord95(), "AutoSpaceLikeWord95", enabledOptions, disabledOptions); + addOptionName(options.getAutofitToFirstFixedWidthCell(), "AutofitToFirstFixedWidthCell", enabledOptions, disabledOptions); + addOptionName(options.getBalanceSingleByteDoubleByteWidth(), "BalanceSingleByteDoubleByteWidth", enabledOptions, disabledOptions); + addOptionName(options.getCachedColBalance(), "CachedColBalance", enabledOptions, disabledOptions); + addOptionName(options.getConvMailMergeEsc(), "ConvMailMergeEsc", enabledOptions, disabledOptions); + addOptionName(options.getDisableOpenTypeFontFormattingFeatures(), "DisableOpenTypeFontFormattingFeatures", enabledOptions, disabledOptions); + addOptionName(options.getDisplayHangulFixedWidth(), "DisplayHangulFixedWidth", enabledOptions, disabledOptions); + addOptionName(options.getDoNotAutofitConstrainedTables(), "DoNotAutofitConstrainedTables", enabledOptions, disabledOptions); + addOptionName(options.getDoNotBreakConstrainedForcedTable(), "DoNotBreakConstrainedForcedTable", enabledOptions, disabledOptions); + addOptionName(options.getDoNotBreakWrappedTables(), "DoNotBreakWrappedTables", enabledOptions, disabledOptions); + addOptionName(options.getDoNotExpandShiftReturn(), "DoNotExpandShiftReturn", enabledOptions, disabledOptions); + addOptionName(options.getDoNotLeaveBackslashAlone(), "DoNotLeaveBackslashAlone", enabledOptions, disabledOptions); + addOptionName(options.getDoNotSnapToGridInCell(), "DoNotSnapToGridInCell", enabledOptions, disabledOptions); + addOptionName(options.getDoNotSuppressIndentation(), "DoNotSnapToGridInCell", enabledOptions, disabledOptions); + addOptionName(options.getDoNotSuppressParagraphBorders(), "DoNotSuppressParagraphBorders", enabledOptions, disabledOptions); + addOptionName(options.getDoNotUseEastAsianBreakRules(), "DoNotUseEastAsianBreakRules", enabledOptions, disabledOptions); + addOptionName(options.getDoNotUseHTMLParagraphAutoSpacing(), "DoNotUseHTMLParagraphAutoSpacing", enabledOptions, disabledOptions); + addOptionName(options.getDoNotUseIndentAsNumberingTabStop(), "DoNotUseIndentAsNumberingTabStop", enabledOptions, disabledOptions); + addOptionName(options.getDoNotVertAlignCellWithSp(), "DoNotVertAlignCellWithSp", enabledOptions, disabledOptions); + addOptionName(options.getDoNotVertAlignInTxbx(), "DoNotVertAlignInTxbx", enabledOptions, disabledOptions); + addOptionName(options.getDoNotWrapTextWithPunct(), "DoNotWrapTextWithPunct", enabledOptions, disabledOptions); + addOptionName(options.getFootnoteLayoutLikeWW8(), "FootnoteLayoutLikeWW8", enabledOptions, disabledOptions); + addOptionName(options.getForgetLastTabAlignment(), "ForgetLastTabAlignment", enabledOptions, disabledOptions); + addOptionName(options.getGrowAutofit(), "GrowAutofit", enabledOptions, disabledOptions); + addOptionName(options.getLayoutRawTableWidth(), "LayoutRawTableWidth", enabledOptions, disabledOptions); + addOptionName(options.getLayoutTableRowsApart(), "LayoutTableRowsApart", enabledOptions, disabledOptions); + addOptionName(options.getLineWrapLikeWord6(), "LineWrapLikeWord6", enabledOptions, disabledOptions); + addOptionName(options.getMWSmallCaps(), "MWSmallCaps", enabledOptions, disabledOptions); + addOptionName(options.getNoColumnBalance(), "NoColumnBalance", enabledOptions, disabledOptions); + addOptionName(options.getNoExtraLineSpacing(), "NoExtraLineSpacing", enabledOptions, disabledOptions); + addOptionName(options.getNoLeading(), "NoLeading", enabledOptions, disabledOptions); + addOptionName(options.getNoSpaceRaiseLower(), "NoSpaceRaiseLower", enabledOptions, disabledOptions); + addOptionName(options.getNoTabHangInd(), "NoTabHangInd", enabledOptions, disabledOptions); + addOptionName(options.getOverrideTableStyleFontSizeAndJustification(), "OverrideTableStyleFontSizeAndJustification", enabledOptions, disabledOptions); + addOptionName(options.getPrintBodyTextBeforeHeader(), "PrintBodyTextBeforeHeader", enabledOptions, disabledOptions); + addOptionName(options.getPrintColBlack(), "PrintColBlack", enabledOptions, disabledOptions); + addOptionName(options.getSelectFldWithFirstOrLastChar(), "SelectFldWithFirstOrLastChar", enabledOptions, disabledOptions); + addOptionName(options.getShapeLayoutLikeWW8(), "ShapeLayoutLikeWW8", enabledOptions, disabledOptions); + addOptionName(options.getShowBreaksInFrames(), "ShowBreaksInFrames", enabledOptions, disabledOptions); + addOptionName(options.getSpaceForUL(), "SpaceForUL", enabledOptions, disabledOptions); + addOptionName(options.getSpacingInWholePoints(), "SpacingInWholePoints", enabledOptions, disabledOptions); + addOptionName(options.getSplitPgBreakAndParaMark(), "SplitPgBreakAndParaMark", enabledOptions, disabledOptions); + addOptionName(options.getSubFontBySize(), "SubFontBySize", enabledOptions, disabledOptions); + addOptionName(options.getSuppressBottomSpacing(), "SuppressBottomSpacing", enabledOptions, disabledOptions); + addOptionName(options.getSuppressSpBfAfterPgBrk(), "SuppressSpBfAfterPgBrk", enabledOptions, disabledOptions); + addOptionName(options.getSuppressSpacingAtTopOfPage(), "SuppressSpacingAtTopOfPage", enabledOptions, disabledOptions); + addOptionName(options.getSuppressTopSpacing(), "SuppressTopSpacing", enabledOptions, disabledOptions); + addOptionName(options.getSuppressTopSpacingWP(), "SuppressTopSpacingWP", enabledOptions, disabledOptions); + addOptionName(options.getSwapBordersFacingPgs(), "SwapBordersFacingPgs", enabledOptions, disabledOptions); + addOptionName(options.getSwapInsideAndOutsideForMirrorIndentsAndRelativePositioning(), "SwapInsideAndOutsideForMirrorIndentsAndRelativePositioning", enabledOptions, disabledOptions); + addOptionName(options.getTransparentMetafiles(), "TransparentMetafiles", enabledOptions, disabledOptions); + addOptionName(options.getTruncateFontHeightsLikeWP6(), "TruncateFontHeightsLikeWP6", enabledOptions, disabledOptions); + addOptionName(options.getUICompat97To2003(), "UICompat97To2003", enabledOptions, disabledOptions); + addOptionName(options.getUlTrailSpace(), "UlTrailSpace", enabledOptions, disabledOptions); + addOptionName(options.getUnderlineTabInNumList(), "UnderlineTabInNumList", enabledOptions, disabledOptions); + addOptionName(options.getUseAltKinsokuLineBreakRules(), "UseAltKinsokuLineBreakRules", enabledOptions, disabledOptions); + addOptionName(options.getUseAnsiKerningPairs(), "UseAnsiKerningPairs", enabledOptions, disabledOptions); + addOptionName(options.getUseFELayout(), "UseFELayout", enabledOptions, disabledOptions); + addOptionName(options.getUseNormalStyleForList(), "UseNormalStyleForList", enabledOptions, disabledOptions); + addOptionName(options.getUsePrinterMetrics(), "UsePrinterMetrics", enabledOptions, disabledOptions); + addOptionName(options.getUseSingleBorderforContiguousCells(), "UseSingleBorderforContiguousCells", enabledOptions, disabledOptions); + addOptionName(options.getUseWord2002TableStyleRules(), "UseWord2002TableStyleRules", enabledOptions, disabledOptions); + addOptionName(options.getUseWord2010TableStyleRules(), "UseWord2010TableStyleRules", enabledOptions, disabledOptions); + addOptionName(options.getUseWord97LineBreakRules(), "UseWord97LineBreakRules", enabledOptions, disabledOptions); + addOptionName(options.getWPJustification(), "WPJustification", enabledOptions, disabledOptions); + addOptionName(options.getWPSpaceWidth(), "WPSpaceWidth", enabledOptions, disabledOptions); + addOptionName(options.getWrapTrailSpaces(), "WrapTrailSpaces", enabledOptions, disabledOptions); + System.out.println("\tEnabled options:"); + for (String optionName : enabledOptions) + System.out.println("\t\t{optionName}"); + System.out.println("\tDisabled options:"); + for (String optionName : disabledOptions) + System.out.println("\t\t{optionName}"); + } + + private static void addOptionName(boolean option, String optionName, ArrayList enabledOptions, ArrayList disabledOptions) + { + if (option) + enabledOptions.add(optionName); + else + disabledOptions.add(optionName); + } + //ExEnd + + @Test + public void tables() throws Exception { + Document doc = new Document(); + + CompatibilityOptions compatibilityOptions = doc.getCompatibilityOptions(); + compatibilityOptions.optimizeFor(MsWordVersion.WORD_2002); + + Assert.assertEquals(false, compatibilityOptions.getAdjustLineHeightInTable()); + Assert.assertEquals(false, compatibilityOptions.getAlignTablesRowByRow()); + Assert.assertEquals(true, compatibilityOptions.getAllowSpaceOfSameStyleInTable()); + Assert.assertEquals(true, compatibilityOptions.getDoNotAutofitConstrainedTables()); + Assert.assertEquals(true, compatibilityOptions.getDoNotBreakConstrainedForcedTable()); + Assert.assertEquals(false, compatibilityOptions.getDoNotBreakWrappedTables()); + Assert.assertEquals(false, compatibilityOptions.getDoNotSnapToGridInCell()); + Assert.assertEquals(false, compatibilityOptions.getDoNotUseHTMLParagraphAutoSpacing()); + Assert.assertEquals(true, compatibilityOptions.getDoNotVertAlignCellWithSp()); + Assert.assertEquals(false, compatibilityOptions.getForgetLastTabAlignment()); + Assert.assertEquals(true, compatibilityOptions.getGrowAutofit()); + Assert.assertEquals(false, compatibilityOptions.getLayoutRawTableWidth()); + Assert.assertEquals(false, compatibilityOptions.getLayoutTableRowsApart()); + Assert.assertEquals(false, compatibilityOptions.getNoColumnBalance()); + Assert.assertEquals(false, compatibilityOptions.getOverrideTableStyleFontSizeAndJustification()); + Assert.assertEquals(false, compatibilityOptions.getUseSingleBorderforContiguousCells()); + Assert.assertEquals(true, compatibilityOptions.getUseWord2002TableStyleRules()); + Assert.assertEquals(false, compatibilityOptions.getUseWord2010TableStyleRules()); + + // In the output document, these settings can be accessed in Microsoft Word via + // File -> Options -> Advanced -> Compatibility options for... + doc.save(getArtifactsDir() + "CompatibilityOptions.Tables.docx"); + } + + @Test + public void breaks() throws Exception { + Document doc = new Document(); + + CompatibilityOptions compatibilityOptions = doc.getCompatibilityOptions(); + compatibilityOptions.optimizeFor(MsWordVersion.WORD_2000); + + Assert.assertEquals(false, compatibilityOptions.getApplyBreakingRules()); + Assert.assertEquals(true, compatibilityOptions.getDoNotUseEastAsianBreakRules()); + Assert.assertEquals(false, compatibilityOptions.getShowBreaksInFrames()); + Assert.assertEquals(true, compatibilityOptions.getSplitPgBreakAndParaMark()); + Assert.assertEquals(true, compatibilityOptions.getUseAltKinsokuLineBreakRules()); + Assert.assertEquals(false, compatibilityOptions.getUseWord97LineBreakRules()); + + // In the output document, these settings can be accessed in Microsoft Word via + // File -> Options -> Advanced -> Compatibility options for... + doc.save(getArtifactsDir() + "CompatibilityOptions.Breaks.docx"); + } + + @Test + public void spacing() throws Exception { + Document doc = new Document(); + + CompatibilityOptions compatibilityOptions = doc.getCompatibilityOptions(); + compatibilityOptions.optimizeFor(MsWordVersion.WORD_2000); + + Assert.assertEquals(false, compatibilityOptions.getAutoSpaceLikeWord95()); + Assert.assertEquals(true, compatibilityOptions.getDisplayHangulFixedWidth()); + Assert.assertEquals(false, compatibilityOptions.getNoExtraLineSpacing()); + Assert.assertEquals(false, compatibilityOptions.getNoLeading()); + Assert.assertEquals(false, compatibilityOptions.getNoSpaceRaiseLower()); + Assert.assertEquals(false, compatibilityOptions.getSpaceForUL()); + Assert.assertEquals(false, compatibilityOptions.getSpacingInWholePoints()); + Assert.assertEquals(false, compatibilityOptions.getSuppressBottomSpacing()); + Assert.assertEquals(false, compatibilityOptions.getSuppressSpBfAfterPgBrk()); + Assert.assertEquals(false, compatibilityOptions.getSuppressSpacingAtTopOfPage()); + Assert.assertEquals(false, compatibilityOptions.getSuppressTopSpacing()); + Assert.assertEquals(false, compatibilityOptions.getUlTrailSpace()); + + // In the output document, these settings can be accessed in Microsoft Word via + // File -> Options -> Advanced -> Compatibility options for... + doc.save(getArtifactsDir() + "CompatibilityOptions.Spacing.docx"); + } + + @Test + public void wordPerfect() throws Exception { + Document doc = new Document(); + + CompatibilityOptions compatibilityOptions = doc.getCompatibilityOptions(); + compatibilityOptions.optimizeFor(MsWordVersion.WORD_2000); + + Assert.assertEquals(false, compatibilityOptions.getSuppressTopSpacingWP()); + Assert.assertEquals(false, compatibilityOptions.getTruncateFontHeightsLikeWP6()); + Assert.assertEquals(false, compatibilityOptions.getWPJustification()); + Assert.assertEquals(false, compatibilityOptions.getWPSpaceWidth()); + Assert.assertEquals(false, compatibilityOptions.getWrapTrailSpaces()); + + // In the output document, these settings can be accessed in Microsoft Word via + // File -> Options -> Advanced -> Compatibility options for... + doc.save(getArtifactsDir() + "CompatibilityOptions.WordPerfect.docx"); + } + + @Test + public void alignment() throws Exception { + Document doc = new Document(); + + CompatibilityOptions compatibilityOptions = doc.getCompatibilityOptions(); + compatibilityOptions.optimizeFor(MsWordVersion.WORD_2000); + + Assert.assertEquals(true, compatibilityOptions.getCachedColBalance()); + Assert.assertEquals(true, compatibilityOptions.getDoNotVertAlignInTxbx()); + Assert.assertEquals(true, compatibilityOptions.getDoNotWrapTextWithPunct()); + Assert.assertEquals(false, compatibilityOptions.getNoTabHangInd()); + + // In the output document, these settings can be accessed in Microsoft Word via + // File -> Options -> Advanced -> Compatibility options for... + doc.save(getArtifactsDir() + "CompatibilityOptions.Alignment.docx"); + } + + @Test + public void legacy() throws Exception { + Document doc = new Document(); + + CompatibilityOptions compatibilityOptions = doc.getCompatibilityOptions(); + compatibilityOptions.optimizeFor(MsWordVersion.WORD_2000); + + Assert.assertEquals(false, compatibilityOptions.getFootnoteLayoutLikeWW8()); + Assert.assertEquals(false, compatibilityOptions.getLineWrapLikeWord6()); + Assert.assertEquals(false, compatibilityOptions.getMWSmallCaps()); + Assert.assertEquals(false, compatibilityOptions.getShapeLayoutLikeWW8()); + Assert.assertEquals(false, compatibilityOptions.getUICompat97To2003()); + + // In the output document, these settings can be accessed in Microsoft Word via + // File -> Options -> Advanced -> Compatibility options for... + doc.save(getArtifactsDir() + "CompatibilityOptions.Legacy.docx"); + } + + @Test + public void list() throws Exception { + Document doc = new Document(); + + CompatibilityOptions compatibilityOptions = doc.getCompatibilityOptions(); + compatibilityOptions.optimizeFor(MsWordVersion.WORD_2000); + + Assert.assertEquals(true, compatibilityOptions.getUnderlineTabInNumList()); + Assert.assertEquals(true, compatibilityOptions.getUseNormalStyleForList()); + + // In the output document, these settings can be accessed in Microsoft Word via + // File -> Options -> Advanced -> Compatibility options for... + doc.save(getArtifactsDir() + "CompatibilityOptions.List.docx"); + } + + @Test + public void misc() throws Exception { + Document doc = new Document(); + + CompatibilityOptions compatibilityOptions = doc.getCompatibilityOptions(); + compatibilityOptions.optimizeFor(MsWordVersion.WORD_2000); + + Assert.assertEquals(false, compatibilityOptions.getBalanceSingleByteDoubleByteWidth()); + Assert.assertEquals(false, compatibilityOptions.getConvMailMergeEsc()); + Assert.assertEquals(false, compatibilityOptions.getDoNotExpandShiftReturn()); + Assert.assertEquals(false, compatibilityOptions.getDoNotLeaveBackslashAlone()); + Assert.assertEquals(false, compatibilityOptions.getDoNotSuppressParagraphBorders()); + Assert.assertEquals(true, compatibilityOptions.getDoNotUseIndentAsNumberingTabStop()); + Assert.assertEquals(false, compatibilityOptions.getPrintBodyTextBeforeHeader()); + Assert.assertEquals(false, compatibilityOptions.getPrintColBlack()); + Assert.assertEquals(true, compatibilityOptions.getSelectFldWithFirstOrLastChar()); + Assert.assertEquals(false, compatibilityOptions.getSubFontBySize()); + Assert.assertEquals(false, compatibilityOptions.getSwapBordersFacingPgs()); + Assert.assertEquals(false, compatibilityOptions.getTransparentMetafiles()); + Assert.assertEquals(true, compatibilityOptions.getUseAnsiKerningPairs()); + Assert.assertEquals(false, compatibilityOptions.getUseFELayout()); + Assert.assertEquals(false, compatibilityOptions.getUsePrinterMetrics()); + + // In the output document, these settings can be accessed in Microsoft Word via + // File -> Options -> Advanced -> Compatibility options for... + doc.save(getArtifactsDir() + "CompatibilityOptions.Misc.docx"); + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExControlChar.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExControlChar.java new file mode 100644 index 00000000..67adda9e --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExControlChar.java @@ -0,0 +1,139 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.text.MessageFormat; + +@Test +public class ExControlChar extends ApiExampleBase { + @Test + public void carriageReturn() throws Exception { + //ExStart + //ExFor:ControlChar + //ExFor:ControlChar.Cr + //ExFor:Node.GetText + //ExSummary:Shows how to use control characters. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert paragraphs with text with DocumentBuilder. + builder.writeln("Hello world!"); + builder.writeln("Hello again!"); + + // Converting the document to text form reveals that control characters + // represent some of the document's structural elements, such as page breaks. + Assert.assertEquals(MessageFormat.format("Hello world!{0}", ControlChar.CR) + + MessageFormat.format("Hello again!{0}", ControlChar.CR) + + ControlChar.PAGE_BREAK, doc.getText()); + + // When converting a document to string form, + // we can omit some of the control characters with the Trim method. + Assert.assertEquals(MessageFormat.format("Hello world!{0}", ControlChar.CR) + + "Hello again!", doc.getText().trim()); + //ExEnd + } + + @Test + public void insertControlChars() throws Exception { + //ExStart + //ExFor:ControlChar.Cell + //ExFor:ControlChar.ColumnBreak + //ExFor:ControlChar.CrLf + //ExFor:ControlChar.Lf + //ExFor:ControlChar.LineBreak + //ExFor:ControlChar.LineFeed + //ExFor:ControlChar.NonBreakingSpace + //ExFor:ControlChar.PageBreak + //ExFor:ControlChar.ParagraphBreak + //ExFor:ControlChar.SectionBreak + //ExFor:ControlChar.CellChar + //ExFor:ControlChar.ColumnBreakChar + //ExFor:ControlChar.DefaultTextInputChar + //ExFor:ControlChar.FieldEndChar + //ExFor:ControlChar.FieldStartChar + //ExFor:ControlChar.FieldSeparatorChar + //ExFor:ControlChar.LineBreakChar + //ExFor:ControlChar.LineFeedChar + //ExFor:ControlChar.NonBreakingHyphenChar + //ExFor:ControlChar.NonBreakingSpaceChar + //ExFor:ControlChar.OptionalHyphenChar + //ExFor:ControlChar.PageBreakChar + //ExFor:ControlChar.ParagraphBreakChar + //ExFor:ControlChar.SectionBreakChar + //ExFor:ControlChar.SpaceChar + //ExSummary:Shows how to add various control characters to a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Add a regular space. + builder.write("Before space." + ControlChar.SPACE_CHAR + "After space."); + + // Add an NBSP, which is a non-breaking space. + // Unlike the regular space, this space cannot have an automatic line break at its position. + builder.write("Before space." + ControlChar.NON_BREAKING_SPACE + "After space."); + + // Add a tab character. + builder.write("Before tab." + ControlChar.TAB + "After tab."); + + // Add a line break. + builder.write("Before line break." + ControlChar.LINE_BREAK + "After line break."); + + // Add a new line and starts a new paragraph. + Assert.assertEquals(1, doc.getFirstSection().getBody().getChildNodes(NodeType.PARAGRAPH, true).getCount()); + builder.write("Before line feed." + ControlChar.LINE_FEED + "After line feed."); + Assert.assertEquals(2, doc.getFirstSection().getBody().getChildNodes(NodeType.PARAGRAPH, true).getCount()); + + // The line feed character has two versions. + Assert.assertEquals(ControlChar.LINE_FEED, ControlChar.LF); + + // Carriage returns and line feeds can be represented together by one character. + Assert.assertEquals(ControlChar.CR_LF, ControlChar.CR + ControlChar.LF); + + // Add a paragraph break, which will start a new paragraph. + builder.write("Before paragraph break." + ControlChar.PARAGRAPH_BREAK + "After paragraph break."); + Assert.assertEquals(doc.getFirstSection().getBody().getChildNodes(NodeType.PARAGRAPH, true).getCount(), 3); + + // Add a section break. This does not make a new section or paragraph. + Assert.assertEquals(doc.getSections().getCount(), 1); + builder.write("Before section break." + ControlChar.SECTION_BREAK + "After section break."); + Assert.assertEquals(doc.getSections().getCount(), 1); + + // Add a page break. + builder.write("Before page break." + ControlChar.PAGE_BREAK + "After page break."); + + // A page break is the same value as a section break. + Assert.assertEquals(ControlChar.PAGE_BREAK, ControlChar.SECTION_BREAK); + + // Insert a new section, and then set its column count to two. + doc.appendChild(new Section(doc)); + builder.moveToSection(1); + builder.getCurrentSection().getPageSetup().getTextColumns().setCount(2); + + // We can use a control character to mark the point where text moves to the next column. + builder.write("Text at end of column 1." + ControlChar.COLUMN_BREAK + "Text at beginning of column 2."); + + doc.save(getArtifactsDir() + "ControlChar.InsertControlChars.docx"); + + // There are char and string counterparts for most characters. + Assert.assertEquals(ControlChar.CELL.toCharArray()[0], ControlChar.CELL_CHAR); + Assert.assertEquals(ControlChar.NON_BREAKING_SPACE.toCharArray()[0], ControlChar.NON_BREAKING_SPACE_CHAR); + Assert.assertEquals(ControlChar.TAB.toCharArray()[0], ControlChar.TAB_CHAR); + Assert.assertEquals(ControlChar.LINE_BREAK.toCharArray()[0], ControlChar.LINE_BREAK_CHAR); + Assert.assertEquals(ControlChar.LINE_FEED.toCharArray()[0], ControlChar.LINE_FEED_CHAR); + Assert.assertEquals(ControlChar.PARAGRAPH_BREAK.toCharArray()[0], ControlChar.PARAGRAPH_BREAK_CHAR); + Assert.assertEquals(ControlChar.SECTION_BREAK.toCharArray()[0], ControlChar.SECTION_BREAK_CHAR); + Assert.assertEquals(ControlChar.PAGE_BREAK.toCharArray()[0], ControlChar.SECTION_BREAK_CHAR); + Assert.assertEquals(ControlChar.COLUMN_BREAK.toCharArray()[0], ControlChar.COLUMN_BREAK_CHAR); + //ExEnd + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExDigitalSignatureCollection.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExDigitalSignatureCollection.java new file mode 100644 index 00000000..dbfd2325 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExDigitalSignatureCollection.java @@ -0,0 +1,62 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.DigitalSignature; +import com.aspose.words.DigitalSignatureCollection; +import com.aspose.words.DigitalSignatureType; +import com.aspose.words.DigitalSignatureUtil; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.Iterator; + +public class ExDigitalSignatureCollection extends ApiExampleBase { + @Test + public void iterator() throws Exception { + //ExStart + //ExFor:DigitalSignatureCollection.GetEnumerator + //ExSummary:Shows how to print all the digital signatures of a signed document. + DigitalSignatureCollection digitalSignatures = + DigitalSignatureUtil.loadSignatures(getMyDir() + "Digitally signed.docx"); + + Iterator enumerator = digitalSignatures.iterator(); + while (enumerator.hasNext()) { + DigitalSignature ds = enumerator.next(); + + if (ds != null) + System.out.println(ds.toString()); + } + //ExEnd + + Assert.assertEquals(1, digitalSignatures.getCount()); + + DigitalSignature signature = digitalSignatures.get(0); + + Assert.assertTrue(signature.isValid()); + Assert.assertEquals(DigitalSignatureType.XML_DSIG, signature.getSignatureType()); + Assert.assertEquals("Test Sign", signature.getComments()); + + Assert.assertEquals(signature.getIssuerName(), signature.getIssuerName()); + Assert.assertEquals(signature.getSubjectName(), signature.getSubjectName()); + + Assert.assertEquals("CN=VeriSign Class 3 Code Signing 2009-2 CA, " + + "OU=Terms of use at https://www.verisign.com/rpa (c)09, " + + "OU=VeriSign Trust Network, " + + "O=\"VeriSign, Inc.\", " + + "C=US", signature.getIssuerName()); + + Assert.assertEquals("CN=Aspose Pty Ltd, " + + "OU=Digital ID Class 3 - Microsoft Software Validation v2, " + + "O=Aspose Pty Ltd, " + + "L=Lane Cove, " + + "S=New South Wales, " + + "C=AU", signature.getSubjectName()); + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExDigitalSignatureUtil.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExDigitalSignatureUtil.java new file mode 100644 index 00000000..d7c3467a --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExDigitalSignatureUtil.java @@ -0,0 +1,249 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Date; + +public class ExDigitalSignatureUtil extends ApiExampleBase { + @Test + public void load() throws Exception { + //ExStart + //ExFor:DigitalSignatureUtil + //ExFor:DigitalSignatureUtil.LoadSignatures(String) + //ExFor:DigitalSignatureUtil.LoadSignatures(Stream) + //ExSummary:Shows how to load signatures from a digitally signed document. + // There are two ways of loading a signed document's collection of digital signatures using the DigitalSignatureUtil class. + // 1 - Load from a document from a local file system filename: + DigitalSignatureCollection digitalSignatures = + DigitalSignatureUtil.loadSignatures(getMyDir() + "Digitally signed.docx"); + + // If this collection is nonempty, then we can verify that the document is digitally signed. + Assert.assertEquals(1, digitalSignatures.getCount()); + + // 2 - Load from a document from a FileStream: + InputStream stream = new FileInputStream(getMyDir() + "Digitally signed.docx"); + try { + digitalSignatures = DigitalSignatureUtil.loadSignatures(stream); + Assert.assertEquals(1, digitalSignatures.getCount()); + } finally { + if (stream != null) stream.close(); + } + //ExEnd + } + + @Test + public void remove() throws Exception { + //ExStart + //ExFor:DigitalSignatureUtil + //ExFor:DigitalSignatureUtil.LoadSignatures(String) + //ExFor:DigitalSignatureUtil.RemoveAllSignatures(Stream, Stream) + //ExFor:DigitalSignatureUtil.RemoveAllSignatures(String, String) + //ExSummary:Shows how to remove digital signatures from a digitally signed document. + // There are two ways of using the DigitalSignatureUtil class to remove digital signatures + // from a signed document by saving an unsigned copy of it somewhere else in the local file system. + // 1 - Determine the locations of both the signed document and the unsigned copy by filename strings: + DigitalSignatureUtil.removeAllSignatures(getMyDir() + "Digitally signed.docx", + getArtifactsDir() + "DigitalSignatureUtil.LoadAndRemove.FromString.docx"); + + // 2 - Determine the locations of both the signed document and the unsigned copy by file streams: + InputStream streamIn = new FileInputStream(getMyDir() + "Digitally signed.docx"); + try { + OutputStream streamOut = new FileOutputStream(getArtifactsDir() + "DigitalSignatureUtil.LoadAndRemove.FromStream.docx"); + try { + DigitalSignatureUtil.removeAllSignatures(streamIn, streamOut); + } finally { + if (streamOut != null) streamOut.close(); + } + } finally { + if (streamIn != null) streamIn.close(); + } + + // Verify that both our output documents have no digital signatures. + Assert.assertEquals(DigitalSignatureUtil.loadSignatures(getArtifactsDir() + "DigitalSignatureUtil.LoadAndRemove.FromString.docx").getCount(), 0); + Assert.assertEquals(DigitalSignatureUtil.loadSignatures(getArtifactsDir() + "DigitalSignatureUtil.LoadAndRemove.FromStream.docx").getCount(), 0); + //ExEnd + } + + @Test + public void removeSignatures() throws Exception + { + DigitalSignatureUtil.removeAllSignatures(getMyDir() + "Digitally signed.odt", + getArtifactsDir() + "DigitalSignatureUtil.RemoveSignatures.odt"); + + Assert.assertEquals(DigitalSignatureUtil.loadSignatures(getArtifactsDir() + "DigitalSignatureUtil.RemoveSignatures.odt").getCount(), 0); + } + + @Test(description = "WORDSNET-16868, WORDSJAVA-2406", enabled = false) + public void signDocument() throws Exception { + //ExStart + //ExFor:CertificateHolder + //ExFor:CertificateHolder.Create(String, String) + //ExFor:DigitalSignatureUtil.Sign(Stream, Stream, CertificateHolder, SignOptions) + //ExFor:DigitalSignatures.SignOptions + //ExFor:SignOptions.Comments + //ExFor:SignOptions.SignTime + //ExSummary:Shows how to digitally sign documents. + // Create an X.509 certificate from a PKCS#12 store, which should contain a private key. + CertificateHolder certificateHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + + // Create a comment and date which will be applied with our new digital signature. + SignOptions signOptions = new SignOptions(); + { + signOptions.setComments("My comment"); + signOptions.setSignTime(new Date()); + } + + // Take an unsigned document from the local file system via a file stream, + // then create a signed copy of it determined by the filename of the output file stream. + InputStream streamIn = new FileInputStream(getMyDir() + "Document.docx"); + try { + OutputStream streamOut = new FileOutputStream(getArtifactsDir() + "DigitalSignatureUtil.SignDocument.docx"); + try { + DigitalSignatureUtil.sign(streamIn, streamOut, certificateHolder, signOptions); + } finally { + if (streamOut != null) streamOut.close(); + } + } finally { + if (streamIn != null) streamIn.close(); + } + //ExEnd + + InputStream stream = new FileInputStream(getArtifactsDir() + "DigitalSignatureUtil.SignDocument.docx"); + try { + DigitalSignatureCollection digitalSignatures = DigitalSignatureUtil.loadSignatures(stream); + Assert.assertEquals(1, digitalSignatures.getCount()); + + DigitalSignature signature = digitalSignatures.get(0); + + Assert.assertTrue(signature.isValid()); + Assert.assertEquals(DigitalSignatureType.XML_DSIG, signature.getSignatureType()); + Assert.assertEquals(signOptions.getSignTime().toString(), signature.getSignTime().toString()); + Assert.assertEquals("My comment", signature.getComments()); + } finally { + if (stream != null) stream.close(); + } + } + + @Test(description = "WORDSNET-16868") + public void decryptionPassword() throws Exception { + //ExStart + //ExFor:CertificateHolder + //ExFor:SignOptions.DecryptionPassword + //ExFor:LoadOptions.Password + //ExSummary:Shows how to sign encrypted document file. + // Create an X.509 certificate from a PKCS#12 store, which should contain a private key. + CertificateHolder certificateHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + + // Create a comment, date, and decryption password which will be applied with our new digital signature. + SignOptions signOptions = new SignOptions(); + { + signOptions.setComments("Comment"); + signOptions.setSignTime(new Date()); + signOptions.setDecryptionPassword("docPassword"); + } + + // Set a local system filename for the unsigned input document, and an output filename for its new digitally signed copy. + String inputFileName = getMyDir() + "Encrypted.docx"; + String outputFileName = getArtifactsDir() + "DigitalSignatureUtil.DecryptionPassword.docx"; + + DigitalSignatureUtil.sign(inputFileName, outputFileName, certificateHolder, signOptions); + //ExEnd + + // Open encrypted document from a file. + LoadOptions loadOptions = new LoadOptions("docPassword"); + Assert.assertEquals(signOptions.getDecryptionPassword(), loadOptions.getPassword()); + + // Check that encrypted document was successfully signed. + Document signedDoc = new Document(outputFileName, loadOptions); + DigitalSignatureCollection signatures = signedDoc.getDigitalSignatures(); + + Assert.assertEquals(1, signatures.getCount()); + Assert.assertTrue(signatures.isValid()); + } + + @Test(description = "WORDSNET-13036, WORDSNET-16868") + public void signDocumentObfuscationBug() throws Exception { + CertificateHolder ch = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + + Document doc = new Document(getMyDir() + "Structured document tags.docx"); + String outputFileName = getArtifactsDir() + "DigitalSignatureUtil.SignDocumentObfuscationBug.doc"; + + SignOptions signOptions = new SignOptions(); + signOptions.setComments("Comment"); + signOptions.setSignTime(new Date()); + + DigitalSignatureUtil.sign(doc.getOriginalFileName(), outputFileName, ch, signOptions); + } + + @Test(description = "WORDSNET-16868") + public void incorrectDecryptionPassword() throws Exception { + CertificateHolder certificateHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + + Document doc = new Document(getMyDir() + "Encrypted.docx", new LoadOptions("docPassword")); + String outputFileName = getArtifactsDir() + "DigitalSignatureUtil.IncorrectDecryptionPassword.docx"; + + SignOptions signOptions = new SignOptions(); + { + signOptions.setComments("Comment"); + signOptions.setSignTime(new Date()); + signOptions.setDecryptionPassword("docPassword1"); + } + + Assert.assertThrows(IncorrectPasswordException.class, () -> DigitalSignatureUtil.sign(doc.getOriginalFileName(), outputFileName, certificateHolder, signOptions)); + } + + @Test + public void noArgumentsForSing() { + SignOptions signOptions = new SignOptions(); + + signOptions.setComments(""); + signOptions.setSignTime(new Date()); + signOptions.setDecryptionPassword(""); + + Assert.assertThrows(IllegalArgumentException.class, () -> DigitalSignatureUtil.sign("", "", null, signOptions)); + } + + @Test + public void noCertificateForSign() throws Exception { + Document doc = new Document(getMyDir() + "Digitally signed.docx"); + + SignOptions signOptions = new SignOptions(); + signOptions.setComments("Comment"); + signOptions.setSignTime(new Date()); + signOptions.setDecryptionPassword("docPassword"); + + Assert.assertThrows(NullPointerException.class, () -> DigitalSignatureUtil.sign(doc.getOriginalFileName(), + getArtifactsDir() + "DigitalSignatureUtil.NoCertificateForSign.docx", null, signOptions)); + } + + @Test + public void xmlDsig() throws Exception + { + //ExStart:XmlDsig + //GistId:6280fd6c1c1854468bea095ec2af902b + //ExFor:SignOptions.XmlDsigLevel + //ExFor:XmlDsigLevel + //ExSummary:Shows how to sign document based on XML-DSig standard. + CertificateHolder certificateHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + SignOptions signOptions = new SignOptions(); { signOptions.setXmlDsigLevel(XmlDsigLevel.X_AD_ES_EPES); } + + String inputFileName = getMyDir() + "Document.docx"; + String outputFileName = getArtifactsDir() + "DigitalSignatureUtil.XmlDsig.docx"; + DigitalSignatureUtil.sign(inputFileName, outputFileName, certificateHolder, signOptions); + //ExEnd:XmlDsig + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExDocSaveOptions.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExDocSaveOptions.java new file mode 100644 index 00000000..b724f9cd --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExDocSaveOptions.java @@ -0,0 +1,200 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.io.File; +import java.util.Calendar; +import java.util.Date; + +@Test +public class ExDocSaveOptions extends ApiExampleBase { + @Test + public void saveAsDoc() throws Exception { + //ExStart + //ExFor:DocSaveOptions + //ExFor:DocSaveOptions.#ctor + //ExFor:DocSaveOptions.#ctor(SaveFormat) + //ExFor:DocSaveOptions.Password + //ExFor:DocSaveOptions.SaveFormat + //ExFor:DocSaveOptions.SaveRoutingSlip + //ExFor:IncorrectPasswordException + //ExSummary:Shows how to set save options for older Microsoft Word formats. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.write("Hello world!"); + + DocSaveOptions options = new DocSaveOptions(SaveFormat.DOC); + + // Set a password which will protect the loading of the document by Microsoft Word or Aspose.Words. + // Note that this does not encrypt the contents of the document in any way. + options.setPassword("MyPassword"); + + // If the document contains a routing slip, we can preserve it while saving by setting this flag to true. + options.setSaveRoutingSlip(true); + + doc.save(getArtifactsDir() + "DocSaveOptions.SaveAsDoc.doc", options); + + // To be able to load the document, + // we will need to apply the password we specified in the DocSaveOptions object in a LoadOptions object. + Assert.assertThrows(IncorrectPasswordException.class, () -> new Document(getArtifactsDir() + "DocSaveOptions.SaveAsDoc.doc")); + + LoadOptions loadOptions = new LoadOptions("MyPassword"); + doc = new Document(getArtifactsDir() + "DocSaveOptions.SaveAsDoc.doc", loadOptions); + + Assert.assertEquals("Hello world!", doc.getText().trim()); + //ExEnd + } + + @Test + public void tempFolder() throws Exception { + //ExStart + //ExFor:SaveOptions.TempFolder + //ExSummary:Shows how to use the hard drive instead of memory when saving a document. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // When we save a document, various elements are temporarily stored in memory as the save operation is taking place. + // We can use this option to use a temporary folder in the local file system instead, + // which will reduce our application's memory overhead. + DocSaveOptions options = new DocSaveOptions(); + options.setTempFolder(getArtifactsDir() + "TempFiles"); + + // The specified temporary folder must exist in the local file system before the save operation. + new File(options.getTempFolder()).mkdir(); + + doc.save(getArtifactsDir() + "DocSaveOptions.TempFolder.doc", options); + + // The folder will persist with no residual contents from the load operation. + Assert.assertEquals(new File(options.getTempFolder()).listFiles().length, 0); + //ExEnd + } + + @Test + public void pictureBullets() throws Exception { + //ExStart + //ExFor:DocSaveOptions.SavePictureBullet + //ExSummary:Shows how to omit PictureBullet data from the document when saving. + Document doc = new Document(getMyDir() + "Image bullet points.docx"); + Assert.assertNotNull(doc.getLists().get(0).getListLevels().get(0).getImageData()); //ExSkip + + // Some word processors, such as Microsoft Word 97, are incompatible with PictureBullet data. + // By setting a flag in the SaveOptions object, + // we can convert all image bullet points to ordinary bullet points while saving. + DocSaveOptions saveOptions = new DocSaveOptions(SaveFormat.DOC); + saveOptions.setSavePictureBullet(false); + + doc.save(getArtifactsDir() + "DocSaveOptions.PictureBullets.doc", saveOptions); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocSaveOptions.PictureBullets.doc"); + + Assert.assertNull(doc.getLists().get(0).getListLevels().get(0).getImageData()); + } + + @Test(dataProvider = "updateLastPrintedPropertyDataProvider") + public void updateLastPrintedProperty(boolean isUpdateLastPrintedProperty) throws Exception { + //ExStart + //ExFor:SaveOptions.UpdateLastPrintedProperty + //ExSummary:Shows how to update a document's "Last printed" property when saving. + Document doc = new Document(); + + Calendar calendar = Calendar.getInstance(); + calendar.set(2019, 11, 20); + doc.getBuiltInDocumentProperties().setLastPrinted(calendar.getTime()); + + // This flag determines whether the last printed date, which is a built-in property, is updated. + // If so, then the date of the document's most recent save operation + // with this SaveOptions object passed as a parameter is used as the print date. + DocSaveOptions saveOptions = new DocSaveOptions(); + saveOptions.setUpdateLastPrintedProperty(isUpdateLastPrintedProperty); + + // In Microsoft Word 2003, this property can be found via File -> Properties -> Statistics -> Printed. + // It can also be displayed in the document's body by using a PRINTDATE field. + doc.save(getArtifactsDir() + "DocSaveOptions.UpdateLastPrintedProperty.doc", saveOptions); + //ExEnd + } + + @DataProvider(name = "updateLastPrintedPropertyDataProvider") + public static Object[][] updateLastPrintedPropertyDataProvider() { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test (dataProvider = "updateCreatedTimePropertyDataProvider") + public void updateCreatedTimeProperty(boolean isUpdateCreatedTimeProperty) throws Exception + { + //ExStart + //ExFor:SaveOptions.UpdateCreatedTimeProperty + //ExSummary:Shows how to update a document's "CreatedTime" property when saving. + Document doc = new Document(); + + Calendar calendar = Calendar.getInstance(); + calendar.set(2019, 11, 20); + doc.getBuiltInDocumentProperties().setCreatedTime(calendar.getTime()); + + // This flag determines whether the created time, which is a built-in property, is updated. + // If so, then the date of the document's most recent save operation + // with this SaveOptions object passed as a parameter is used as the created time. + DocSaveOptions saveOptions = new DocSaveOptions(); + saveOptions.setUpdateCreatedTimeProperty(isUpdateCreatedTimeProperty); + + doc.save(getArtifactsDir() + "DocSaveOptions.UpdateCreatedTimeProperty.docx", saveOptions); + //ExEnd + } + + @DataProvider(name = "updateCreatedTimePropertyDataProvider") + public static Object[][] updateCreatedTimePropertyDataProvider() { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test(dataProvider = "alwaysCompressMetafilesDataProvider") + public void alwaysCompressMetafiles(boolean compressAllMetafiles) throws Exception { + //ExStart + //ExFor:DocSaveOptions.AlwaysCompressMetafiles + //ExSummary:Shows how to change metafiles compression in a document while saving. + // Open a document that contains a Microsoft Equation 3.0 formula. + Document doc = new Document(getMyDir() + "Microsoft equation object.docx"); + + // When we save a document, smaller metafiles are not compressed for performance reasons. + // We can set a flag in a SaveOptions object to compress every metafile when saving. + // Some editors such as LibreOffice cannot read uncompressed metafiles. + DocSaveOptions saveOptions = new DocSaveOptions(); + saveOptions.setAlwaysCompressMetafiles(compressAllMetafiles); + + doc.save(getArtifactsDir() + "DocSaveOptions.AlwaysCompressMetafiles.docx", saveOptions); + //ExEnd + + long testedFileLength = new File(getArtifactsDir() + "DocSaveOptions.AlwaysCompressMetafiles.docx").length(); + + if (compressAllMetafiles) + Assert.assertTrue(testedFileLength < 13315); + else + Assert.assertTrue(testedFileLength <= 30000); + } + + @DataProvider(name = "alwaysCompressMetafilesDataProvider") + public static Object[][] alwaysCompressMetafilesDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExDocument.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExDocument.java new file mode 100644 index 00000000..eb8cc180 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExDocument.java @@ -0,0 +1,2665 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.pdf.TextAbsorber; +import com.aspose.words.Font; +import com.aspose.words.List; +import com.aspose.words.Shape; +import com.aspose.words.*; +import com.aspose.words.shaping.harfbuzz.HarfBuzzTextShaperFactory; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.io.*; +import java.net.URL; +import java.net.URLConnection; +import java.nio.file.Files; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Base64; +import java.util.Date; +import java.util.Iterator; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@Test +public class ExDocument extends ApiExampleBase +{ + @Test + public void createSimpleDocument() throws Exception + { + //ExStart:CreateSimpleDocument + //GistId:6d898be16b796fcf7448ad3bfe18e51c + //ExFor:DocumentBase.Document + //ExFor:Document.#ctor() + //ExSummary:Shows how to create simple document. + Document doc = new Document(); + + // New Document objects by default come with the minimal set of nodes + // required to begin adding content such as text and shapes: a Section, a Body, and a Paragraph. + doc.appendChild(new Section(doc)) + .appendChild(new Body(doc)) + .appendChild(new Paragraph(doc)) + .appendChild(new Run(doc, "Hello world!")); + //ExEnd:CreateSimpleDocument + } + + @Test + public void constructor() throws Exception { + //ExStart + //ExFor:Document.#ctor() + //ExFor:Document.#ctor(String,LoadOptions) + //ExSummary:Shows how to create and load documents. + // There are two ways of creating a Document object using Aspose.Words. + // 1 - Create a blank document: + Document doc = new Document(); + + // New Document objects by default come with the minimal set of nodes + // required to begin adding content such as text and shapes: a Section, a Body, and a Paragraph. + doc.getFirstSection().getBody().getFirstParagraph().appendChild(new Run(doc, "Hello world!")); + + // 2 - Load a document that exists in the local file system: + doc = new Document(getMyDir() + "Document.docx"); + + // Loaded documents will have contents that we can access and edit. + Assert.assertEquals("Hello World!", doc.getFirstSection().getBody().getFirstParagraph().getText().trim()); + + // Some operations that need to occur during loading, such as using a password to decrypt a document, + // can be done by passing a LoadOptions object when loading the document. + doc = new Document(getMyDir() + "Encrypted.docx", new LoadOptions("docPassword")); + + Assert.assertEquals("Test encrypted document.", doc.getFirstSection().getBody().getFirstParagraph().getText().trim()); + //ExEnd + } + + @Test + public void loadFromStream() throws Exception { + //ExStart + //ExFor:Document.#ctor(Stream) + //ExSummary:Shows how to load a document using a stream. + InputStream stream = new FileInputStream(getMyDir() + "Document.docx"); + try { + Document doc = new Document(stream); + Assert.assertEquals("Hello World!", doc.getFirstSection().getBody().getText().trim()); + } finally { + if (stream != null) stream.close(); + } + //ExEnd + } + + @Test + public void loadFromWeb() throws Exception { + //ExStart + //ExFor:Document.#ctor(Stream) + //ExSummary:Shows how to retrieve a document from a URL and saves it to disk in a different format. + // This is the URL address pointing to where to find the document + URL url = new URL("https://filesamples.com/samples/document/docx/sample3.docx"); + + // The easiest way to load our document from the internet is make use of the URLConnection class + URLConnection webClient = url.openConnection(); + webClient.addRequestProperty("User-Agent", "Mozilla"); + webClient.setReadTimeout(5000); + webClient.setConnectTimeout(5000); + + // Download the bytes from the location referenced by the URL + InputStream inputStream = webClient.getInputStream(); + + // Convert the input stream to a byte array + int pos; + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + while ((pos = inputStream.read()) != -1) bos.write(pos); + + byte[] dataBytes = bos.toByteArray(); + Assert.assertNotEquals(dataBytes, null); //ExSkip + + // Wrap the bytes representing the document in memory into a stream object + ByteArrayInputStream byteStream = new ByteArrayInputStream(dataBytes); + + // Load this memory stream into a new Aspose.Words Document + // The file format of the passed data is inferred from the content of the bytes itself + // You can load any document format supported by Aspose.Words in the same way + Document doc = new Document(byteStream); + Assert.assertTrue(doc.getText().contains("There are eight section headings in this document")); //ExSkip + + // Convert the document to any format supported by Aspose.Words and save + doc.save(getArtifactsDir() + "Document.OpenDocumentFromWeb.docx"); + //ExEnd + } + + @Test + public void convertToPdf() throws Exception { + //ExStart + //ExFor:Document.#ctor(String) + //ExFor:Document.Save(String) + //ExSummary:Shows how to open a document and convert it to .PDF. + Document doc = new Document(getMyDir() + "Document.docx"); + + doc.save(getArtifactsDir() + "Document.ConvertToPdf.pdf"); + //ExEnd + } + + @Test(groups = "IgnoreOnJenkins") + public void openType() throws Exception { + //ExStart + //ExFor:LayoutOptions.TextShaperFactory + //ExSummary:Shows how to support OpenType features using the HarfBuzz text shaping engine. + Document doc = new Document(getMyDir() + "OpenType text shaping.docx"); + + // Aspose.Words can use externally provided text shaper objects, + // which represent fonts and compute shaping information for text. + // A text shaper factory is necessary for documents that use multiple fonts. + // When the text shaper factory set, the layout uses OpenType features. + // An Instance property returns a static BasicTextShaperCache object wrapping HarfBuzzTextShaperFactory. + doc.getLayoutOptions().setTextShaperFactory(HarfBuzzTextShaperFactory.getInstance()); + + // Currently, text shaping is performing when exporting to PDF or XPS formats. + doc.save(getArtifactsDir() + "Document.OpenType.pdf"); + //ExEnd + } + + @Test + public void detectMobiDocumentFormat() throws Exception + { + FileFormatInfo info = FileFormatUtil.detectFileFormat(getMyDir() + "Document.mobi"); + Assert.assertEquals(info.getLoadFormat(), LoadFormat.MOBI); + } + + @Test + public void detectPdfDocumentFormat() throws Exception { + FileFormatInfo info = FileFormatUtil.detectFileFormat(getMyDir() + "Pdf Document.pdf"); + Assert.assertEquals(info.getLoadFormat(), LoadFormat.PDF); + } + + @Test + public void openFromStreamWithBaseUri() throws Exception { + //ExStart + //ExFor:Document.#ctor(Stream,LoadOptions) + //ExFor:LoadOptions.#ctor + //ExFor:LoadOptions.BaseUri + //ExFor:ShapeBase.IsImage + //ExSummary:Shows how to open an HTML document with images from a stream using a base URI. + InputStream stream = new FileInputStream(getMyDir() + "Document.html"); + try /*JAVA: was using*/ { + // Pass the URI of the base folder while loading it + // so that any images with relative URIs in the HTML document can be found. + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setBaseUri(getImageDir()); + + Document doc = new Document(stream, loadOptions); + + // Verify that the first shape of the document contains a valid image. + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertTrue(shape.isImage()); + Assert.assertNotNull(shape.getImageData().getImageBytes()); + Assert.assertEquals(32.0, ConvertUtil.pointToPixel(shape.getWidth()), 0.01); + Assert.assertEquals(32.0, ConvertUtil.pointToPixel(shape.getHeight()), 0.01); + } finally { + if (stream != null) stream.close(); + } + //ExEnd + } + + @Test(enabled = false, description = "Need to rework") + public void insertHtmlFromWebPage() throws Exception { + //ExStart + //ExFor:Document.#ctor(Stream, LoadOptions) + //ExFor:LoadOptions.#ctor(LoadFormat, String, String) + //ExFor:LoadFormat + //ExSummary:Shows how to insert the HTML contents from a web page into a new document. + URL url = new URL("https://www.aspose.com"); + + // The easiest way to load our document from the internet is make use of the URLConnection class. + URLConnection webClient = url.openConnection(); + + // Download the bytes from the location referenced by the URL. + InputStream inputStream = webClient.getInputStream(); + + // Convert the input stream to a byte array. + int pos; + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + while ((pos = inputStream.read()) != -1) bos.write(pos); + + byte[] dataBytes = bos.toByteArray(); + + // Wrap the bytes representing the document in memory into a stream object. + ByteArrayInputStream byteStream = new ByteArrayInputStream(dataBytes); + + // The baseUri property should be set to ensure any relative img paths are retrieved correctly. + LoadOptions options = new LoadOptions(LoadFormat.HTML, "", url.getPath()); + + // Load the HTML document from stream and pass the LoadOptions object. + Document doc = new Document(byteStream, options); + + doc.save(getArtifactsDir() + "Document.InsertHtmlFromWebPage.docx"); + //ExEnd + + TestUtil.verifyWebResponseStatusCode(200, url); + } + + @Test + public void loadEncrypted() throws Exception { + //ExStart + //ExFor:Document.#ctor(Stream,LoadOptions) + //ExFor:Document.#ctor(String,LoadOptions) + //ExFor:LoadOptions + //ExFor:LoadOptions.#ctor(String) + //ExSummary:Shows how to load an encrypted Microsoft Word document. + Document doc; + + // Aspose.Words throw an exception if we try to open an encrypted document without its password. + Assert.assertThrows(IncorrectPasswordException.class, () -> new Document(getMyDir() + "Encrypted.docx")); + + // When loading such a document, the password is passed to the document's constructor using a LoadOptions object. + LoadOptions options = new LoadOptions("docPassword"); + + // There are two ways of loading an encrypted document with a LoadOptions object. + // 1 - Load the document from the local file system by filename: + doc = new Document(getMyDir() + "Encrypted.docx", options); + Assert.assertEquals("Test encrypted document.", doc.getText().trim()); //ExSkip + + // 2 - Load the document from a stream: + InputStream stream = new FileInputStream(getMyDir() + "Encrypted.docx"); + try { + doc = new Document(stream, options); + Assert.assertEquals("Test encrypted document.", doc.getText().trim()); //ExSkip + } finally { + if (stream != null) stream.close(); + } + //ExEnd + } + + @Test + public void notSupportedWarning() throws Exception + { + //ExStart + //ExFor:WarningInfoCollection.Count + //ExFor:WarningInfoCollection.Item(Int32) + //ExSummary:Shows how to get warnings about unsupported formats. + WarningInfoCollection warings = new WarningInfoCollection(); + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setWarningCallback(warings); + Document doc = new Document(getMyDir() + "FB2 document.fb2", loadOptions); + + Assert.assertEquals("The original file load format is FB2, which is not supported by Aspose.Words. The file is loaded as an XML document.", warings.get(0).getDescription()); + //ExEnd + } + + @Test + public void tempFolder() throws Exception { + //ExStart + //ExFor:LoadOptions.TempFolder + //ExSummary:Shows how to load a document using temporary files. + // Note that such an approach can reduce memory usage but degrades speed. + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setTempFolder("C:\\TempFolder\\"); + + // Ensure that the directory exists and load. + new File(loadOptions.getTempFolder()).mkdir(); + + Document doc = new Document(getMyDir() + "Document.docx", loadOptions); + //ExEnd + } + + @Test + public void convertToHtml() throws Exception { + //ExStart + //ExFor:Document.Save(String,SaveFormat) + //ExFor:SaveFormat + //ExSummary:Shows how to convert from DOCX to HTML format. + Document doc = new Document(getMyDir() + "Document.docx"); + doc.save(getArtifactsDir() + "Document.ConvertToHtml.html", SaveFormat.HTML); + //ExEnd + } + + @Test + public void convertToMhtml() throws Exception { + Document doc = new Document(getMyDir() + "Document.docx"); + doc.save(getArtifactsDir() + "Document.ConvertToMhtml.mht"); + } + + @Test + public void convertToTxt() throws Exception { + Document doc = new Document(getMyDir() + "Document.docx"); + doc.save(getArtifactsDir() + "Document.ConvertToTxt.txt"); + } + + @Test + public void convertToEpub() throws Exception { + Document doc = new Document(getMyDir() + "Rendering.docx"); + doc.save(getArtifactsDir() + "Document.ConvertToEpub.epub"); + } + + @Test + public void saveToStream() throws Exception { + //ExStart + //ExFor:Document.Save(Stream,SaveFormat) + //ExSummary:Shows how to save a document to a stream. + Document doc = new Document(getMyDir() + "Document.docx"); + + ByteArrayOutputStream dstStream = new ByteArrayOutputStream(); + try { + doc.save(dstStream, SaveFormat.DOCX); + + byte[] dataBytes = dstStream.toByteArray(); + ByteArrayInputStream byteStream = new ByteArrayInputStream(dataBytes); + + // Verify that the stream contains the document. + Assert.assertEquals("Hello World!", new Document(byteStream).getFirstSection().getBody().getText().trim()); + } finally { + if (dstStream != null) dstStream.close(); + } + //ExEnd + } + + //ExStart + //ExFor:Range.Fields + //ExFor:INodeChangingCallback + //ExFor:INodeChangingCallback.NodeInserting + //ExFor:INodeChangingCallback.NodeInserted + //ExFor:INodeChangingCallback.NodeRemoving + //ExFor:INodeChangingCallback.NodeRemoved + //ExFor:NodeChangingArgs + //ExFor:NodeChangingArgs.Node + //ExFor:DocumentBase.NodeChangingCallback + //ExSummary:Shows how customize node changing with a callback. + @Test //ExSkip + public void fontChangeViaCallback() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Set the node changing callback to custom implementation, + // then add/remove nodes to get it to generate a log. + HandleNodeChangingFontChanger callback = new HandleNodeChangingFontChanger(); + doc.setNodeChangingCallback(callback); + + builder.writeln("Hello world!"); + builder.writeln("Hello again!"); + builder.insertField(" HYPERLINK \"https://www.google.com/\" "); + builder.insertShape(ShapeType.RECTANGLE, 300.0, 300.0); + + doc.getRange().getFields().get(0).remove(); + + System.out.println(callback.getLog()); + testFontChangeViaCallback(callback.getLog()); //ExSkip + } + + /// + /// Logs the date and time of each node insertion and removal. + /// Sets a custom font name/size for the text contents of Run nodes. + /// + public static class HandleNodeChangingFontChanger implements INodeChangingCallback { + public void nodeInserted(NodeChangingArgs args) { + mLog.append(MessageFormat.format("\tType:\t{0}", args.getNode().getNodeType())); + mLog.append(MessageFormat.format("\tHash:\t{0}", args.getNode().hashCode())); + + if (args.getNode().getNodeType() == NodeType.RUN) { + Font font = ((Run) args.getNode()).getFont(); + mLog.append(MessageFormat.format("\tFont:\tChanged from \"{0}\" {1}pt", font.getName(), font.getSize())); + + font.setSize(24.0); + font.setName("Arial"); + + mLog.append(MessageFormat.format(" to \"{0}\" {1}pt", font.getName(), font.getSize())); + mLog.append(MessageFormat.format("\tContents:\n\t\t\"{0}\"", args.getNode().getText())); + } + } + + public void nodeInserting(NodeChangingArgs args) { + mLog.append(MessageFormat.format("\n{0}\tNode insertion:", new Date())); + } + + public void nodeRemoved(NodeChangingArgs args) { + mLog.append(MessageFormat.format("\tType:\t{0}", args.getNode().getNodeType())); + mLog.append(MessageFormat.format("\tHash code:\t{0}", args.getNode().hashCode())); + } + + public void nodeRemoving(NodeChangingArgs args) { + mLog.append(MessageFormat.format("\n{0}\tNode removal:", new Date())); + } + + public String getLog() { + return mLog.toString(); + } + + private final StringBuilder mLog = new StringBuilder(); + } + //ExEnd + + private static void testFontChangeViaCallback(String log) { + Assert.assertEquals(10, getLogCount(log, "insertion")); + Assert.assertEquals(5, getLogCount(log, "removal")); + } + + private static int getLogCount(String log, String pattern) { + Matcher matcher = Pattern.compile(pattern).matcher(log); + + int count = 0; + while (matcher.find()) + count++; + + return count; + } + + @Test + public void appendDocument() throws Exception { + //ExStart + //ExFor:Document.AppendDocument(Document, ImportFormatMode) + //ExSummary:Shows how to append a document to the end of another document. + Document srcDoc = new Document(); + srcDoc.getFirstSection().getBody().appendParagraph("Source document text. "); + + Document dstDoc = new Document(); + dstDoc.getFirstSection().getBody().appendParagraph("Destination document text. "); + + // Append the source document to the destination document while preserving its formatting, + // then save the source document to the local file system. + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + Assert.assertEquals(2, dstDoc.getSections().getCount()); //ExSkip + + dstDoc.save(getArtifactsDir() + "Document.AppendDocument.docx"); + //ExEnd + + String outDocText = new Document(getArtifactsDir() + "Document.AppendDocument.docx").getText(); + + Assert.assertTrue(outDocText.startsWith(dstDoc.getText())); + Assert.assertTrue(outDocText.endsWith(srcDoc.getText())); + } + + @Test + // The file path used below does not point to an existing file. + public void appendDocumentFromAutomation() throws Exception { + Document doc = new Document(); + + // We should call this method to clear this document of any existing content. + doc.removeAllChildren(); + + final int RECORD_COUNT = 5; + for (int i = 1; i <= RECORD_COUNT; i++) { + Document srcDoc = new Document(); + + Assert.assertThrows(FileNotFoundException.class, () -> new Document("C:\\DetailsList.doc")); + + // Append the source document at the end of the destination document. + doc.appendDocument(srcDoc, ImportFormatMode.USE_DESTINATION_STYLES); + + // Automation required you to insert a new section break at this point, however, in Aspose.Words we + // do not need to do anything here as the appended document is imported as separate sections already + + // Unlink all headers/footers in this section from the previous section headers/footers + // if this is the second document or above being appended. + if (i > 1) { + int finalI = i; + Assert.assertThrows(NullPointerException.class, () -> doc.getSections().get(finalI).getHeadersFooters().linkToPrevious(false)); + } + } + } + + @Test (dataProvider = "importListDataProvider") + public void importList(boolean isKeepSourceNumbering) throws Exception + { + //ExStart + //ExFor:ImportFormatOptions.KeepSourceNumbering + //ExSummary:Shows how to import a document with numbered lists. + Document srcDoc = new Document(getMyDir() + "List source.docx"); + Document dstDoc = new Document(getMyDir() + "List destination.docx"); + + Assert.assertEquals(dstDoc.getLists().getCount(), 4); + + ImportFormatOptions options = new ImportFormatOptions(); + + // If there is a clash of list styles, apply the list format of the source document. + // Set the "KeepSourceNumbering" property to "false" to not import any list numbers into the destination document. + // Set the "KeepSourceNumbering" property to "true" import all clashing + // list style numbering with the same appearance that it had in the source document. + options.setKeepSourceNumbering(isKeepSourceNumbering); + + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING, options); + dstDoc.updateListLabels(); + + if (isKeepSourceNumbering) + Assert.assertEquals(dstDoc.getLists().getCount(), 5); + else + Assert.assertEquals(dstDoc.getLists().getCount(), 4); + //ExEnd + } + + @DataProvider(name = "importListDataProvider") + public static Object[][] importListDataProvider() { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test + public void keepSourceNumberingSameListIds() throws Exception + { + //ExStart + //ExFor:ImportFormatOptions.KeepSourceNumbering + //ExFor:NodeImporter.#ctor(DocumentBase, DocumentBase, ImportFormatMode, ImportFormatOptions) + //ExSummary:Shows how resolve a clash when importing documents that have lists with the same list definition identifier. + Document srcDoc = new Document(getMyDir() + "List with the same definition identifier - source.docx"); + Document dstDoc = new Document(getMyDir() + "List with the same definition identifier - destination.docx"); + + ImportFormatOptions importFormatOptions = new ImportFormatOptions(); + + // Set the "KeepSourceNumbering" property to "true" to apply a different list definition ID + // to identical styles as Aspose.Words imports them into destination documents. + importFormatOptions.setKeepSourceNumbering(true); + dstDoc.appendDocument(srcDoc, ImportFormatMode.USE_DESTINATION_STYLES, importFormatOptions); + + dstDoc.updateListLabels(); + //ExEnd + + String paraText = dstDoc.getSections().get(1).getBody().getLastParagraph().getText(); + + Assert.assertTrue(paraText.startsWith("13->13"), paraText); + Assert.assertEquals("1.", dstDoc.getSections().get(1).getBody().getLastParagraph().getListLabel().getLabelString()); + } + + @Test + public void mergePastedLists() throws Exception + { + //ExStart + //ExFor:ImportFormatOptions.MergePastedLists + //ExSummary:Shows how to merge lists from a documents. + Document srcDoc = new Document(getMyDir() + "List item.docx"); + Document dstDoc = new Document(getMyDir() + "List destination.docx"); + + ImportFormatOptions options = new ImportFormatOptions(); { options.setMergePastedLists(true); } + + // Set the "MergePastedLists" property to "true" pasted lists will be merged with surrounding lists. + dstDoc.appendDocument(srcDoc, ImportFormatMode.USE_DESTINATION_STYLES, options); + + dstDoc.save(getArtifactsDir() + "Document.MergePastedLists.docx"); + //ExEnd + } + + @Test + public void forceCopyStyles() throws Exception + { + //ExStart + //ExFor:ImportFormatOptions.ForceCopyStyles + //ExSummary:Shows how to copy source styles with unique names forcibly. + // Both documents contain MyStyle1 and MyStyle2, MyStyle3 exists only in a source document. + Document srcDoc = new Document(getMyDir() + "Styles source.docx"); + Document dstDoc = new Document(getMyDir() + "Styles destination.docx"); + + ImportFormatOptions options = new ImportFormatOptions(); { options.setForceCopyStyles(true); } + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING, options); + + ParagraphCollection paras = dstDoc.getSections().get(1).getBody().getParagraphs(); + + Assert.assertEquals(paras.get(0).getParagraphFormat().getStyle().getName(), "MyStyle1_0"); + Assert.assertEquals(paras.get(1).getParagraphFormat().getStyle().getName(), "MyStyle2_0"); + Assert.assertEquals(paras.get(2).getParagraphFormat().getStyle().getName(), "MyStyle3"); + //ExEnd + } + + @Test + public void adjustSentenceAndWordSpacing() throws Exception + { + //ExStart + //ExFor:ImportFormatOptions.AdjustSentenceAndWordSpacing + //ExSummary:Shows how to adjust sentence and word spacing automatically. + Document srcDoc = new Document(); + Document dstDoc = new Document(); + + DocumentBuilder builder = new DocumentBuilder(srcDoc); + builder.write("Dolor sit amet."); + + builder = new DocumentBuilder(dstDoc); + builder.write("Lorem ipsum."); + + ImportFormatOptions options = new ImportFormatOptions(); { options.setAdjustSentenceAndWordSpacing(true); } + builder.insertDocument(srcDoc, ImportFormatMode.USE_DESTINATION_STYLES, options); + + Assert.assertEquals("Lorem ipsum. Dolor sit amet.", dstDoc.getFirstSection().getBody().getFirstParagraph().getText().trim()); + //ExEnd + } + + @Test + public void validateIndividualDocumentSignatures() throws Exception { + //ExStart + //ExFor:CertificateHolder.Certificate + //ExFor:Document.DigitalSignatures + //ExFor:DigitalSignature + //ExFor:DigitalSignatureCollection + //ExFor:DigitalSignature.IsValid + //ExFor:DigitalSignature.Comments + //ExFor:DigitalSignature.SignTime + //ExFor:DigitalSignature.SignatureType + //ExSummary:Shows how to validate and display information about each signature in a document. + Document doc = new Document(getMyDir() + "Digitally signed.docx"); + + for (DigitalSignature signature : doc.getDigitalSignatures()) { + System.out.println("*** Signature Found ***"); + System.out.println("Is valid: " + signature.isValid()); + // This property is available in MS Word documents only + System.out.println("Reason for signing: " + signature.getComments()); + System.out.println("Signature type: " + signature.getSignatureType()); + System.out.println("Time of signing: " + signature.getSignTime()); + System.out.println("Subject name: " + signature.getSubjectName()); + System.out.println("Issuer name: " + signature.getIssuerName()); + System.out.println(); + } + //ExEnd + + Assert.assertEquals(1, doc.getDigitalSignatures().getCount()); + + DigitalSignature digitalSig = doc.getDigitalSignatures().get(0); + + Assert.assertTrue(digitalSig.isValid()); + Assert.assertEquals("Test Sign", digitalSig.getComments()); + Assert.assertEquals("XmlDsig", DigitalSignatureType.toString(digitalSig.getSignatureType())); + Assert.assertTrue(digitalSig.getSubjectName().contains("Aspose Pty Ltd")); + Assert.assertTrue(digitalSig.getIssuerName().contains("VeriSign")); + } + + @Test + public void digitalSignature() throws Exception { + //ExStart + //ExFor:DigitalSignature.CertificateHolder + //ExFor:DigitalSignature.IssuerName + //ExFor:DigitalSignature.SubjectName + //ExFor:DigitalSignatureCollection + //ExFor:DigitalSignatureCollection.IsValid + //ExFor:DigitalSignatureCollection.Count + //ExFor:DigitalSignatureCollection.Item(Int32) + //ExFor:DigitalSignatureUtil.Sign(Stream, Stream, CertificateHolder) + //ExFor:DigitalSignatureUtil.Sign(String, String, CertificateHolder) + //ExFor:DigitalSignatureType + //ExFor:Document.DigitalSignatures + //ExSummary:Shows how to sign documents with X.509 certificates. + // Verify that a document is not signed. + Assert.assertFalse(FileFormatUtil.detectFileFormat(getMyDir() + "Document.docx").hasDigitalSignature()); + + // Create a CertificateHolder object from a PKCS12 file, which we will use to sign the document. + CertificateHolder certificateHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw", null); + + SignOptions signOptions = new SignOptions(); + signOptions.setSignTime(new Date()); + + // There are two ways of saving a signed copy of a document to the local file system: + // 1 - Designate a document by a local system filename and save a signed copy at a location specified by another filename. + DigitalSignatureUtil.sign(getMyDir() + "Document.docx", getArtifactsDir() + "Document.DigitalSignature.docx", + certificateHolder, signOptions); + + Assert.assertTrue(FileFormatUtil.detectFileFormat(getArtifactsDir() + "Document.DigitalSignature.docx").hasDigitalSignature()); + + // 2 - Take a document from a stream, and save a signed copy to another stream. + InputStream inDoc = new FileInputStream(getMyDir() + "Document.docx"); + try { + OutputStream outDoc = new FileOutputStream(getArtifactsDir() + "Document.DigitalSignature.docx"); + try { + DigitalSignatureUtil.sign(inDoc, outDoc, certificateHolder); + } finally { + if (outDoc != null) outDoc.close(); + } + } finally { + if (inDoc != null) inDoc.close(); + } + + Assert.assertTrue(FileFormatUtil.detectFileFormat(getArtifactsDir() + "Document.DigitalSignature.docx").hasDigitalSignature()); + + // Please verify that all of the document's digital signatures are valid and check their details. + Document signedDoc = new Document(getArtifactsDir() + "Document.DigitalSignature.docx"); + DigitalSignatureCollection digitalSignatureCollection = signedDoc.getDigitalSignatures(); + + Assert.assertTrue(digitalSignatureCollection.isValid()); + Assert.assertEquals(1, digitalSignatureCollection.getCount()); + Assert.assertEquals(DigitalSignatureType.XML_DSIG, digitalSignatureCollection.get(0).getSignatureType()); + Assert.assertEquals("CN=Morzal.Me", signedDoc.getDigitalSignatures().get(0).getIssuerName()); + Assert.assertEquals("CN=Morzal.Me", signedDoc.getDigitalSignatures().get(0).getSubjectName()); + //ExEnd + } + + @Test + public void signatureValue() throws Exception + { + //ExStart + //ExFor:DigitalSignature.SignatureValue + //ExSummary:Shows how to get a digital signature value from a digitally signed document. + Document doc = new Document(getMyDir() + "Digitally signed.docx"); + + for (DigitalSignature digitalSignature : doc.getDigitalSignatures()) + { + String signatureValue = Base64.getEncoder().encodeToString(digitalSignature.getSignatureValue()); + Assert.assertEquals("K1cVLLg2kbJRAzT5WK+m++G8eEO+l7S+5ENdjMxxTXkFzGUfvwxREuJdSFj9AbD" + + "MhnGvDURv9KEhC25DDF1al8NRVR71TF3CjHVZXpYu7edQS5/yLw/k5CiFZzCp1+MmhOdYPcVO+Fm" + + "+9fKr2iNLeyYB+fgEeZHfTqTFM2WwAqo=", signatureValue); + } + //ExEnd + } + + @Test + public void appendAllDocumentsInFolder() throws Exception { + //ExStart + //ExFor:Document.AppendDocument(Document, ImportFormatMode) + //ExSummary:Shows how to append all the documents in a folder to the end of a template document. + Document dstDoc = new Document(); + + DocumentBuilder builder = new DocumentBuilder(dstDoc); + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + builder.writeln("Template Document"); + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.NORMAL); + builder.writeln("Some content here"); + Assert.assertEquals(5, dstDoc.getStyles().getCount()); //ExSkip + Assert.assertEquals(1, dstDoc.getSections().getCount()); //ExSkip + + // Append all unencrypted documents with the .doc extension + // from our local file system directory to the base document. + for (File fileName : new File(getMyDir()).listFiles((f, name) -> name.endsWith(".doc"))) { + FileFormatInfo info = FileFormatUtil.detectFileFormat(fileName.getPath()); + if (info.isEncrypted()) + continue; + + Document srcDoc = new Document(fileName.getPath()); + dstDoc.appendDocument(srcDoc, ImportFormatMode.USE_DESTINATION_STYLES); + } + + dstDoc.save(getArtifactsDir() + "Document.AppendAllDocumentsInFolder.doc"); + //ExEnd + + Assert.assertEquals(7, dstDoc.getStyles().getCount()); + Assert.assertEquals(10, dstDoc.getSections().getCount()); + } + + @Test + public void joinRunsWithSameFormatting() throws Exception { + //ExStart + //ExFor:Document.JoinRunsWithSameFormatting + //ExSummary:Shows how to join runs in a document to reduce unneeded runs. + // Open a document that contains adjacent runs of text with identical formatting, + // which commonly occurs if we edit the same paragraph multiple times in Microsoft Word. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // If any number of these runs are adjacent with identical formatting, + // then the document may be simplified. + Assert.assertEquals(317, doc.getChildNodes(NodeType.RUN, true).getCount()); + + // Combine such runs with this method and verify the number of run joins that will take place. + Assert.assertEquals(121, doc.joinRunsWithSameFormatting()); + + // The number of joins and the number of runs we have after the join + // should add up the number of runs we had initially. + Assert.assertEquals(196, doc.getChildNodes(NodeType.RUN, true).getCount()); + //ExEnd + } + + @Test + public void defaultTabStop() throws Exception { + //ExStart + //ExFor:Document.DefaultTabStop + //ExFor:ControlChar.Tab + //ExFor:ControlChar.TabChar + //ExSummary:Shows how to set a custom interval for tab stop positions. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Set tab stops to appear every 72 points (1 inch). + builder.getDocument().setDefaultTabStop(72.0); + + // Each tab character snaps the text after it to the next closest tab stop position. + builder.writeln("Hello" + ControlChar.TAB + "World!"); + builder.writeln("Hello" + ControlChar.TAB_CHAR + "World!"); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + Assert.assertEquals(72.0, doc.getDefaultTabStop()); + } + + @Test + public void cloneDocument() throws Exception { + //ExStart + //ExFor:Document.Clone + //ExSummary:Shows how to deep clone a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Hello world!"); + + // Cloning will produce a new document with the same contents as the original, + // but with a unique copy of each of the original document's nodes. + Document clone = doc.deepClone(); + + Assert.assertEquals(doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0).getText(), + clone.getFirstSection().getBody().getFirstParagraph().getRuns().get(0).getText()); + Assert.assertNotEquals(doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0).hashCode(), + clone.getFirstSection().getBody().getFirstParagraph().getRuns().get(0).hashCode()); + //ExEnd + } + + @Test + public void documentGetTextToString() throws Exception { + //ExStart + //ExFor:CompositeNode.GetText + //ExFor:Node.ToString(SaveFormat) + //ExSummary:Shows the difference between calling the GetText and ToString methods on a node. + Document doc = new Document(); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertField("MERGEFIELD Field"); + + // GetText will retrieve the visible text as well as field codes and special characters. + Assert.assertEquals("\u0013MERGEFIELD Field\u0014«Field»\u0015\f", doc.getText()); + + // ToString will give us the document's appearance if saved to a passed save format. + Assert.assertEquals("«Field»\r\n", doc.toString(SaveFormat.TEXT)); + //ExEnd + } + + @Test + public void documentByteArray() throws Exception { + Document doc = new Document(getMyDir() + "Document.docx"); + + ByteArrayOutputStream streamOut = new ByteArrayOutputStream(); + doc.save(streamOut, SaveFormat.DOCX); + + byte[] docBytes = streamOut.toByteArray(); + + ByteArrayInputStream streamIn = new ByteArrayInputStream(docBytes); + + Document loadDoc = new Document(streamIn); + Assert.assertEquals(doc.getText(), loadDoc.getText()); + } + + @Test + public void protectUnprotect() throws Exception { + //ExStart + //ExFor:Document.Protect(ProtectionType,String) + //ExFor:Document.ProtectionType + //ExFor:Document.Unprotect + //ExFor:Document.Unprotect(String) + //ExSummary:Shows how to protect and unprotect a document. + Document doc = new Document(); + doc.protect(ProtectionType.READ_ONLY, "password"); + + Assert.assertEquals(ProtectionType.READ_ONLY, doc.getProtectionType()); + + // If we open this document with Microsoft Word intending to edit it, + // we will need to apply the password to get through the protection. + doc.save(getArtifactsDir() + "Document.Protect.docx"); + + // Note that the protection only applies to Microsoft Word users opening our document. + // We have not encrypted the document in any way, and we do not need the password to open and edit it programmatically. + Document protectedDoc = new Document(getArtifactsDir() + "Document.Protect.docx"); + + Assert.assertEquals(ProtectionType.READ_ONLY, protectedDoc.getProtectionType()); + + DocumentBuilder builder = new DocumentBuilder(protectedDoc); + builder.writeln("Text added to a protected document."); + Assert.assertEquals("Text added to a protected document.", protectedDoc.getRange().getText().trim()); //ExSkip + + // There are two ways of removing protection from a document. + // 1 - With no password: + doc.unprotect(); + + Assert.assertEquals(ProtectionType.NO_PROTECTION, doc.getProtectionType()); + + doc.protect(ProtectionType.READ_ONLY, "NewPassword"); + + Assert.assertEquals(ProtectionType.READ_ONLY, doc.getProtectionType()); + + doc.unprotect("WrongPassword"); + + Assert.assertEquals(ProtectionType.READ_ONLY, doc.getProtectionType()); + + // 2 - With the correct password: + doc.unprotect("NewPassword"); + + Assert.assertEquals(ProtectionType.NO_PROTECTION, doc.getProtectionType()); + //ExEnd + } + + @Test + public void documentEnsureMinimum() throws Exception { + //ExStart + //ExFor:Document.EnsureMinimum + //ExSummary:Shows how to ensure that a document contains the minimal set of nodes required for editing its contents. + // A newly created document contains one child Section, which includes one child Body and one child Paragraph. + // We can edit the document body's contents by adding nodes such as Runs or inline Shapes to that paragraph. + Document doc = new Document(); + NodeCollection nodes = doc.getChildNodes(NodeType.ANY, true); + + Assert.assertEquals(NodeType.SECTION, nodes.get(0).getNodeType()); + Assert.assertEquals(doc, nodes.get(0).getParentNode()); + + Assert.assertEquals(NodeType.BODY, nodes.get(1).getNodeType()); + Assert.assertEquals(nodes.get(0), nodes.get(1).getParentNode()); + + Assert.assertEquals(NodeType.PARAGRAPH, nodes.get(2).getNodeType()); + Assert.assertEquals(nodes.get(1), nodes.get(2).getParentNode()); + + // This is the minimal set of nodes that we need to be able to edit the document. + // We will no longer be able to edit the document if we remove any of them. + doc.removeAllChildren(); + + Assert.assertEquals(0, doc.getChildNodes(NodeType.ANY, true).getCount()); + + // Call this method to make sure that the document has at least those three nodes so we can edit it again. + doc.ensureMinimum(); + + Assert.assertEquals(NodeType.SECTION, nodes.get(0).getNodeType()); + Assert.assertEquals(NodeType.BODY, nodes.get(1).getNodeType()); + Assert.assertEquals(NodeType.PARAGRAPH, nodes.get(2).getNodeType()); + + ((Paragraph) nodes.get(2)).getRuns().add(new Run(doc, "Hello world!")); + //ExEnd + + Assert.assertEquals("Hello world!", doc.getText().trim()); + } + + @Test + public void removeMacrosFromDocument() throws Exception { + //ExStart + //ExFor:Document.RemoveMacros + //ExSummary:Shows how to remove all macros from a document. + Document doc = new Document(getMyDir() + "Macro.docm"); + + Assert.assertTrue(doc.hasMacros()); + Assert.assertEquals("Project", doc.getVbaProject().getName()); + + // Remove the document's VBA project, along with all its macros. + doc.removeMacros(); + + Assert.assertFalse(doc.hasMacros()); + Assert.assertNull(doc.getVbaProject()); + //ExEnd + } + + @Test + public void getPageCount() throws Exception { + //ExStart + //ExFor:Document.PageCount + //ExSummary:Shows how to count the number of pages in the document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Page 1"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.write("Page 2"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.write("Page 3"); + + // Verify the expected page count of the document. + Assert.assertEquals(3, doc.getPageCount()); + + // Getting the PageCount property invoked the document's page layout to calculate the value. + // This operation will not need to be re-done when rendering the document to a fixed page save format, + // such as .pdf. So you can save some time, especially with more complex documents. + doc.save(getArtifactsDir() + "Document.GetPageCount.pdf"); + //ExEnd + } + + @Test + public void getUpdatedPageProperties() throws Exception { + //ExStart + //ExFor:Document.UpdateWordCount() + //ExFor:Document.UpdateWordCount(Boolean) + //ExFor:BuiltInDocumentProperties.Characters + //ExFor:BuiltInDocumentProperties.Words + //ExFor:BuiltInDocumentProperties.Paragraphs + //ExFor:BuiltInDocumentProperties.Lines + //ExSummary:Shows how to update all list labels in a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + builder.write("Ut enim ad minim veniam, " + + "quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."); + + // Aspose.Words does not track document metrics like these in real time. + Assert.assertEquals(0, doc.getBuiltInDocumentProperties().getCharacters()); + Assert.assertEquals(0, doc.getBuiltInDocumentProperties().getWords()); + Assert.assertEquals(1, doc.getBuiltInDocumentProperties().getParagraphs()); + Assert.assertEquals(1, doc.getBuiltInDocumentProperties().getLines()); + + // To get accurate values for three of these properties, we will need to update them manually. + doc.updateWordCount(); + + Assert.assertEquals(196, doc.getBuiltInDocumentProperties().getCharacters()); + Assert.assertEquals(36, doc.getBuiltInDocumentProperties().getWords()); + Assert.assertEquals(2, doc.getBuiltInDocumentProperties().getParagraphs()); + + // For the line count, we will need to call a specific overload of the updating method. + Assert.assertEquals(1, doc.getBuiltInDocumentProperties().getLines()); + + doc.updateWordCount(true); + + Assert.assertEquals(4, doc.getBuiltInDocumentProperties().getLines()); + //ExEnd + } + + @Test + public void tableStyleToDirectFormatting() throws Exception { + //ExStart + //ExFor:CompositeNode.GetChild + //ExFor:Document.ExpandTableStylesToDirectFormatting + //ExSummary:Shows how to apply the properties of a table's style directly to the table's elements. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + builder.write("Hello world!"); + builder.endTable(); + + TableStyle tableStyle = (TableStyle) doc.getStyles().add(StyleType.TABLE, "MyTableStyle1"); + tableStyle.setRowStripe(3); + tableStyle.setCellSpacing(5.0); + tableStyle.getShading().setBackgroundPatternColor(Color.WHITE); + tableStyle.getBorders().setColor(Color.BLUE); + tableStyle.getBorders().setLineStyle(LineStyle.DOT_DASH); + + table.setStyle(tableStyle); + + // This method concerns table style properties such as the ones we set above. + doc.expandTableStylesToDirectFormatting(); + + doc.save(getArtifactsDir() + "Document.TableStyleToDirectFormatting.docx"); + //ExEnd + + TestUtil.docPackageFileContainsString("", + getArtifactsDir() + "Document.TableStyleToDirectFormatting.docx", "word/document.xml"); + TestUtil.docPackageFileContainsString("", + getArtifactsDir() + "Document.TableStyleToDirectFormatting.docx", "word/document.xml"); + TestUtil.docPackageFileContainsString("", + getArtifactsDir() + "Document.TableStyleToDirectFormatting.docx", "word/document.xml"); + } + + @Test + public void getOriginalFileInfo() throws Exception { + //ExStart + //ExFor:Document.OriginalFileName + //ExFor:Document.OriginalLoadFormat + //ExSummary:Shows how to retrieve details of a document's load operation. + Document doc = new Document(getMyDir() + "Document.docx"); + + Assert.assertEquals(getMyDir() + "Document.docx", doc.getOriginalFileName()); + Assert.assertEquals(LoadFormat.DOCX, doc.getOriginalLoadFormat()); + //ExEnd + } + + @Test(description = "WORDSNET-16099") + public void footnoteColumns() throws Exception { + //ExStart + //ExFor:FootnoteOptions + //ExFor:FootnoteOptions.Columns + //ExSummary:Shows how to split the footnote section into a given number of columns. + Document doc = new Document(getMyDir() + "Footnotes and endnotes.docx"); + Assert.assertEquals(0, doc.getFootnoteOptions().getColumns()); //ExSkip + + doc.getFootnoteOptions().setColumns(2); + doc.save(getArtifactsDir() + "Document.FootnoteColumns.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Document.FootnoteColumns.docx"); + + Assert.assertEquals(2, doc.getFirstSection().getPageSetup().getFootnoteOptions().getColumns()); + } + + @Test + public void removeExternalSchemaReferences() throws Exception { + //ExStart + //ExFor:Document.RemoveExternalSchemaReferences + //ExSummary:Shows how to remove all external XML schema references from a document. + Document doc = new Document(getMyDir() + "External XML schema.docx"); + + doc.removeExternalSchemaReferences(); + //ExEnd + } + + @Test + public void updateThumbnail() throws Exception { + //ExStart + //ExFor:Document.UpdateThumbnail() + //ExFor:Document.UpdateThumbnail(ThumbnailGeneratingOptions) + //ExFor:ThumbnailGeneratingOptions + //ExFor:ThumbnailGeneratingOptions.GenerateFromFirstPage + //ExFor:ThumbnailGeneratingOptions.ThumbnailSize + //ExSummary:Shows how to update a document's thumbnail. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + builder.insertImage(getImageDir() + "Logo.jpg"); + + // There are two ways of setting a thumbnail image when saving a document to .epub. + // 1 - Use the document's first page: + doc.updateThumbnail(); + doc.save(getArtifactsDir() + "Document.UpdateThumbnail.FirstPage.epub"); + + // 2 - Use the first image found in the document: + ThumbnailGeneratingOptions options = new ThumbnailGeneratingOptions(); + Assert.assertEquals(new Dimension(600, 900), options.getThumbnailSize()); //ExSKip + Assert.assertTrue(options.getGenerateFromFirstPage()); //ExSkip + options.setThumbnailSize(new Dimension(400, 400)); + options.setGenerateFromFirstPage(false); + + doc.updateThumbnail(options); + doc.save(getArtifactsDir() + "Document.UpdateThumbnail.FirstImage.epub"); + //ExEnd + } + + @Test + public void hyphenationOptions() throws Exception { + //ExStart + //ExFor:Document.HyphenationOptions + //ExFor:HyphenationOptions + //ExFor:HyphenationOptions.AutoHyphenation + //ExFor:HyphenationOptions.ConsecutiveHyphenLimit + //ExFor:HyphenationOptions.HyphenationZone + //ExFor:HyphenationOptions.HyphenateCaps + //ExSummary:Shows how to configure automatic hyphenation. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setSize(24.0); + builder.writeln("Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + + doc.getHyphenationOptions().setAutoHyphenation(true); + doc.getHyphenationOptions().setConsecutiveHyphenLimit(2); + doc.getHyphenationOptions().setHyphenationZone(720); + doc.getHyphenationOptions().setHyphenateCaps(true); + + doc.save(getArtifactsDir() + "Document.HyphenationOptions.docx"); + //ExEnd + + Assert.assertEquals(true, doc.getHyphenationOptions().getAutoHyphenation()); + Assert.assertEquals(2, doc.getHyphenationOptions().getConsecutiveHyphenLimit()); + Assert.assertEquals(720, doc.getHyphenationOptions().getHyphenationZone()); + Assert.assertEquals(true, doc.getHyphenationOptions().getHyphenateCaps()); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "Document.HyphenationOptions.docx", + getGoldsDir() + "Document.HyphenationOptions Gold.docx")); + } + + @Test + public void hyphenationOptionsDefaultValues() throws Exception { + Document doc = new Document(); + doc = DocumentHelper.saveOpen(doc); + + Assert.assertEquals(false, doc.getHyphenationOptions().getAutoHyphenation()); + Assert.assertEquals(0, doc.getHyphenationOptions().getConsecutiveHyphenLimit()); + Assert.assertEquals(360, doc.getHyphenationOptions().getHyphenationZone()); // 0.25 inch + Assert.assertEquals(true, doc.getHyphenationOptions().getHyphenateCaps()); + } + + @Test + public void hyphenationOptionsExceptions() throws Exception { + Document doc = new Document(); + + doc.getHyphenationOptions().setConsecutiveHyphenLimit(0); + Assert.assertThrows(IllegalArgumentException.class, () -> doc.getHyphenationOptions().setHyphenationZone(0)); + + Assert.assertThrows(IllegalArgumentException.class, () -> doc.getHyphenationOptions().setConsecutiveHyphenLimit(-1)); + doc.getHyphenationOptions().setHyphenationZone(360); + } + + @Test + public void ooxmlComplianceVersion() throws Exception { + //ExStart + //ExFor:Document.Compliance + //ExSummary:Shows how to read a loaded document's Open Office XML compliance version. + // The compliance version varies between documents created by different versions of Microsoft Word. + Document doc = new Document(getMyDir() + "Document.doc"); + + Assert.assertEquals(doc.getCompliance(), OoxmlCompliance.ECMA_376_2006); + + doc = new Document(getMyDir() + "Document.docx"); + + Assert.assertEquals(doc.getCompliance(), OoxmlCompliance.ISO_29500_2008_TRANSITIONAL); + //ExEnd + } + + @Test(enabled = false, description = "WORDSNET-20342") + public void imageSaveOptions() throws Exception { + //ExStart + //ExFor:Document.Save(String, SaveOptions) + //ExFor:SaveOptions.UseAntiAliasing + //ExFor:SaveOptions.UseHighQualityRendering + //ExSummary:Shows how to improve the quality of a rendered document with SaveOptions. + Document doc = new Document(getMyDir() + "Rendering.docx"); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setSize(60.0); + builder.writeln("Some text."); + + SaveOptions options = new ImageSaveOptions(SaveFormat.JPEG); + Assert.assertFalse(options.getUseAntiAliasing()); //ExSkip + Assert.assertFalse(options.getUseHighQualityRendering()); //ExSkip + + doc.save(getArtifactsDir() + "Document.ImageSaveOptions.Default.jpg", options); + + options.setUseAntiAliasing(true); + options.setUseHighQualityRendering(true); + + doc.save(getArtifactsDir() + "Document.ImageSaveOptions.HighQuality.jpg", options); + //ExEnd + + TestUtil.verifyImage(794, 1122, getArtifactsDir() + "Document.ImageSaveOptions.Default.jpg"); + TestUtil.verifyImage(794, 1122, getArtifactsDir() + "Document.ImageSaveOptions.HighQuality.jpg"); + } + + @Test + public void cleanup() throws Exception { + //ExStart + //ExFor:Document.Cleanup + //ExSummary:Shows how to remove unused custom styles from a document. + Document doc = new Document(); + + doc.getStyles().add(StyleType.LIST, "MyListStyle1"); + doc.getStyles().add(StyleType.LIST, "MyListStyle2"); + doc.getStyles().add(StyleType.CHARACTER, "MyParagraphStyle1"); + doc.getStyles().add(StyleType.CHARACTER, "MyParagraphStyle2"); + + // Combined with the built-in styles, the document now has eight styles. + // A custom style counts as "used" while applied to some part of the document, + // which means that the four styles we added are currently unused. + Assert.assertEquals(8, doc.getStyles().getCount()); + + // Apply a custom character style, and then a custom list style. Doing so will mark the styles as "used". + DocumentBuilder builder = new DocumentBuilder(doc); + builder.getFont().setStyle(doc.getStyles().get("MyParagraphStyle1")); + builder.writeln("Hello world!"); + + List docList = doc.getLists().add(doc.getStyles().get("MyListStyle1")); + builder.getListFormat().setList(docList); + builder.writeln("Item 1"); + builder.writeln("Item 2"); + + doc.cleanup(); + + Assert.assertEquals(6, doc.getStyles().getCount()); + + // Removing every node that a custom style is applied to marks it as "unused" again. + // Run the Cleanup method again to remove them. + doc.getFirstSection().getBody().removeAllChildren(); + doc.cleanup(); + + Assert.assertEquals(4, doc.getStyles().getCount()); + //ExEnd + } + + @Test + public void automaticallyUpdateStyles() throws Exception { + //ExStart + //ExFor:Document.AutomaticallyUpdateStyles + //ExSummary:Shows how to attach a template to a document. + Document doc = new Document(); + + // Microsoft Word documents by default come with an attached template called "Normal.dotm". + // There is no default template for blank Aspose.Words documents. + Assert.assertEquals("", doc.getAttachedTemplate()); + + // Attach a template, then set the flag to apply style changes + // within the template to styles in our document. + doc.setAttachedTemplate(getMyDir() + "Business brochure.dotx"); + doc.setAutomaticallyUpdateStyles(true); + + doc.save(getArtifactsDir() + "Document.AutomaticallyUpdateStyles.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Document.AutomaticallyUpdateStyles.docx"); + + Assert.assertTrue(doc.getAutomaticallyUpdateStyles()); + Assert.assertEquals(getMyDir() + "Business brochure.dotx", doc.getAttachedTemplate()); + Assert.assertTrue(new File(doc.getAttachedTemplate()).exists()); + } + + @Test + public void defaultTemplate() throws Exception { + //ExStart + //ExFor:Document.AttachedTemplate + //ExFor:Document.AutomaticallyUpdateStyles + //ExFor:SaveOptions.CreateSaveOptions(String) + //ExFor:SaveOptions.DefaultTemplate + //ExSummary:Shows how to set a default template for documents that do not have attached templates. + Document doc = new Document(); + + // Enable automatic style updating, but do not attach a template document. + doc.setAutomaticallyUpdateStyles(true); + + Assert.assertEquals("", doc.getAttachedTemplate()); + + // Since there is no template document, the document had nowhere to track style changes. + // Use a SaveOptions object to automatically set a template + // if a document that we are saving does not have one. + SaveOptions options = SaveOptions.createSaveOptions("Document.DefaultTemplate.docx"); + options.setDefaultTemplate(getMyDir() + "Business brochure.dotx"); + + doc.save(getArtifactsDir() + "Document.DefaultTemplate.docx", options); + //ExEnd + + Assert.assertTrue(new File(options.getDefaultTemplate()).exists()); + } + + @Test + public void useSubstitutions() throws Exception + { + //ExStart + //ExFor:FindReplaceOptions.#ctor() + //ExFor:FindReplaceOptions.UseSubstitutions + //ExFor:FindReplaceOptions.LegacyMode + //ExSummary:Shows how to recognize and use substitutions within replacement patterns. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Jason gave money to Paul."); + + String regex = "([A-z]+) gave money to ([A-z]+)"; + + FindReplaceOptions options = new FindReplaceOptions(); + options.setUseSubstitutions(true); + + // Using legacy mode does not support many advanced features, so we need to set it to 'false'. + options.setLegacyMode(false); + + doc.getRange().replace(Pattern.compile(regex), "$2 took money from $1", options); + + Assert.assertEquals(doc.getText(), "Paul took money from Jason.\f"); + //ExEnd + } + + @Test + public void setInvalidateFieldTypes() throws Exception + { + //ExStart + //ExFor:Document.NormalizeFieldTypes + //ExFor:Range.NormalizeFieldTypes + //ExSummary:Shows how to get the keep a field's type up to date with its field code. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Field field = builder.insertField("DATE", null); + + // Aspose.Words automatically detects field types based on field codes. + Assert.assertEquals(FieldType.FIELD_DATE, field.getType()); + + // Manually change the raw text of the field, which determines the field code. + Run fieldText = (Run) doc.getFirstSection().getBody().getFirstParagraph().getChildNodes(NodeType.RUN, true).get(0); + Assert.assertEquals("DATE", fieldText.getText()); //ExSkip + fieldText.setText("PAGE"); + + // Changing the field code has changed this field to one of a different type, + // but the field's type properties still display the old type. + Assert.assertEquals("PAGE", field.getFieldCode()); + Assert.assertEquals(FieldType.FIELD_DATE, field.getType()); + Assert.assertEquals(FieldType.FIELD_DATE, field.getStart().getFieldType()); + Assert.assertEquals(FieldType.FIELD_DATE, field.getSeparator().getFieldType()); + Assert.assertEquals(FieldType.FIELD_DATE, field.getEnd().getFieldType()); + + // Update those properties with this method to display current value. + doc.normalizeFieldTypes(); + + Assert.assertEquals(FieldType.FIELD_PAGE, field.getType()); + Assert.assertEquals(FieldType.FIELD_PAGE, field.getStart().getFieldType()); + Assert.assertEquals(FieldType.FIELD_PAGE, field.getSeparator().getFieldType()); + Assert.assertEquals(FieldType.FIELD_PAGE, field.getEnd().getFieldType()); + //ExEnd + } + + @Test(dataProvider = "layoutOptionsHiddenTextDataProvider") + public void layoutOptionsHiddenText(boolean showHiddenText) throws Exception { + //ExStart + //ExFor:Document.LayoutOptions + //ExFor:LayoutOptions + //ExFor:LayoutOptions.ShowHiddenText + //ExSummary:Shows how to hide text in a rendered output document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + Assert.assertFalse(doc.getLayoutOptions().getShowHiddenText()); //ExSkip + + // Insert hidden text, then specify whether we wish to omit it from a rendered document. + builder.writeln("This text is not hidden."); + builder.getFont().setHidden(true); + builder.writeln("This text is hidden."); + + doc.getLayoutOptions().setShowHiddenText(showHiddenText); + + doc.save(getArtifactsDir() + "Document.LayoutOptionsHiddenText.pdf"); + //ExEnd + + com.aspose.pdf.Document pdfDoc = new com.aspose.pdf.Document(getArtifactsDir() + "Document.LayoutOptionsHiddenText.pdf"); + TextAbsorber textAbsorber = new TextAbsorber(); + textAbsorber.visit(pdfDoc); + + Assert.assertEquals(showHiddenText + ? MessageFormat.format("This text is not hidden.{0}This text is hidden.", System.lineSeparator()) + : "This text is not hidden.", textAbsorber.getText()); + + pdfDoc.close(); + } + + @DataProvider(name = "layoutOptionsHiddenTextDataProvider") + public static Object[][] layoutOptionsHiddenTextDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "layoutOptionsParagraphMarksDataProvider") + public void layoutOptionsParagraphMarks(boolean showParagraphMarks) throws Exception { + //ExStart + //ExFor:Document.LayoutOptions + //ExFor:LayoutOptions + //ExFor:LayoutOptions.ShowParagraphMarks + //ExSummary:Shows how to show paragraph marks in a rendered output document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + Assert.assertFalse(doc.getLayoutOptions().getShowParagraphMarks()); //ExSkip + + // Add some paragraphs, then enable paragraph marks to show the ends of paragraphs + // with a pilcrow (¶) symbol when we render the document. + builder.writeln("Hello world!"); + builder.writeln("Hello again!"); + + doc.getLayoutOptions().setShowParagraphMarks(showParagraphMarks); + + doc.save(getArtifactsDir() + "Document.LayoutOptionsParagraphMarks.pdf"); + //ExEnd + + com.aspose.pdf.Document pdfDoc = new com.aspose.pdf.Document(getArtifactsDir() + "Document.LayoutOptionsParagraphMarks.pdf"); + TextAbsorber textAbsorber = new TextAbsorber(); + textAbsorber.visit(pdfDoc); + + Assert.assertEquals(showParagraphMarks ? + MessageFormat.format("Hello world!¶{0}Hello again!¶{1}¶", System.lineSeparator(), System.lineSeparator()) : + MessageFormat.format("Hello world!{0}Hello again!", System.lineSeparator()), textAbsorber.getText()); + + pdfDoc.close(); + } + + //JAVA-added data provider for test method + @DataProvider(name = "layoutOptionsParagraphMarksDataProvider") + public static Object[][] layoutOptionsParagraphMarksDataProvider() throws Exception { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void updatePageLayout() throws Exception { + //ExStart + //ExFor:StyleCollection.Item(String) + //ExFor:SectionCollection.Item(Int32) + //ExFor:Document.UpdatePageLayout + //ExFor:Margins + //ExFor:PageSetup.Margins + //ExSummary:Shows when to recalculate the page layout of the document. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // Saving a document to PDF, to an image, or printing for the first time will automatically + // cache the layout of the document within its pages. + doc.save(getArtifactsDir() + "Document.UpdatePageLayout.1.pdf"); + + // Modify the document in some way. + doc.getStyles().get("Normal").getFont().setSize(6.0); + doc.getSections().get(0).getPageSetup().setOrientation(Orientation.LANDSCAPE); + doc.getSections().get(0).getPageSetup().setMargins(Margins.MIRRORED); + + // In the current version of Aspose.Words, modifying the document does not automatically rebuild + // the cached page layout. If we wish for the cached layout + // to stay up to date, we will need to update it manually. + doc.updatePageLayout(); + + doc.save(getArtifactsDir() + "Document.UpdatePageLayout.2.pdf"); + //ExEnd + } + + @Test + public void docPackageCustomParts() throws Exception { + //ExStart + //ExFor:CustomPart + //ExFor:CustomPart.ContentType + //ExFor:CustomPart.RelationshipType + //ExFor:CustomPart.IsExternal + //ExFor:CustomPart.Data + //ExFor:CustomPart.Name + //ExFor:CustomPart.Clone + //ExFor:CustomPartCollection + //ExFor:CustomPartCollection.Add(CustomPart) + //ExFor:CustomPartCollection.Clear + //ExFor:CustomPartCollection.Clone + //ExFor:CustomPartCollection.Count + //ExFor:CustomPartCollection.GetEnumerator + //ExFor:CustomPartCollection.Item(Int32) + //ExFor:CustomPartCollection.RemoveAt(Int32) + //ExFor:Document.PackageCustomParts + //ExSummary:Shows how to access a document's arbitrary custom parts collection. + Document doc = new Document(getMyDir() + "Custom parts OOXML package.docx"); + + Assert.assertEquals(2, doc.getPackageCustomParts().getCount()); + + // Clone the second part, then add the clone to the collection. + CustomPart clonedPart = doc.getPackageCustomParts().get(1).deepClone(); + doc.getPackageCustomParts().add(clonedPart); + testDocPackageCustomParts(doc.getPackageCustomParts()); //ExSkip + + Assert.assertEquals(3, doc.getPackageCustomParts().getCount()); + + // Enumerate over the collection and print every part. + Iterator enumerator = doc.getPackageCustomParts().iterator(); + + int index = 0; + while (enumerator.hasNext()) { + CustomPart customPart = enumerator.next(); + System.out.println(MessageFormat.format("Part index {0}:", index)); + System.out.println(MessageFormat.format("\tName: {0}", customPart.getName())); + System.out.println(MessageFormat.format("\tContentType: {0}", customPart.getContentType())); + System.out.println(MessageFormat.format("\tRelationshipType: {0}", customPart.getRelationshipType())); + if (customPart.isExternal()) { + System.out.println("\tSourced from outside the document"); + } else { + System.out.println(MessageFormat.format("\tSourced from within the document, length: {0} bytes", customPart.getData().length)); + } + index++; + } + + // We can remove elements from this collection individually, or all at once. + doc.getPackageCustomParts().removeAt(2); + + Assert.assertEquals(2, doc.getPackageCustomParts().getCount()); + + doc.getPackageCustomParts().clear(); + + Assert.assertEquals(0, doc.getPackageCustomParts().getCount()); + //ExEnd + } + + private static void testDocPackageCustomParts(CustomPartCollection parts) { + Assert.assertEquals(3, parts.getCount()); + + Assert.assertEquals("/payload/payload_on_package.test", parts.get(0).getName()); + Assert.assertEquals("mytest/somedata", parts.get(0).getContentType()); + Assert.assertEquals("http://mytest.payload.internal", parts.get(0).getRelationshipType()); + Assert.assertEquals(false, parts.get(0).isExternal()); + Assert.assertEquals(18, parts.get(0).getData().length); + + Assert.assertEquals("http://www.aspose.com/Images/aspose-logo.jpg", parts.get(1).getName()); + Assert.assertEquals("", parts.get(1).getContentType()); + Assert.assertEquals("http://mytest.payload.external", parts.get(1).getRelationshipType()); + Assert.assertEquals(true, parts.get(1).isExternal()); + Assert.assertEquals(0, parts.get(1).getData().length); + + Assert.assertEquals("http://www.aspose.com/Images/aspose-logo.jpg", parts.get(2).getName()); + Assert.assertEquals("", parts.get(2).getContentType()); + Assert.assertEquals("http://mytest.payload.external", parts.get(2).getRelationshipType()); + Assert.assertEquals(true, parts.get(2).isExternal()); + Assert.assertEquals(0, parts.get(2).getData().length); + } + + @Test(dataProvider = "shadeFormDataDataProvider") + public void shadeFormData(boolean useGreyShading) throws Exception { + //ExStart + //ExFor:Document.ShadeFormData + //ExSummary:Shows how to apply gray shading to form fields. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + Assert.assertTrue(doc.getShadeFormData()); //ExSkip + + builder.write("Hello world! "); + builder.insertTextInput("My form field", TextFormFieldType.REGULAR, "", + "Text contents of form field, which are shaded in grey by default.", 0); + + // We can turn the grey shading off, so the bookmarked text will blend in with the other text. + doc.setShadeFormData(useGreyShading); + doc.save(getArtifactsDir() + "Document.ShadeFormData.docx"); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "shadeFormDataDataProvider") + public static Object[][] shadeFormDataDataProvider() throws Exception { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void versionsCount() throws Exception { + //ExStart + //ExFor:Document.VersionsCount + //ExSummary:Shows how to work with the versions count feature of older Microsoft Word documents. + Document doc = new Document(getMyDir() + "Versions.doc"); + + // We can read this property of a document, but we cannot preserve it while saving. + Assert.assertEquals(4, doc.getVersionsCount()); + + doc.save(getArtifactsDir() + "Document.VersionsCount.doc"); + doc = new Document(getArtifactsDir() + "Document.VersionsCount.doc"); + + Assert.assertEquals(0, doc.getVersionsCount()); + //ExEnd + } + + @Test + public void writeProtection() throws Exception { + //ExStart + //ExFor:Document.WriteProtection + //ExFor:WriteProtection + //ExFor:WriteProtection.IsWriteProtected + //ExFor:WriteProtection.ReadOnlyRecommended + //ExFor:WriteProtection.SetPassword(String) + //ExFor:WriteProtection.ValidatePassword(String) + //ExSummary:Shows how to protect a document with a password. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world! This document is protected."); + Assert.assertFalse(doc.getWriteProtection().isWriteProtected()); //ExSkip + Assert.assertFalse(doc.getWriteProtection().getReadOnlyRecommended()); //ExSkip + + // Enter a password up to 15 characters in length, and then verify the document's protection status. + doc.getWriteProtection().setPassword("MyPassword"); + doc.getWriteProtection().setReadOnlyRecommended(true); + + Assert.assertTrue(doc.getWriteProtection().isWriteProtected()); + Assert.assertTrue(doc.getWriteProtection().validatePassword("MyPassword")); + + // Protection does not prevent the document from being edited programmatically, nor does it encrypt the contents. + doc.save(getArtifactsDir() + "Document.WriteProtection.docx"); + doc = new Document(getArtifactsDir() + "Document.WriteProtection.docx"); + + Assert.assertTrue(doc.getWriteProtection().isWriteProtected()); + + builder = new DocumentBuilder(doc); + builder.moveToDocumentEnd(); + builder.writeln("Writing text in a protected document."); + + Assert.assertEquals("Hello world! This document is protected." + + "\rWriting text in a protected document.", doc.getText().trim()); + //ExEnd + + Assert.assertTrue(doc.getWriteProtection().getReadOnlyRecommended()); + Assert.assertTrue(doc.getWriteProtection().validatePassword("MyPassword")); + Assert.assertFalse(doc.getWriteProtection().validatePassword("wrongpassword")); + } + + @Test(dataProvider = "removePersonalInformationDataProvider") + public void removePersonalInformation(boolean saveWithoutPersonalInfo) throws Exception { + //ExStart + //ExFor:Document.RemovePersonalInformation + //ExSummary:Shows how to enable the removal of personal information during a manual save. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert some content with personal information. + doc.getBuiltInDocumentProperties().setAuthor("John Doe"); + doc.getBuiltInDocumentProperties().setCompany("Placeholder Inc."); + + doc.startTrackRevisions(doc.getBuiltInDocumentProperties().getAuthor(), new Date()); + builder.write("Hello world!"); + doc.stopTrackRevisions(); + + // This flag is equivalent to File -> Options -> Trust Center -> Trust Center Settings... -> + // Privacy Options -> "Remove personal information from file properties on save" in Microsoft Word. + doc.setRemovePersonalInformation(saveWithoutPersonalInfo); + + // This option will not take effect during a save operation made using Aspose.Words. + // Personal data will be removed from our document with the flag set when we save it manually using Microsoft Word. + doc.save(getArtifactsDir() + "Document.RemovePersonalInformation.docx"); + doc = new Document(getArtifactsDir() + "Document.RemovePersonalInformation.docx"); + + Assert.assertEquals(saveWithoutPersonalInfo, doc.getRemovePersonalInformation()); + Assert.assertEquals("John Doe", doc.getBuiltInDocumentProperties().getAuthor()); + Assert.assertEquals("Placeholder Inc.", doc.getBuiltInDocumentProperties().getCompany()); + Assert.assertEquals("John Doe", doc.getRevisions().get(0).getAuthor()); + //ExEnd + } + + @DataProvider(name = "removePersonalInformationDataProvider") + public static Object[][] removePersonalInformationDataProvider() throws Exception { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void showComments() throws Exception + { + //ExStart + //ExFor:LayoutOptions.CommentDisplayMode + //ExFor:CommentDisplayMode + //ExSummary:Shows how to show comments when saving a document to a rendered format. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Hello world!"); + + Comment comment = new Comment(doc, "John Doe", "J.D.", new Date()); + comment.setText("My comment."); + builder.getCurrentParagraph().appendChild(comment); + + // ShowInAnnotations is only available in Pdf1.7 and Pdf1.5 formats. + // In other formats, it will work similarly to Hide. + doc.getLayoutOptions().setCommentDisplayMode(CommentDisplayMode.SHOW_IN_ANNOTATIONS); + + doc.save(getArtifactsDir() + "Document.ShowCommentsInAnnotations.pdf"); + + // Note that it's required to rebuild the document page layout (via Document.UpdatePageLayout() method) + // after changing the Document.LayoutOptions values. + doc.getLayoutOptions().setCommentDisplayMode(CommentDisplayMode.SHOW_IN_BALLOONS); + doc.updatePageLayout(); + + doc.save(getArtifactsDir() + "Document.ShowCommentsInBalloons.pdf"); + //ExEnd + + com.aspose.pdf.Document pdfDoc = + new com.aspose.pdf.Document(getArtifactsDir() + "Document.ShowCommentsInBalloons.pdf"); + TextAbsorber textAbsorber = new TextAbsorber(); + textAbsorber.visit(pdfDoc); + + Assert.assertEquals( + "Hello world! Commented [J.D.1]: My comment.", + textAbsorber.getText()); + + pdfDoc.close(); + } + + @Test + public void copyTemplateStylesViaDocument() throws Exception { + //ExStart + //ExFor:Document.CopyStylesFromTemplate(Document) + //ExSummary:Shows how to copies styles from the template to a document via Document. + Document template = new Document(getMyDir() + "Rendering.docx"); + Document target = new Document(getMyDir() + "Document.docx"); + + Assert.assertEquals(template.getStyles().getCount(), 18); //ExSkip + Assert.assertEquals(target.getStyles().getCount(), 12); //ExSkip + + target.copyStylesFromTemplate(template); + //ExEnd + Assert.assertEquals(target.getStyles().getCount(), 22); //ExSkip + } + + @Test + public void copyTemplateStylesViaDocumentNew() throws Exception { + //ExStart + //ExFor:Document.CopyStylesFromTemplate(Document) + //ExFor:Document.CopyStylesFromTemplate(String) + //ExSummary:Shows how to copy styles from one document to another. + // Create a document, and then add styles that we will copy to another document. + Document template = new Document(); + + Style style = template.getStyles().add(StyleType.PARAGRAPH, "TemplateStyle1"); + style.getFont().setName("Times New Roman"); + style.getFont().setColor(Color.WHITE); + + style = template.getStyles().add(StyleType.PARAGRAPH, "TemplateStyle2"); + style.getFont().setName("Arial"); + style.getFont().setColor(Color.RED); + + style = template.getStyles().add(StyleType.PARAGRAPH, "TemplateStyle3"); + style.getFont().setName("Courier New"); + style.getFont().setColor(Color.BLUE); + + Assert.assertEquals(7, template.getStyles().getCount()); + + // Create a document which we will copy the styles to. + Document target = new Document(); + + // Create a style with the same name as a style from the template document and add it to the target document. + style = target.getStyles().add(StyleType.PARAGRAPH, "TemplateStyle3"); + style.getFont().setName("Calibri"); + style.getFont().setColor(Color.ORANGE); + + Assert.assertEquals(5, target.getStyles().getCount()); + + // There are two ways of calling the method to copy all the styles from one document to another. + // 1 - Passing the template document object: + target.copyStylesFromTemplate(template); + + // Copying styles adds all styles from the template document to the target + // and overwrites existing styles with the same name. + Assert.assertEquals(7, target.getStyles().getCount()); + + Assert.assertEquals("Courier New", target.getStyles().get("TemplateStyle3").getFont().getName()); + Assert.assertEquals(Color.BLUE.getRGB(), target.getStyles().get("TemplateStyle3").getFont().getColor().getRGB()); + + // 2 - Passing the local system filename of a template document: + target.copyStylesFromTemplate(getMyDir() + "Rendering.docx"); + + Assert.assertEquals(21, target.getStyles().getCount()); + //ExEnd + } + + @Test + public void readMacrosFromExistingDocument() throws Exception { + //ExStart + //ExFor:Document.VbaProject + //ExFor:VbaModuleCollection + //ExFor:VbaModuleCollection.Count + //ExFor:VbaModuleCollection.Item(System.Int32) + //ExFor:VbaModuleCollection.Item(System.String) + //ExFor:VbaModuleCollection.Remove + //ExFor:VbaModule + //ExFor:VbaModule.Name + //ExFor:VbaModule.SourceCode + //ExFor:VbaProject + //ExFor:VbaProject.Name + //ExFor:VbaProject.Modules + //ExFor:VbaProject.CodePage + //ExFor:VbaProject.IsSigned + //ExSummary:Shows how to access a document's VBA project information. + Document doc = new Document(getMyDir() + "VBA project.docm"); + + // A VBA project contains a collection of VBA modules. + VbaProject vbaProject = doc.getVbaProject(); + Assert.assertTrue(vbaProject.isSigned()); //ExSkip + System.out.println(vbaProject.isSigned() + ? MessageFormat.format("Project name: {0} signed; Project code page: {1}; Modules count: {2}\n", vbaProject.getName(), vbaProject.getCodePage(), vbaProject.getModules().getCount()) + : MessageFormat.format("Project name: {0} not signed; Project code page: {1}; Modules count: {2}\n", vbaProject.getName(), vbaProject.getCodePage(), vbaProject.getModules().getCount())); + + VbaModuleCollection vbaModules = doc.getVbaProject().getModules(); + + Assert.assertEquals(vbaModules.getCount(), 3); + + for (VbaModule module : vbaModules) { + System.out.println(MessageFormat.format("Module name: {0};\nModule code:\n{1}\n", module.getName(), module.getSourceCode())); + } + + // Set new source code for VBA module. You can access VBA modules in the collection either by index or by name. + vbaModules.get(0).setSourceCode("Your VBA code..."); + vbaModules.get("Module1").setSourceCode("Your VBA code..."); + + // Remove a module from the collection. + vbaModules.remove(vbaModules.get(2)); + //ExEnd + + Assert.assertEquals("AsposeVBAtest", vbaProject.getName()); + Assert.assertEquals(2, vbaProject.getModules().getCount()); + Assert.assertEquals(1251, vbaProject.getCodePage()); + Assert.assertFalse(vbaProject.isSigned()); + + Assert.assertEquals("ThisDocument", vbaModules.get(0).getName()); + Assert.assertEquals("Your VBA code...", vbaModules.get(0).getSourceCode()); + + Assert.assertEquals("Module1", vbaModules.get(1).getName()); + Assert.assertEquals("Your VBA code...", vbaModules.get(1).getSourceCode()); + } + + @Test + public void saveOutputParameters() throws Exception { + //ExStart + //ExFor:SaveOutputParameters + //ExFor:SaveOutputParameters.ContentType + //ExSummary:Shows how to access output parameters of a document's save operation. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + // After we save a document, we can access the Internet Media Type (MIME type) of the newly created output document. + SaveOutputParameters parameters = doc.save(getArtifactsDir() + "Document.SaveOutputParameters.doc"); + + Assert.assertEquals("application/msword", parameters.getContentType()); + + // This property changes depending on the save format. + parameters = doc.save(getArtifactsDir() + "Document.SaveOutputParameters.pdf"); + + Assert.assertEquals("application/pdf", parameters.getContentType()); + //ExEnd + } + + @Test + public void subDocument() throws Exception { + //ExStart + //ExFor:SubDocument + //ExFor:SubDocument.NodeType + //ExSummary:Shows how to access a master document's subdocument. + Document doc = new Document(getMyDir() + "Master document.docx"); + + NodeCollection subDocuments = doc.getChildNodes(NodeType.SUB_DOCUMENT, true); + Assert.assertEquals(1, subDocuments.getCount()); //ExSkip + + // This node serves as a reference to an external document, and its contents cannot be accessed. + SubDocument subDocument = (SubDocument) subDocuments.get(0); + + Assert.assertFalse(subDocument.isComposite()); + //ExEnd + } + + @Test + public void createWebExtension() throws Exception { + //ExStart + //ExFor:BaseWebExtensionCollection`1.Add(`0) + //ExFor:BaseWebExtensionCollection`1.Clear + //ExFor:Document.WebExtensionTaskPanes + //ExFor:TaskPane + //ExFor:TaskPane.DockState + //ExFor:TaskPane.IsVisible + //ExFor:TaskPane.Width + //ExFor:TaskPane.IsLocked + //ExFor:TaskPane.WebExtension + //ExFor:TaskPane.Row + //ExFor:WebExtension + //ExFor:WebExtension.Id + //ExFor:WebExtension.AlternateReferences + //ExFor:WebExtension.Reference + //ExFor:WebExtension.Properties + //ExFor:WebExtension.Bindings + //ExFor:WebExtension.IsFrozen + //ExFor:WebExtensionReference + //ExFor:WebExtensionReference.Id + //ExFor:WebExtensionReference.Version + //ExFor:WebExtensionReference.StoreType + //ExFor:WebExtensionReference.Store + //ExFor:WebExtensionPropertyCollection + //ExFor:WebExtensionBindingCollection + //ExFor:WebExtensionProperty.#ctor(String, String) + //ExFor:WebExtensionProperty.Name + //ExFor:WebExtensionProperty.Value + //ExFor:WebExtensionBinding.#ctor(String, WebExtensionBindingType, String) + //ExFor:WebExtensionStoreType + //ExFor:WebExtensionBindingType + //ExFor:TaskPaneDockState + //ExFor:TaskPaneCollection + //ExFor:WebExtensionBinding.Id + //ExFor:WebExtensionBinding.AppRef + //ExFor:WebExtensionBinding.BindingType + //ExSummary:Shows how to add a web extension to a document. + Document doc = new Document(); + + // Create task pane with "MyScript" add-in, which will be used by the document, + // then set its default location. + TaskPane myScriptTaskPane = new TaskPane(); + doc.getWebExtensionTaskPanes().add(myScriptTaskPane); + myScriptTaskPane.setDockState(TaskPaneDockState.RIGHT); + myScriptTaskPane.isVisible(true); + myScriptTaskPane.setWidth(300.0); + myScriptTaskPane.isLocked(true); + + // If there are multiple task panes in the same docking location, we can set this index to arrange them. + myScriptTaskPane.setRow(1); + + // Create an add-in called "MyScript Math Sample", which the task pane will display within. + WebExtension webExtension = myScriptTaskPane.getWebExtension(); + + // Set application store reference parameters for our add-in, such as the ID. + webExtension.getReference().setId("WA104380646"); + webExtension.getReference().setVersion("1.0.0.0"); + webExtension.getReference().setStoreType(WebExtensionStoreType.OMEX); + webExtension.getReference().setStore("English (United States)"); + webExtension.getProperties().add(new WebExtensionProperty("MyScript", "MyScript Math Sample")); + webExtension.getBindings().add(new WebExtensionBinding("MyScript", WebExtensionBindingType.TEXT, "104380646")); + + // Allow the user to interact with the add-in. + webExtension.isFrozen(false); + + // We can access the web extension in Microsoft Word via Developer -> Add-ins. + doc.save(getArtifactsDir() + "Document.WebExtension.docx"); + + // Remove all web extension task panes at once like this. + doc.getWebExtensionTaskPanes().clear(); + + Assert.assertEquals(0, doc.getWebExtensionTaskPanes().getCount()); + + doc = new Document(getArtifactsDir() + "Document.WebExtension.docx"); + + myScriptTaskPane = doc.getWebExtensionTaskPanes().get(0); + Assert.assertEquals(TaskPaneDockState.RIGHT, myScriptTaskPane.getDockState()); + Assert.assertTrue(myScriptTaskPane.isVisible()); + Assert.assertEquals(300.0d, myScriptTaskPane.getWidth()); + Assert.assertTrue(myScriptTaskPane.isLocked()); + Assert.assertEquals(1, myScriptTaskPane.getRow()); + + webExtension = myScriptTaskPane.getWebExtension(); + Assert.assertEquals("", webExtension.getId()); + + Assert.assertEquals("WA104380646", webExtension.getReference().getId()); + Assert.assertEquals("1.0.0.0", webExtension.getReference().getVersion()); + Assert.assertEquals(WebExtensionStoreType.OMEX, webExtension.getReference().getStoreType()); + Assert.assertEquals("English (United States)", webExtension.getReference().getStore()); + Assert.assertEquals(0, webExtension.getAlternateReferences().getCount()); + + Assert.assertEquals("MyScript", webExtension.getProperties().get(0).getName()); + Assert.assertEquals("MyScript Math Sample", webExtension.getProperties().get(0).getValue()); + + Assert.assertEquals("MyScript", webExtension.getBindings().get(0).getId()); + Assert.assertEquals(WebExtensionBindingType.TEXT, webExtension.getBindings().get(0).getBindingType()); + Assert.assertEquals("104380646", webExtension.getBindings().get(0).getAppRef()); + + Assert.assertFalse(webExtension.isFrozen()); + //ExEnd + } + + @Test + public void getWebExtensionInfo() throws Exception { + //ExStart + //ExFor:BaseWebExtensionCollection`1 + //ExFor:BaseWebExtensionCollection`1.GetEnumerator + //ExFor:BaseWebExtensionCollection`1.Remove(Int32) + //ExFor:BaseWebExtensionCollection`1.Count + //ExFor:BaseWebExtensionCollection`1.Item(Int32) + //ExSummary:Shows how to work with a document's collection of web extensions. + Document doc = new Document(getMyDir() + "Web extension.docx"); + + Assert.assertEquals(1, doc.getWebExtensionTaskPanes().getCount()); + + // Print all properties of the document's web extension. + WebExtensionPropertyCollection webExtensionPropertyCollection = doc.getWebExtensionTaskPanes().get(0).getWebExtension().getProperties(); + Iterator enumerator = webExtensionPropertyCollection.iterator(); + + while (enumerator.hasNext()) { + WebExtensionProperty webExtensionProperty = enumerator.next(); + System.out.println("Binding name: {webExtensionProperty.Name}; Binding value: {webExtensionProperty.Value}"); + } + + // Remove the web extension. + doc.getWebExtensionTaskPanes().remove(0); + + Assert.assertEquals(0, doc.getWebExtensionTaskPanes().getCount()); + //ExEnd + } + + @Test + public void epubCover() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + // When saving to .epub, some Microsoft Word document properties convert to .epub metadata. + doc.getBuiltInDocumentProperties().setAuthor("John Doe"); + doc.getBuiltInDocumentProperties().setTitle("My Book Title"); + + // The thumbnail we specify here can become the cover image. + byte[] image = DocumentHelper.getBytesFromStream(new FileInputStream(getImageDir() + "Transparent background logo.png")); + doc.getBuiltInDocumentProperties().setThumbnail(image); + + doc.save(getArtifactsDir() + "Document.EpubCover.epub"); + } + + @Test + public void textWatermark() throws Exception { + //ExStart + //ExFor:Document.Watermark + //ExFor:Watermark + //ExFor:Watermark.SetText(String) + //ExFor:Watermark.SetText(String, TextWatermarkOptions) + //ExFor:Watermark.Remove + //ExFor:TextWatermarkOptions + //ExFor:TextWatermarkOptions.FontFamily + //ExFor:TextWatermarkOptions.FontSize + //ExFor:TextWatermarkOptions.Color + //ExFor:TextWatermarkOptions.Layout + //ExFor:TextWatermarkOptions.IsSemitrasparent + //ExFor:WatermarkLayout + //ExFor:WatermarkType + //ExFor:Watermark.Type + //ExSummary:Shows how to create a text watermark. + Document doc = new Document(); + + // Add a plain text watermark. + doc.getWatermark().setText("Aspose Watermark"); + + // If we wish to edit the text formatting using it as a watermark, + // we can do so by passing a TextWatermarkOptions object when creating the watermark. + TextWatermarkOptions textWatermarkOptions = new TextWatermarkOptions(); + textWatermarkOptions.setFontFamily("Arial"); + textWatermarkOptions.setFontSize(36f); + textWatermarkOptions.setColor(Color.BLACK); + textWatermarkOptions.setLayout(WatermarkLayout.DIAGONAL); + textWatermarkOptions.isSemitrasparent(false); + + doc.getWatermark().setText("Aspose Watermark", textWatermarkOptions); + + doc.save(getArtifactsDir() + "Document.TextWatermark.docx"); + + // We can remove a watermark from a document like this. + if (doc.getWatermark().getType() == WatermarkType.TEXT) + doc.getWatermark().remove(); + //ExEnd + + doc = new Document(getArtifactsDir() + "Document.TextWatermark.docx"); + + Assert.assertEquals(WatermarkType.TEXT, doc.getWatermark().getType()); + } + + @Test + public void imageWatermark() throws Exception { + //ExStart + //ExFor:Watermark.SetImage(Image) + //ExFor:Watermark.SetImage(Image, ImageWatermarkOptions) + //ExFor:Watermark.SetImage(String, ImageWatermarkOptions) + //ExFor:ImageWatermarkOptions + //ExFor:ImageWatermarkOptions.Scale + //ExFor:ImageWatermarkOptions.IsWashout + //ExSummary:Shows how to create a watermark from an image in the local file system. + Document doc = new Document(); + + // Modify the image watermark's appearance with an ImageWatermarkOptions object, + // then pass it while creating a watermark from an image file. + ImageWatermarkOptions imageWatermarkOptions = new ImageWatermarkOptions(); + imageWatermarkOptions.setScale(5.0); + imageWatermarkOptions.isWashout(false); + + // We have a different options to insert image: + doc.getWatermark().setImage(ImageIO.read(new File(getImageDir() + "Logo.jpg")), imageWatermarkOptions); + + doc.getWatermark().setImage(ImageIO.read(new File(getImageDir() + "Logo.jpg"))); + + doc.getWatermark().setImage(getImageDir() + "Logo.jpg", imageWatermarkOptions); + + doc.save(getArtifactsDir() + "Document.ImageWatermark.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Document.ImageWatermark.docx"); + + Assert.assertEquals(WatermarkType.IMAGE, doc.getWatermark().getType()); + } + + @Test + public void imageWatermarkStream() throws Exception + { + //ExStart:ImageWatermarkStream + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Watermark.SetImage(Stream, ImageWatermarkOptions) + //ExSummary:Shows how to create a watermark from an image stream. + Document doc = new Document(); + + // Modify the image watermark's appearance with an ImageWatermarkOptions object, + // then pass it while creating a watermark from an image file. + ImageWatermarkOptions imageWatermarkOptions = new ImageWatermarkOptions(); + imageWatermarkOptions.setScale(5.0); + + try (FileInputStream imageStream = new FileInputStream(getImageDir() + "Logo.jpg")) { + doc.getWatermark().setImage(imageStream, imageWatermarkOptions); + } + + doc.save(getArtifactsDir() + "Document.ImageWatermarkStream.docx"); + //ExEnd:ImageWatermarkStream + + doc = new Document(getArtifactsDir() + "Document.ImageWatermarkStream.docx"); + Assert.assertEquals(WatermarkType.IMAGE, doc.getWatermark().getType()); + } + + @Test(dataProvider = "spellingAndGrammarErrorsDataProvider") + public void spellingAndGrammarErrors(boolean showErrors) throws Exception + { + //ExStart + //ExFor:Document.ShowGrammaticalErrors + //ExFor:Document.ShowSpellingErrors + //ExSummary:Shows how to show/hide errors in the document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert two sentences with mistakes that would be picked up + // by the spelling and grammar checkers in Microsoft Word. + builder.writeln("There is a speling error in this sentence."); + builder.writeln("Their is a grammatical error in this sentence."); + + // If these options are enabled, then spelling errors will be underlined + // in the output document by a jagged red line, and a double blue line will highlight grammatical mistakes. + doc.setShowGrammaticalErrors(showErrors); + doc.setShowSpellingErrors(showErrors); + + doc.save(getArtifactsDir() + "Document.SpellingAndGrammarErrors.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Document.SpellingAndGrammarErrors.docx"); + + Assert.assertEquals(showErrors, doc.getShowGrammaticalErrors()); + Assert.assertEquals(showErrors, doc.getShowSpellingErrors()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "spellingAndGrammarErrorsDataProvider") + public static Object[][] spellingAndGrammarErrorsDataProvider() throws Exception { + return new Object[][] + { + {false}, + {true}, + }; + } + + @DataProvider(name = "granularityCompareOptionDataProvider") + public static Object[][] granularityCompareOptionDataProvider() throws Exception { + return new Object[][] + { + {Granularity.CHAR_LEVEL}, + {Granularity.WORD_LEVEL}, + }; + } + + @Test + public void ignorePrinterMetrics() throws Exception { + //ExStart + //ExFor:LayoutOptions.IgnorePrinterMetrics + //ExSummary:Shows how to ignore 'Use printer metrics to lay out document' option. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + doc.getLayoutOptions().setIgnorePrinterMetrics(false); + + doc.save(getArtifactsDir() + "Document.IgnorePrinterMetrics.docx"); + //ExEnd + } + + @Test + public void extractPages() throws Exception { + //ExStart + //ExFor:Document.ExtractPages(int, int) + //ExSummary:Shows how to get specified range of pages from the document. + Document doc = new Document(getMyDir() + "Layout entities.docx"); + + doc = doc.extractPages(0, 2); + + doc.save(getArtifactsDir() + "Document.ExtractPages.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Document.ExtractPages.docx"); + Assert.assertEquals(doc.getPageCount(), 2); + } + + @Test(dataProvider = "spellingOrGrammarDataProvider") + public void spellingOrGrammar(boolean checkSpellingGrammar) throws Exception { + //ExStart + //ExFor:Document.SpellingChecked + //ExFor:Document.GrammarChecked + //ExSummary:Shows how to set spelling or grammar verifying. + Document doc = new Document(); + + // The string with spelling errors. + doc.getFirstSection().getBody().getFirstParagraph().getRuns().add(new Run(doc, "The speeling in this documentz is all broked.")); + + // Spelling/Grammar check start if we set properties to false. + // We can see all errors in Microsoft Word via Review -> Spelling & Grammar. + // Note that Microsoft Word does not start grammar/spell check automatically for DOC and RTF document format. + doc.setSpellingChecked(checkSpellingGrammar); + doc.setGrammarChecked(checkSpellingGrammar); + + doc.save(getArtifactsDir() + "Document.SpellingOrGrammar.docx"); + //ExEnd + } + + @DataProvider(name = "spellingOrGrammarDataProvider") + public static Object[][] spellingOrGrammarDataProvider() { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test + public void allowEmbeddingPostScriptFonts() throws Exception { + //ExStart + //ExFor:SaveOptions.AllowEmbeddingPostScriptFonts + //ExSummary:Shows how to save the document with PostScript font. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("PostScriptFont"); + builder.writeln("Some text with PostScript font."); + + // Load the font with PostScript to use in the document. + MemoryFontSource otf = new MemoryFontSource(DocumentHelper.getBytesFromStream(new FileInputStream(getFontsDir() + "AllegroOpen.otf"))); + doc.setFontSettings(new FontSettings()); + doc.getFontSettings().setFontsSources(new FontSourceBase[]{otf}); + + // Embed TrueType fonts. + doc.getFontInfos().setEmbedTrueTypeFonts(true); + + // Allow embedding PostScript fonts while embedding TrueType fonts. + // Microsoft Word does not embed PostScript fonts, but can open documents with embedded fonts of this type. + SaveOptions saveOptions = SaveOptions.createSaveOptions(SaveFormat.DOCX); + saveOptions.setAllowEmbeddingPostScriptFonts(true); + + doc.save(getArtifactsDir() + "Document.AllowEmbeddingPostScriptFonts.docx", saveOptions); + //ExEnd + } + + @Test + public void frameset() throws Exception + { + //ExStart + //ExFor:Document.Frameset + //ExFor:Frameset + //ExFor:Frameset.FrameDefaultUrl + //ExFor:Frameset.IsFrameLinkToFile + //ExFor:Frameset.ChildFramesets + //ExFor:FramesetCollection + //ExFor:FramesetCollection.Count + //ExFor:FramesetCollection.Item(Int32) + //ExSummary:Shows how to access frames on-page. + // Document contains several frames with links to other documents. + Document doc = new Document(getMyDir() + "Frameset.docx"); + + Assert.assertEquals(3, doc.getFrameset().getChildFramesets().getCount()); + // We can check the default URL (a web page URL or local document) or if the frame is an external resource. + Assert.assertEquals("https://file-examples-com.github.io/uploads/2017/02/file-sample_100kB.docx", + doc.getFrameset().getChildFramesets().get(0).getChildFramesets().get(0).getFrameDefaultUrl()); + Assert.assertTrue(doc.getFrameset().getChildFramesets().get(0).getChildFramesets().get(0).isFrameLinkToFile()); + + Assert.assertEquals("Document.docx", doc.getFrameset().getChildFramesets().get(1).getFrameDefaultUrl()); + Assert.assertFalse(doc.getFrameset().getChildFramesets().get(1).isFrameLinkToFile()); + + // Change properties for one of our frames. + doc.getFrameset().getChildFramesets().get(0).getChildFramesets().get(0).setFrameDefaultUrl("https://github.com/aspose-words/Aspose.Words-for-.NET/blob/master/Examples/Data/Absolute%20position%20tab.docx"); + doc.getFrameset().getChildFramesets().get(0).getChildFramesets().get(0).isFrameLinkToFile(false); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + + Assert.assertEquals( + "https://github.com/aspose-words/Aspose.Words-for-.NET/blob/master/Examples/Data/Absolute%20position%20tab.docx", + doc.getFrameset().getChildFramesets().get(0).getChildFramesets().get(0).getFrameDefaultUrl()); + Assert.assertFalse(doc.getFrameset().getChildFramesets().get(0).getChildFramesets().get(0).isFrameLinkToFile()); + } + + @Test + public void openAzw() throws Exception + { + FileFormatInfo info = FileFormatUtil.detectFileFormat(getMyDir() + "Azw3 document.azw3"); + Assert.assertEquals(info.getLoadFormat(), LoadFormat.AZW_3); + + Document doc = new Document(getMyDir() + "Azw3 document.azw3"); + Assert.assertTrue(doc.getText().contains("Hachette Book Group USA")); + } + + @Test(enabled = false, description = "https://issue.auckland.dynabic.com/issues/WORDSJAVA-2892") + public void openEpub() throws Exception + { + FileFormatInfo info = FileFormatUtil.detectFileFormat(getMyDir() + "Epub document.epub"); + Assert.assertEquals(info.getLoadFormat(), LoadFormat.EPUB); + + Document doc = new Document(getMyDir() + "Epub document.epub"); + Assert.assertTrue(doc.getText().contains("Down the Rabbit-Hole")); + } + + @Test + public void openXml() throws Exception + { + FileFormatInfo info = FileFormatUtil.detectFileFormat(getMyDir() + "Mail merge data - Customers.xml"); + Assert.assertEquals(info.getLoadFormat(), LoadFormat.XML); + + Document doc = new Document(getMyDir() + "Mail merge data - Purchase order.xml"); + Assert.assertTrue(doc.getText().contains("Ellen Adams\r123 Maple Street")); + } + + @Test + public void moveToStructuredDocumentTag() throws Exception + { + //ExStart + //ExFor:DocumentBuilder.MoveToStructuredDocumentTag(int, int) + //ExFor:DocumentBuilder.MoveToStructuredDocumentTag(StructuredDocumentTag, int) + //ExFor:DocumentBuilder.IsAtEndOfStructuredDocumentTag + //ExFor:DocumentBuilder.CurrentStructuredDocumentTag + //ExSummary:Shows how to move cursor of DocumentBuilder inside a structured document tag. + Document doc = new Document(getMyDir() + "Structured document tags.docx"); + DocumentBuilder builder = new DocumentBuilder(doc); + + // There is a several ways to move the cursor: + // 1 - Move to the first character of structured document tag by index. + builder.moveToStructuredDocumentTag(1, 1); + + // 2 - Move to the first character of structured document tag by object. + StructuredDocumentTag tag = (StructuredDocumentTag)doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 2, true); + builder.moveToStructuredDocumentTag(tag, 1); + builder.write(" New text."); + + Assert.assertEquals("R New text.ichText", tag.getText().trim()); + + // 3 - Move to the end of the second structured document tag. + builder.moveToStructuredDocumentTag(1, -1); + Assert.assertTrue(builder.isAtEndOfStructuredDocumentTag()); + + // Get currently selected structured document tag. + builder.getCurrentStructuredDocumentTag().setColor(Color.GREEN); + + doc.save(getArtifactsDir() + "Document.MoveToStructuredDocumentTag.docx"); + //ExEnd + } + + @Test + public void includeTextboxesFootnotesEndnotesInStat() throws Exception + { + //ExStart + //ExFor:Document.IncludeTextboxesFootnotesEndnotesInStat + //ExSummary: Shows how to include or exclude textboxes, footnotes and endnotes from word count statistics. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Lorem ipsum"); + builder.insertFootnote(FootnoteType.FOOTNOTE, "sit amet"); + + // By default option is set to 'false'. + doc.updateWordCount(); + // Words count without textboxes, footnotes and endnotes. + Assert.assertEquals(2, doc.getBuiltInDocumentProperties().getWords()); + + doc.setIncludeTextboxesFootnotesEndnotesInStat(true); + doc.updateWordCount(); + // Words count with textboxes, footnotes and endnotes. + Assert.assertEquals(4, doc.getBuiltInDocumentProperties().getWords()); + //ExEnd + } + + @Test + public void setJustificationMode() throws Exception + { + //ExStart + //ExFor:Document.JustificationMode + //ExFor:JustificationMode + //ExSummary:Shows how to manage character spacing control. + Document doc = new Document(getMyDir() + "Document.docx"); + + int justificationMode = doc.getJustificationMode(); + if (justificationMode == JustificationMode.EXPAND) + doc.setJustificationMode(JustificationMode.COMPRESS); + + doc.save(getArtifactsDir() + "Document.SetJustificationMode.docx"); + //ExEnd + } + + @Test + public void pageIsInColor() throws Exception + { + //ExStart + //ExFor:PageInfo.Colored + //ExFor:Document.GetPageInfo(Int32) + //ExSummary:Shows how to check whether the page is in color or not. + Document doc = new Document(getMyDir() + "Document.docx"); + + // Check that the first page of the document is not colored. + Assert.assertFalse(doc.getPageInfo(0).getColored()); + //ExEnd + } + + @Test + public void insertDocumentInline() throws Exception + { + //ExStart:InsertDocumentInline + //GistId:3428e84add5beb0d46a8face6e5fc858 + //ExFor:DocumentBuilder.InsertDocumentInline(Document, ImportFormatMode, ImportFormatOptions) + //ExSummary:Shows how to insert a document inline at the cursor position. + DocumentBuilder srcDoc = new DocumentBuilder(); + srcDoc.write("[src content]"); + + // Create destination document. + DocumentBuilder dstDoc = new DocumentBuilder(); + dstDoc.write("Before "); + dstDoc.insertNode(new BookmarkStart(dstDoc.getDocument(), "src_place")); + dstDoc.insertNode(new BookmarkEnd(dstDoc.getDocument(), "src_place")); + dstDoc.write(" after"); + + Assert.assertEquals("Before after", dstDoc.getDocument().getText().trim()); + + // Insert source document into destination inline. + dstDoc.moveToBookmark("src_place"); + dstDoc.insertDocumentInline(srcDoc.getDocument(), ImportFormatMode.USE_DESTINATION_STYLES, new ImportFormatOptions()); + + Assert.assertEquals("Before [src content] after", dstDoc.getDocument().getText().trim()); + //ExEnd:InsertDocumentInline + } + + @Test (dataProvider = "saveDocumentToStreamDataProvider") + public void saveDocumentToStream(int saveFormat) throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Lorem ipsum"); + + try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) + { + if (saveFormat == SaveFormat.HTML_FIXED) + { + HtmlFixedSaveOptions saveOptions = new HtmlFixedSaveOptions(); + saveOptions.setExportEmbeddedCss(true); + saveOptions.setExportEmbeddedFonts(true); + saveOptions.setSaveFormat(saveFormat); + + doc.save(stream, saveOptions); + } + else if (saveFormat == SaveFormat.XAML_FIXED) + { + XamlFixedSaveOptions saveOptions = new XamlFixedSaveOptions(); + saveOptions.setResourcesFolder(getArtifactsDir()); + saveOptions.setSaveFormat(saveFormat); + + doc.save(stream, saveOptions); + } + else + doc.save(stream, saveFormat); + } + } + + @DataProvider(name = "saveDocumentToStreamDataProvider") + public static Object[][] saveDocumentToStreamDataProvider() { + return new Object[][] + { + {SaveFormat.DOC}, + {SaveFormat.DOT}, + {SaveFormat.DOCX}, + {SaveFormat.DOCM}, + {SaveFormat.DOTX}, + {SaveFormat.DOTM}, + {SaveFormat.FLAT_OPC}, + {SaveFormat.FLAT_OPC_MACRO_ENABLED}, + {SaveFormat.FLAT_OPC_TEMPLATE}, + {SaveFormat.FLAT_OPC_TEMPLATE_MACRO_ENABLED}, + {SaveFormat.RTF}, + {SaveFormat.WORD_ML}, + {SaveFormat.PDF}, + {SaveFormat.XPS}, + {SaveFormat.XAML_FIXED}, + {SaveFormat.SVG}, + {SaveFormat.HTML_FIXED}, + {SaveFormat.OPEN_XPS}, + {SaveFormat.PS}, + {SaveFormat.PCL}, + {SaveFormat.HTML}, + {SaveFormat.MHTML}, + {SaveFormat.EPUB}, + {SaveFormat.AZW_3}, + {SaveFormat.MOBI}, + {SaveFormat.ODT}, + {SaveFormat.OTT}, + {SaveFormat.TEXT}, + {SaveFormat.XAML_FLOW}, + {SaveFormat.XAML_FLOW_PACK}, + {SaveFormat.MARKDOWN}, + {SaveFormat.XLSX}, + {SaveFormat.TIFF}, + {SaveFormat.PNG}, + {SaveFormat.BMP}, + {SaveFormat.EMF}, + {SaveFormat.JPEG}, + {SaveFormat.GIF}, + {SaveFormat.EPS}, + }; + } + + @Test + public void hasMacros() throws Exception + { + //ExStart:HasMacros + //GistId:f99d87e10ab87a581c52206321d8b617 + //ExFor:FileFormatInfo.HasMacros + //ExSummary:Shows how to check VBA macro presence without loading document. + FileFormatInfo fileFormatInfo = FileFormatUtil.detectFileFormat(getMyDir() + "Macro.docm"); + Assert.assertTrue(fileFormatInfo.hasMacros()); + //ExEnd:HasMacros + } + + @Test + public void punctuationKerning() throws Exception + { + //ExStart + //ExFor:Document.PunctuationKerning + //ExSummary:Shows how to work with kerning applies to both Latin text and punctuation. + Document doc = new Document(getMyDir() + "Document.docx"); + Assert.assertTrue(doc.getPunctuationKerning()); + //ExEnd + } + + @Test + public void removeBlankPages() throws Exception + { + //ExStart + //ExFor:Document.RemoveBlankPages + //ExSummary:Shows how to remove blank pages from the document. + Document doc = new Document(getMyDir() + "Blank pages.docx"); + Assert.assertEquals(2, doc.getPageCount()); + doc.removeBlankPages(); + doc.updatePageLayout(); + Assert.assertEquals(1, doc.getPageCount()); + //ExEnd + } + + @Test + public void extractPagesWithOptions() throws Exception + { + //ExStart:ExtractPagesWithOptions + //GistId:571cc6e23284a2ec075d15d4c32e3bbf + //ExFor:Document.ExtractPages(int, int) + //ExFor:PageExtractOptions + //ExFor:PageExtractOptions.UpdatePageStartingNumber + //ExFor:PageExtractOptions.UnlinkPagesNumberFields + //ExSummary:Show how to reset the initial page numbering and save the NUMPAGE field. + Document doc = new Document(getMyDir() + "Page fields.docx"); + + // Default behavior: + // The extracted page numbering is the same as in the original document, as if we had selected "Print 2 pages" in MS Word. + // The start page will be set to 2 and the field indicating the number of pages will be removed + // and replaced with a constant value equal to the number of pages. + Document extractedDoc1 = doc.extractPages(1, 1); + extractedDoc1.save(getArtifactsDir() + "Document.ExtractPagesWithOptions.Default.docx"); + + Assert.assertEquals(1, extractedDoc1.getRange().getFields().getCount()); //ExSkip + + // Altered behavior: + // The extracted page numbering is reset and a new one begins, + // as if we had copied the contents of the second page and pasted it into a new document. + // The start page will be set to 1 and the field indicating the number of pages will be left unchanged + // and will show the current number of pages. + PageExtractOptions extractOptions = new PageExtractOptions(); + extractOptions.setUpdatePageStartingNumber(false); + extractOptions.setUnlinkPagesNumberFields(false); + Document extractedDoc2 = doc.extractPages(1, 1, extractOptions); + extractedDoc2.save(getArtifactsDir() + "Document.ExtractPagesWithOptions.Options.docx"); + //ExEnd:ExtractPagesWithOptions + + Assert.assertEquals(2, extractedDoc2.getRange().getFields().getCount()); + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExDocumentBase.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExDocumentBase.java new file mode 100644 index 00000000..8f087b36 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExDocumentBase.java @@ -0,0 +1,262 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.pdf.ColorType; +import com.aspose.pdf.XImage; +import com.aspose.words.Shape; +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.awt.*; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; + +@Test +public class ExDocumentBase extends ApiExampleBase { + @Test + public void constructor() throws Exception { + //ExStart + //ExFor:DocumentBase + //ExSummary:Shows how to initialize the subclasses of DocumentBase. + Document doc = new Document(); + + Assert.assertEquals(DocumentBase.class, doc.getClass().getSuperclass()); + + GlossaryDocument glossaryDoc = new GlossaryDocument(); + doc.setGlossaryDocument(glossaryDoc); + + Assert.assertEquals(DocumentBase.class, glossaryDoc.getClass().getSuperclass()); + //ExEnd + } + + @Test + public void setPageColor() throws Exception { + //ExStart + //ExFor:DocumentBase.PageColor + //ExSummary:Shows how to set the background color for all pages of a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + doc.setPageColor(Color.lightGray); + + doc.save(getArtifactsDir() + "DocumentBase.SetPageColor.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBase.SetPageColor.docx"); + Assert.assertEquals(Color.lightGray.getRGB(), doc.getPageColor().getRGB()); + } + + @Test + public void importNode() throws Exception { + //ExStart + //ExFor:DocumentBase.ImportNode(Node, Boolean) + //ExSummary:Shows how to import a node from one document to another. + Document srcDoc = new Document(); + Document dstDoc = new Document(); + + srcDoc.getFirstSection().getBody().getFirstParagraph().appendChild( + new Run(srcDoc, "Source document first paragraph text.")); + dstDoc.getFirstSection().getBody().getFirstParagraph().appendChild( + new Run(dstDoc, "Destination document first paragraph text.")); + + // Every node has a parent document, which is the document that contains the node. + // Inserting a node into a document that the node does not belong to will throw an exception. + Assert.assertNotEquals(dstDoc, srcDoc.getFirstSection().getDocument()); + Assert.assertThrows(IllegalArgumentException.class, () -> dstDoc.appendChild(srcDoc.getFirstSection())); + + // Use the ImportNode method to create a copy of a node, which will have the document + // that called the ImportNode method set as its new owner document. + Section importedSection = (Section) dstDoc.importNode(srcDoc.getFirstSection(), true); + + Assert.assertEquals(dstDoc, importedSection.getDocument()); + + // We can now insert the node into the document. + dstDoc.appendChild(importedSection); + + Assert.assertEquals("Destination document first paragraph text.\r\nSource document first paragraph text.\r\n", + dstDoc.toString(SaveFormat.TEXT)); + //ExEnd + + Assert.assertNotEquals(importedSection, srcDoc.getFirstSection()); + Assert.assertNotEquals(importedSection.getDocument(), srcDoc.getFirstSection().getDocument()); + Assert.assertEquals(importedSection.getBody().getFirstParagraph().getText(), + srcDoc.getFirstSection().getBody().getFirstParagraph().getText()); + } + + @Test + public void importNodeCustom() throws Exception { + //ExStart + //ExFor:DocumentBase.ImportNode(Node, Boolean, ImportFormatMode) + //ExSummary:Shows how to import node from source document to destination document with specific options. + // Create two documents and add a character style to each document. + // Configure the styles to have the same name, but different text formatting. + Document srcDoc = new Document(); + Style srcStyle = srcDoc.getStyles().add(StyleType.CHARACTER, "My style"); + srcStyle.getFont().setName("Courier New"); + DocumentBuilder srcBuilder = new DocumentBuilder(srcDoc); + srcBuilder.getFont().setStyle(srcStyle); + srcBuilder.writeln("Source document text."); + + Document dstDoc = new Document(); + Style dstStyle = dstDoc.getStyles().add(StyleType.CHARACTER, "My style"); + dstStyle.getFont().setName("Calibri"); + DocumentBuilder dstBuilder = new DocumentBuilder(dstDoc); + dstBuilder.getFont().setStyle(dstStyle); + dstBuilder.writeln("Destination document text."); + + // Import the Section from the destination document into the source document, causing a style name collision. + // If we use destination styles, then the imported source text with the same style name + // as destination text will adopt the destination style. + Section importedSection = (Section) dstDoc.importNode(srcDoc.getFirstSection(), true, ImportFormatMode.USE_DESTINATION_STYLES); + Assert.assertEquals("Source document text.", importedSection.getBody().getParagraphs().get(0).getRuns().get(0).getText().trim()); //ExSkip + Assert.assertNull(dstDoc.getStyles().get("My style_0")); //ExSkip + Assert.assertEquals(dstStyle.getFont().getName(), importedSection.getBody().getFirstParagraph().getRuns().get(0).getFont().getName()); + Assert.assertEquals(dstStyle.getName(), importedSection.getBody().getFirstParagraph().getRuns().get(0).getFont().getStyleName()); + + // If we use ImportFormatMode.KeepDifferentStyles, the source style is preserved, + // and the naming clash resolves by adding a suffix. + dstDoc.importNode(srcDoc.getFirstSection(), true, ImportFormatMode.KEEP_DIFFERENT_STYLES); + Assert.assertEquals(dstStyle.getFont().getName(), dstDoc.getStyles().get("My style").getFont().getName()); + Assert.assertEquals(srcStyle.getFont().getName(), dstDoc.getStyles().get("My style_0").getFont().getName()); + //ExEnd + } + + @Test + public void backgroundShape() throws Exception { + //ExStart + //ExFor:DocumentBase.BackgroundShape + //ExSummary:Shows how to set a background shape for every page of a document. + Document doc = new Document(); + + Assert.assertNull(doc.getBackgroundShape()); + + // The only shape type that we can use as a background is a rectangle. + Shape shapeRectangle = new Shape(doc, ShapeType.RECTANGLE); + + // There are two ways of using this shape as a page background. + // 1 - A flat color: + shapeRectangle.setFillColor(Color.BLUE); + doc.setBackgroundShape(shapeRectangle); + + doc.save(getArtifactsDir() + "DocumentBase.BackgroundShape.FlatColor.docx"); + + // 2 - An image: + shapeRectangle = new Shape(doc, ShapeType.RECTANGLE); + shapeRectangle.getImageData().setImage(getImageDir() + "Transparent background logo.png"); + + // Adjust the image's appearance to make it more suitable as a watermark. + shapeRectangle.getImageData().setContrast(0.2); + shapeRectangle.getImageData().setBrightness(0.7); + + doc.setBackgroundShape(shapeRectangle); + + Assert.assertTrue(doc.getBackgroundShape().hasImage()); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setCacheBackgroundGraphics(false); + + // Microsoft Word does not support shapes with images as backgrounds, + // but we can still see these backgrounds in other save formats such as .pdf. + doc.save(getArtifactsDir() + "DocumentBase.BackgroundShape.Image.pdf", saveOptions); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBase.BackgroundShape.FlatColor.docx"); + + Assert.assertEquals(Color.BLUE.getRGB(), doc.getBackgroundShape().getFillColor().getRGB()); + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "DocumentBase.BackgroundShape.Image.pdf"); + XImage pdfDocImage = pdfDocument.getPages().get_Item(1).getResources().getImages().get_Item(1); + + Assert.assertEquals(400, pdfDocImage.getWidth()); + Assert.assertEquals(400, pdfDocImage.getHeight()); + Assert.assertEquals(ColorType.Rgb, pdfDocImage.getColorType()); + + pdfDocument.close(); + } + + //ExStart + //ExFor:DocumentBase.ResourceLoadingCallback + //ExFor:IResourceLoadingCallback + //ExFor:IResourceLoadingCallback.ResourceLoading(ResourceLoadingArgs) + //ExFor:ResourceLoadingAction + //ExFor:ResourceLoadingArgs + //ExFor:ResourceLoadingArgs.OriginalUri + //ExFor:ResourceLoadingArgs.ResourceType + //ExFor:ResourceLoadingArgs.SetData(Byte[]) + //ExFor:ResourceType + //ExSummary:Shows how to customize the process of loading external resources into a document. + @Test //ExSkip + public void resourceLoadingCallback() throws Exception { + Document doc = new Document(); + doc.setResourceLoadingCallback(new ImageNameHandler()); + + DocumentBuilder builder = new DocumentBuilder(doc); + + // Images usually are inserted using a URI, or a byte array. + // Every instance of a resource load will call our callback's ResourceLoading method. + builder.insertImage("Google logo"); + builder.insertImage("Aspose logo"); + builder.insertImage("Watermark"); + + Assert.assertEquals(3, doc.getChildNodes(NodeType.SHAPE, true).getCount()); + + doc.save(getArtifactsDir() + "DocumentBase.ResourceLoadingCallback.docx"); + testResourceLoadingCallback(new Document(getArtifactsDir() + "DocumentBase.ResourceLoadingCallback.docx")); //ExSkip + } + + /// + /// Allows us to load images into a document using predefined shorthands, as opposed to URIs. + /// This will separate image loading logic from the rest of the document construction. + /// + private static class ImageNameHandler implements IResourceLoadingCallback { + public int resourceLoading(final ResourceLoadingArgs args) throws URISyntaxException, IOException { + if (args.getResourceType() == ResourceType.IMAGE) { + // If this callback encounters one of the image shorthands while loading an image, + // it will apply unique logic for each defined shorthand instead of treating it as a URI. + if ("Google logo".equals(args.getOriginalUri())) { + args.setData(DocumentHelper.getBytesFromStream(new URI("http://www.google.com/images/logos/ps_logo2.png").toURL().openStream())); + + return ResourceLoadingAction.USER_PROVIDED; + } + + if ("Aspose logo".equals(args.getOriginalUri())) { + args.setData(DocumentHelper.getBytesFromStream(getAsposelogoUri().toURL().openStream())); + + return ResourceLoadingAction.USER_PROVIDED; + } + + if ("Watermark".equals(args.getOriginalUri())) { + InputStream imageStream = new FileInputStream(getImageDir() + "Transparent background logo.png"); + args.setData(DocumentHelper.getBytesFromStream(imageStream)); + + return ResourceLoadingAction.USER_PROVIDED; + } + } + + return ResourceLoadingAction.DEFAULT; + } + } + //ExEnd + + private void testResourceLoadingCallback(Document doc) throws Exception { + for (Shape shape : (Iterable) doc.getChildNodes(NodeType.SHAPE, true)) { + Assert.assertTrue(shape.hasImage()); + Assert.assertNotEquals(shape.getImageData().getImageBytes(), new byte[0]); + } + + TestUtil.verifyWebResponseStatusCode(200, new URL("http://www.google.com/images/logos/ps_logo2.png")); + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExDocumentBuilder.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExDocumentBuilder.java new file mode 100644 index 00000000..4f8b2676 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExDocumentBuilder.java @@ -0,0 +1,3574 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.Font; +import com.aspose.words.List; +import com.aspose.words.Shape; +import com.aspose.words.*; +import org.apache.commons.collections4.IterableUtils; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.*; +import java.net.URL; +import java.text.DecimalFormat; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.UUID; + +public class ExDocumentBuilder extends ApiExampleBase { + @Test + public void writeAndFont() throws Exception { + //ExStart + //ExFor:Font.Size + //ExFor:Font.Bold + //ExFor:Font.Name + //ExFor:Font.Color + //ExFor:Font.Underline + //ExFor:DocumentBuilder.#ctor + //ExSummary:Shows how to insert formatted text using DocumentBuilder. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Specify font formatting, then add text. + Font font = builder.getFont(); + font.setSize(16.0); + font.setBold(true); + font.setColor(Color.BLUE); + font.setName("Courier New"); + font.setUnderline(Underline.DASH); + + builder.write("Hello world!"); + //ExEnd + + doc = DocumentHelper.saveOpen(builder.getDocument()); + Run firstRun = doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0); + + Assert.assertEquals("Hello world!", firstRun.getText().trim()); + Assert.assertEquals(16.0, firstRun.getFont().getSize()); + Assert.assertTrue(firstRun.getFont().getBold()); + Assert.assertEquals("Courier New", firstRun.getFont().getName()); + Assert.assertEquals(Color.BLUE.getRGB(), firstRun.getFont().getColor().getRGB()); + Assert.assertEquals(Underline.DASH, firstRun.getFont().getUnderline()); + } + + @Test + public void headersAndFooters() throws Exception { + //ExStart + //ExFor:DocumentBuilder + //ExFor:DocumentBuilder.#ctor(Document) + //ExFor:DocumentBuilder.MoveToHeaderFooter + //ExFor:DocumentBuilder.MoveToSection + //ExFor:DocumentBuilder.InsertBreak + //ExFor:DocumentBuilder.Writeln + //ExFor:HeaderFooterType + //ExFor:PageSetup.DifferentFirstPageHeaderFooter + //ExFor:PageSetup.OddAndEvenPagesHeaderFooter + //ExFor:BreakType + //ExSummary:Shows how to create headers and footers in a document using DocumentBuilder. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Specify that we want different headers and footers for first, even and odd pages. + builder.getPageSetup().setDifferentFirstPageHeaderFooter(true); + builder.getPageSetup().setOddAndEvenPagesHeaderFooter(true); + + // Create the headers, then add three pages to the document to display each header type. + builder.moveToHeaderFooter(HeaderFooterType.HEADER_FIRST); + builder.write("Header for the first page"); + builder.moveToHeaderFooter(HeaderFooterType.HEADER_EVEN); + builder.write("Header for even pages"); + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.write("Header for all other pages"); + + builder.moveToSection(0); + builder.writeln("Page1"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page2"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page3"); + + doc.save(getArtifactsDir() + "DocumentBuilder.HeadersAndFooters.docx"); + //ExEnd + + HeaderFooterCollection headersFooters = + new Document(getArtifactsDir() + "DocumentBuilder.HeadersAndFooters.docx").getFirstSection().getHeadersFooters(); + + Assert.assertEquals(3, headersFooters.getCount()); + Assert.assertEquals("Header for the first page", headersFooters.getByHeaderFooterType(HeaderFooterType.HEADER_FIRST).getText().trim()); + Assert.assertEquals("Header for even pages", headersFooters.getByHeaderFooterType(HeaderFooterType.HEADER_EVEN).getText().trim()); + Assert.assertEquals("Header for all other pages", headersFooters.getByHeaderFooterType(HeaderFooterType.HEADER_PRIMARY).getText().trim()); + + } + + @Test + public void mergeFields() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertField(String) + //ExFor:DocumentBuilder.MoveToMergeField(String, Boolean, Boolean) + //ExSummary:Shows how to insert fields, and move the document builder's cursor to them. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertField("MERGEFIELD MyMergeField1 \\* MERGEFORMAT"); + builder.insertField("MERGEFIELD MyMergeField2 \\* MERGEFORMAT"); + + // Move the cursor to the first MERGEFIELD. + builder.moveToMergeField("MyMergeField1", true, false); + + // Note that the cursor is placed immediately after the first MERGEFIELD, and before the second. + Assert.assertEquals(doc.getRange().getFields().get(1).getStart(), builder.getCurrentNode()); + Assert.assertEquals(doc.getRange().getFields().get(0).getEnd(), builder.getCurrentNode().getPreviousSibling()); + + // If we wish to edit the field's field code or contents using the builder, + // its cursor would need to be inside a field. + // To place it inside a field, we would need to call the document builder's MoveTo method + // and pass the field's start or separator node as an argument. + builder.write(" Text between our merge fields. "); + + doc.save(getArtifactsDir() + "DocumentBuilder.MergeFields.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.MergeFields.docx"); + + Assert.assertEquals("MERGEFIELD MyMergeField1 \\* MERGEFORMAT\u0014«MyMergeField1»\u0015" + + " Text between our merge fields. " + + "\u0013MERGEFIELD MyMergeField2 \\* MERGEFORMAT\u0014«MyMergeField2»", doc.getText().trim()); + Assert.assertEquals(2, doc.getRange().getFields().getCount()); + + TestUtil.verifyField(FieldType.FIELD_MERGE_FIELD, "MERGEFIELD MyMergeField1 \\* MERGEFORMAT", "«MyMergeField1»", doc.getRange().getFields().get(0)); + TestUtil.verifyField(FieldType.FIELD_MERGE_FIELD, "MERGEFIELD MyMergeField2 \\* MERGEFORMAT", "«MyMergeField2»", doc.getRange().getFields().get(1)); + } + + @Test + public void insertHorizontalRule() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertHorizontalRule + //ExFor:ShapeBase.IsHorizontalRule + //ExFor:Shape.HorizontalRuleFormat + //ExFor:HorizontalRuleAlignment + //ExFor:HorizontalRuleFormat + //ExFor:HorizontalRuleFormat.Alignment + //ExFor:HorizontalRuleFormat.WidthPercent + //ExFor:HorizontalRuleFormat.Height + //ExFor:HorizontalRuleFormat.Color + //ExFor:HorizontalRuleFormat.NoShade + //ExSummary:Shows how to insert a horizontal rule shape, and customize its formatting. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + Shape shape = builder.insertHorizontalRule(); + + HorizontalRuleFormat horizontalRuleFormat = shape.getHorizontalRuleFormat(); + horizontalRuleFormat.setAlignment(HorizontalRuleAlignment.CENTER); + horizontalRuleFormat.setWidthPercent(70.0); + horizontalRuleFormat.setHeight(3.0); + horizontalRuleFormat.setColor(Color.BLUE); + horizontalRuleFormat.setNoShade(true); + + Assert.assertTrue(shape.isHorizontalRule()); + Assert.assertTrue(shape.getHorizontalRuleFormat().getNoShade()); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(HorizontalRuleAlignment.CENTER, shape.getHorizontalRuleFormat().getAlignment()); + Assert.assertEquals(70.0, shape.getHorizontalRuleFormat().getWidthPercent()); + Assert.assertEquals(3.0, shape.getHorizontalRuleFormat().getHeight()); + Assert.assertEquals(Color.BLUE.getRGB(), shape.getHorizontalRuleFormat().getColor().getRGB()); + } + + @Test(description = "Checking the boundary conditions of WidthPercent and Height properties") + public void horizontalRuleFormatExceptions() throws Exception { + DocumentBuilder builder = new DocumentBuilder(); + Shape shape = builder.insertHorizontalRule(); + + HorizontalRuleFormat horizontalRuleFormat = shape.getHorizontalRuleFormat(); + horizontalRuleFormat.setWidthPercent(1.0); + horizontalRuleFormat.setWidthPercent(100.0); + Assert.assertThrows(IllegalArgumentException.class, () -> horizontalRuleFormat.setWidthPercent(0.0)); + Assert.assertThrows(IllegalArgumentException.class, () -> horizontalRuleFormat.setWidthPercent(101.0)); + + horizontalRuleFormat.setHeight(0.0); + horizontalRuleFormat.setHeight(1584.0); + Assert.assertThrows(IllegalArgumentException.class, () -> horizontalRuleFormat.setHeight(-1)); + Assert.assertThrows(IllegalArgumentException.class, () -> horizontalRuleFormat.setHeight(1585.0)); + } + + @Test + public void insertHyperlink() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertHyperlink + //ExFor:Font.ClearFormatting + //ExFor:Font.Color + //ExFor:Font.Underline + //ExFor:Underline + //ExSummary:Shows how to insert a hyperlink field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("For more information, please visit the "); + + // Insert a hyperlink and emphasize it with custom formatting. + // The hyperlink will be a clickable piece of text which will take us to the location specified in the URL. + builder.getFont().setColor(Color.BLUE); + builder.getFont().setUnderline(Underline.SINGLE); + builder.insertHyperlink("Google website", "https://www.google.com", false); + builder.getFont().clearFormatting(); + builder.writeln("."); + + // Ctrl + left clicking the link in the text in Microsoft Word will take us to the URL via a new web browser window. + doc.save(getArtifactsDir() + "DocumentBuilder.InsertHyperlink.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertHyperlink.docx"); + + FieldHyperlink hyperlink = (FieldHyperlink)doc.getRange().getFields().get(0); + Assert.assertEquals("https://www.google.com", hyperlink.getAddress()); + TestUtil.verifyWebResponseStatusCode(200, new URL(hyperlink.getAddress())); + + // This field is written as w:hyperlink element therefore field code cannot have formatting. + Run fieldCode = (Run)hyperlink.getStart().getNextSibling(); + Assert.assertEquals("HYPERLINK \"https://www.google.com\"", fieldCode.getText().trim()); + + Run fieldResult = (Run)hyperlink.getSeparator().getNextSibling(); + + Assert.assertEquals(Color.BLUE.getRGB(), fieldResult.getFont().getColor().getRGB()); + Assert.assertEquals(Underline.SINGLE, fieldResult.getFont().getUnderline()); + Assert.assertEquals("Google website", fieldResult.getText().trim()); + } + + @Test + public void pushPopFont() throws Exception { + //ExStart + //ExFor:DocumentBuilder.PushFont + //ExFor:DocumentBuilder.PopFont + //ExFor:DocumentBuilder.InsertHyperlink + //ExSummary:Shows how to use a document builder's formatting stack. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Set up font formatting, then write the text that goes before the hyperlink. + builder.getFont().setName("Arial"); + builder.getFont().setSize(24.0); + builder.write("To visit Google, hold Ctrl and click "); + + // Preserve our current formatting configuration on the stack. + builder.pushFont(); + + // Alter the builder's current formatting by applying a new style. + builder.getFont().setStyleIdentifier(StyleIdentifier.HYPERLINK); + builder.insertHyperlink("here", "http://www.google.com", false); + + Assert.assertEquals(Color.BLUE.getRGB(), builder.getFont().getColor().getRGB()); + Assert.assertEquals(Underline.SINGLE, builder.getFont().getUnderline()); + + // Restore the font formatting that we saved earlier and remove the element from the stack. + builder.popFont(); + + Assert.assertEquals(0, builder.getFont().getColor().getRGB()); + Assert.assertEquals(Underline.NONE, builder.getFont().getUnderline()); + + builder.write(". We hope you enjoyed the example."); + + doc.save(getArtifactsDir() + "DocumentBuilder.PushPopFont.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.PushPopFont.docx"); + RunCollection runs = doc.getFirstSection().getBody().getFirstParagraph().getRuns(); + + Assert.assertEquals(4, runs.getCount()); + + Assert.assertEquals("To visit Google, hold Ctrl and click", runs.get(0).getText().trim()); + Assert.assertEquals(". We hope you enjoyed the example.", runs.get(3).getText().trim()); + Assert.assertEquals(runs.get(0).getFont().getColor(), runs.get(3).getFont().getColor()); + Assert.assertEquals(runs.get(0).getFont().getUnderline(), runs.get(3).getFont().getUnderline()); + + Assert.assertEquals("here", runs.get(2).getText().trim()); + Assert.assertEquals(Color.BLUE.getRGB(), runs.get(2).getFont().getColor().getRGB()); + Assert.assertEquals(Underline.SINGLE, runs.get(2).getFont().getUnderline()); + Assert.assertNotEquals(runs.get(0).getFont().getColor(), runs.get(2).getFont().getColor()); + Assert.assertNotEquals(runs.get(0).getFont().getUnderline(), runs.get(2).getFont().getUnderline()); + } + + @Test + public void insertWatermark() throws Exception { + //ExStart + //ExFor:DocumentBuilder.MoveToHeaderFooter + //ExFor:PageSetup.PageWidth + //ExFor:PageSetup.PageHeight + //ExFor:WrapType + //ExFor:RelativeHorizontalPosition + //ExFor:RelativeVerticalPosition + //ExSummary:Shows how to insert an image, and use it as a watermark. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert the image into the header so that it will be visible on every page. + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + Shape shape = builder.insertImage(getImageDir() + "Transparent background logo.png"); + shape.setWrapType(WrapType.NONE); + shape.setBehindText(true); + + // Place the image at the center of the page. + shape.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE); + shape.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE); + shape.setLeft((builder.getPageSetup().getPageWidth() - shape.getWidth()) / 2.0); + shape.setTop((builder.getPageSetup().getPageHeight() - shape.getHeight()) / 2.0); + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertWatermark.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertWatermark.docx"); + shape = (Shape) doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.HEADER_PRIMARY).getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(400, 400, ImageType.PNG, shape); + Assert.assertEquals(WrapType.NONE, shape.getWrapType()); + Assert.assertTrue(shape.getBehindText()); + Assert.assertEquals(RelativeHorizontalPosition.PAGE, shape.getRelativeHorizontalPosition()); + Assert.assertEquals(RelativeVerticalPosition.PAGE, shape.getRelativeVerticalPosition()); + Assert.assertEquals((doc.getFirstSection().getPageSetup().getPageWidth() - shape.getWidth()) / 2.0, shape.getLeft()); + Assert.assertEquals((doc.getFirstSection().getPageSetup().getPageHeight() - shape.getHeight()) / 2.0, shape.getTop()); + } + + @Test + public void insertOleObject() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertOleObject(String, Boolean, Boolean, Stream) + //ExFor:DocumentBuilder.InsertOleObject(String, String, Boolean, Boolean, Stream) + //ExFor:DocumentBuilder.InsertOleObjectAsIcon(String, Boolean, String, String) + //ExSummary:Shows how to insert an OLE object into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // OLE objects are links to files in our local file system that can be opened by other installed applications. + // Double clicking these shapes will launch the application, and then use it to open the linked object. + // There are three ways of using the InsertOleObject method to insert these shapes and configure their appearance. + // If 'presentation' is omitted and 'asIcon' is set, this overloaded method selects + // the icon according to the file extension and uses the filename for the icon caption. + // 1 - Image taken from the local file system: + builder.insertOleObject(getMyDir() + "Spreadsheet.xlsx", false, false, new FileInputStream(getImageDir() + "Logo.jpg")); + + // If 'presentation' is omitted and 'asIcon' is set, this overloaded method selects + // the icon according to 'progId' and uses the filename for the icon caption. + // 2 - Icon based on the application that will open the object: + builder.insertOleObject(getMyDir() + "Spreadsheet.xlsx", "Excel.Sheet", false, true, new FileInputStream(getImageDir() + "Logo.jpg")); + + // If 'iconFile' and 'iconCaption' are omitted, this overloaded method selects + // the icon according to 'progId' and uses the predefined icon caption. + // 3 - Image icon that's 32 x 32 pixels or smaller from the local file system, with a custom caption: + builder.insertOleObjectAsIcon(getMyDir() + "Presentation.pptx", false, getImageDir() + "Logo icon.ico", + "Double click to view presentation!"); + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertOleObject.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertOleObject.docx"); + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(ShapeType.OLE_OBJECT, shape.getShapeType()); + Assert.assertEquals("Excel.Sheet.12", shape.getOleFormat().getProgId()); + Assert.assertEquals(".xlsx", shape.getOleFormat().getSuggestedExtension()); + + shape = (Shape) doc.getChild(NodeType.SHAPE, 1, true); + + Assert.assertEquals(ShapeType.OLE_OBJECT, shape.getShapeType()); + Assert.assertEquals("Package", shape.getOleFormat().getProgId()); + Assert.assertEquals(".xlsx", shape.getOleFormat().getSuggestedExtension()); + + shape = (Shape) doc.getChild(NodeType.SHAPE, 2, true); + + Assert.assertEquals(ShapeType.OLE_OBJECT, shape.getShapeType()); + Assert.assertEquals("PowerPoint.Show.12", shape.getOleFormat().getProgId()); + Assert.assertEquals(".pptx", shape.getOleFormat().getSuggestedExtension()); + } + + @Test + public void insertHtml() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertHtml(String) + //ExSummary:Shows how to use a document builder to insert html content into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + final String HTML = "

Paragraph right

" + + "Implicit paragraph left" + + "
Div center
" + + "

Heading 1 left.

"; + + builder.insertHtml(HTML); + + // Inserting HTML code parses the formatting of each element into equivalent document text formatting. + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + Assert.assertEquals("Paragraph right", paragraphs.get(0).getText().trim()); + Assert.assertEquals(ParagraphAlignment.RIGHT, paragraphs.get(0).getParagraphFormat().getAlignment()); + + Assert.assertEquals("Implicit paragraph left", paragraphs.get(1).getText().trim()); + Assert.assertEquals(ParagraphAlignment.LEFT, paragraphs.get(1).getParagraphFormat().getAlignment()); + Assert.assertTrue(paragraphs.get(1).getRuns().get(0).getFont().getBold()); + + Assert.assertEquals("Div center", paragraphs.get(2).getText().trim()); + Assert.assertEquals(ParagraphAlignment.CENTER, paragraphs.get(2).getParagraphFormat().getAlignment()); + + Assert.assertEquals("Heading 1 left.", paragraphs.get(3).getText().trim()); + Assert.assertEquals("Heading 1", paragraphs.get(3).getParagraphFormat().getStyle().getName()); + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertHtml.docx"); + //ExEnd + } + + @Test(dataProvider = "insertHtmlWithFormattingDataProvider") + public void insertHtmlWithFormatting(boolean useBuilderFormatting) throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertHtml(String, Boolean) + //ExSummary:Shows how to apply a document builder's formatting while inserting HTML content. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Set a text alignment for the builder, insert an HTML paragraph with a specified alignment, and one without. + builder.getParagraphFormat().setAlignment(ParagraphAlignment.DISTRIBUTED); + builder.insertHtml( + "

Paragraph 1.

" + + "

Paragraph 2.

", useBuilderFormatting); + + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + // The first paragraph has an alignment specified. When InsertHtml parses the HTML code, + // the paragraph alignment value found in the HTML code always supersedes the document builder's value. + Assert.assertEquals("Paragraph 1.", paragraphs.get(0).getText().trim()); + Assert.assertEquals(ParagraphAlignment.RIGHT, paragraphs.get(0).getParagraphFormat().getAlignment()); + + // The second paragraph has no alignment specified. It can have its alignment value filled in + // by the builder's value depending on the flag we passed to the InsertHtml method. + Assert.assertEquals("Paragraph 2.", paragraphs.get(1).getText().trim()); + Assert.assertEquals(useBuilderFormatting ? ParagraphAlignment.DISTRIBUTED : ParagraphAlignment.LEFT, + paragraphs.get(1).getParagraphFormat().getAlignment()); + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertHtmlWithFormatting.docx"); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "insertHtmlWithFormattingDataProvider") + public static Object[][] insertHtmlWithFormattingDataProvider() throws Exception { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void mathMl() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + final String mathML = + "a1+b1"; + + builder.insertHtml(mathML); + + doc.save(getArtifactsDir() + "DocumentBuilder.MathML.docx"); + doc.save(getArtifactsDir() + "DocumentBuilder.MathML.pdf"); + + Assert.assertTrue(DocumentHelper.compareDocs(getGoldsDir() + "DocumentBuilder.MathML Gold.docx", getArtifactsDir() + "DocumentBuilder.MathML.docx")); + } + + @Test + public void insertTextAndBookmark() throws Exception { + //ExStart + //ExFor:DocumentBuilder.StartBookmark + //ExFor:DocumentBuilder.EndBookmark + //ExSummary:Shows how create a bookmark. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // A valid bookmark needs to have document body text enclosed by + // BookmarkStart and BookmarkEnd nodes created with a matching bookmark name. + builder.startBookmark("MyBookmark"); + builder.writeln("Hello world!"); + builder.endBookmark("MyBookmark"); + + Assert.assertEquals(1, doc.getRange().getBookmarks().getCount()); + Assert.assertEquals("MyBookmark", doc.getRange().getBookmarks().get(0).getName()); + Assert.assertEquals("Hello world!", doc.getRange().getBookmarks().get(0).getText().trim()); + //ExEnd + } + + @Test + public void createColumnBookmark() throws Exception + { + //ExStart + //ExFor:DocumentBuilder.StartColumnBookmark + //ExFor:DocumentBuilder.EndColumnBookmark + //ExSummary:Shows how to create a column bookmark. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startTable(); + + builder.insertCell(); + // Cells 1,2,4,5 will be bookmarked. + builder.startColumnBookmark("MyBookmark_1"); + // Badly formed bookmarks or bookmarks with duplicate names will be ignored when the document is saved. + builder.startColumnBookmark("MyBookmark_1"); + builder.startColumnBookmark("BadStartBookmark"); + builder.write("Cell 1"); + + builder.insertCell(); + builder.write("Cell 2"); + + builder.insertCell(); + builder.write("Cell 3"); + + builder.endRow(); + + builder.insertCell(); + builder.write("Cell 4"); + + builder.insertCell(); + builder.write("Cell 5"); + builder.endColumnBookmark("MyBookmark_1"); + builder.endColumnBookmark("MyBookmark_1"); + + Assert.assertThrows(IllegalStateException.class, () -> builder.endColumnBookmark("BadEndBookmark")); //ExSkip + + builder.insertCell(); + builder.write("Cell 6"); + + builder.endRow(); + builder.endTable(); + + doc.save(getArtifactsDir() + "Bookmarks.CreateColumnBookmark.docx"); + //ExEnd + } + + @Test + public void createForm() throws Exception + { + //ExStart + //ExFor:TextFormFieldType + //ExFor:DocumentBuilder.InsertTextInput + //ExFor:DocumentBuilder.InsertComboBox + //ExSummary:Shows how to create form fields. + DocumentBuilder builder = new DocumentBuilder(); + + // Form fields are objects in the document that the user can interact with by being prompted to enter values. + // We can create them using a document builder, and below are two ways of doing so. + // 1 - Basic text input: + builder.insertTextInput("My text input", TextFormFieldType.REGULAR, + "", "Enter your name here", 30); + + // 2 - Combo box with prompt text, and a range of possible values: + String[] items = + { + "-- Select your favorite footwear --", "Sneakers", "Oxfords", "Flip-flops", "Other" + }; + + builder.insertParagraph(); + builder.insertComboBox("My combo box", items, 0); + + builder.getDocument().save(getArtifactsDir() + "DocumentBuilder.CreateForm.docx"); + //ExEnd + + Document doc = new Document(getArtifactsDir() + "DocumentBuilder.CreateForm.docx"); + FormField formField = doc.getRange().getFormFields().get(0); + + Assert.assertEquals("My text input", formField.getName()); + Assert.assertEquals(TextFormFieldType.REGULAR, formField.getTextInputType()); + Assert.assertEquals("Enter your name here", formField.getResult()); + + formField = doc.getRange().getFormFields().get(1); + + Assert.assertEquals("My combo box", formField.getName()); + Assert.assertEquals(TextFormFieldType.REGULAR, formField.getTextInputType()); + Assert.assertEquals("-- Select your favorite footwear --", formField.getResult()); + Assert.assertEquals(0, formField.getDropDownSelectedIndex()); + Assert.assertEquals(Arrays.asList("-- Select your favorite footwear --", "Sneakers", "Oxfords", "Flip-flops", "Other"), + formField.getDropDownItems()); + } + + @Test + public void insertCheckBox() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertCheckBox(string, bool, bool, int) + //ExFor:DocumentBuilder.InsertCheckBox(String, bool, int) + //ExSummary:Shows how to insert checkboxes into the document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert checkboxes of varying sizes and default checked statuses. + builder.write("Unchecked check box of a default size: "); + builder.insertCheckBox("", false, false, 0); + builder.insertParagraph(); + + builder.write("Large checked check box: "); + builder.insertCheckBox("CheckBox_Default", true, true, 50); + builder.insertParagraph(); + + // Form fields have a name length limit of 20 characters. + builder.write("Very large checked check box: "); + builder.insertCheckBox("CheckBox_OnlyCheckedValue", true, 100); + + Assert.assertEquals("CheckBox_OnlyChecked", doc.getRange().getFormFields().get(2).getName()); + + // We can interact with these check boxes in Microsoft Word by double clicking them. + doc.save(getArtifactsDir() + "DocumentBuilder.InsertCheckBox.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertCheckBox.docx"); + + FormFieldCollection formFields = doc.getRange().getFormFields(); + + Assert.assertEquals("", formFields.get(0).getName()); + Assert.assertEquals(false, formFields.get(0).getChecked()); + Assert.assertEquals(false, formFields.get(0).getDefault()); + Assert.assertEquals(10.0, formFields.get(0).getCheckBoxSize()); + + Assert.assertEquals("CheckBox_Default", formFields.get(1).getName()); + Assert.assertEquals(true, formFields.get(1).getChecked()); + Assert.assertEquals(true, formFields.get(1).getDefault()); + Assert.assertEquals(50.0, formFields.get(1).getCheckBoxSize()); + + Assert.assertEquals("CheckBox_OnlyChecked", formFields.get(2).getName()); + Assert.assertEquals(true, formFields.get(2).getChecked()); + Assert.assertEquals(true, formFields.get(2).getDefault()); + Assert.assertEquals(100.0, formFields.get(2).getCheckBoxSize()); + } + + @Test + public void insertCheckBoxEmptyName() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Checking that the checkbox insertion with an empty name working correctly. + builder.insertCheckBox("", true, false, 1); + builder.insertCheckBox("", false, 1); + } + + @Test + public void workingWithNodes() throws Exception { + //ExStart + //ExFor:DocumentBuilder.MoveTo(Node) + //ExFor:DocumentBuilder.MoveToBookmark(String) + //ExFor:DocumentBuilder.CurrentParagraph + //ExFor:DocumentBuilder.CurrentNode + //ExFor:DocumentBuilder.MoveToDocumentStart + //ExFor:DocumentBuilder.MoveToDocumentEnd + //ExFor:DocumentBuilder.IsAtEndOfParagraph + //ExFor:DocumentBuilder.IsAtStartOfParagraph + //ExSummary:Shows how to move a document builder's cursor to different nodes in a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a valid bookmark, an entity that consists of nodes enclosed by a bookmark start node, + // and a bookmark end node. + builder.startBookmark("MyBookmark"); + builder.write("Bookmark contents."); + builder.endBookmark("MyBookmark"); + + NodeCollection firstParagraphNodes = doc.getFirstSection().getBody().getFirstParagraph().getChildNodes(NodeType.ANY, false); + + Assert.assertEquals(NodeType.BOOKMARK_START, firstParagraphNodes.get(0).getNodeType()); + Assert.assertEquals(NodeType.RUN, firstParagraphNodes.get(1).getNodeType()); + Assert.assertEquals("Bookmark contents.", firstParagraphNodes.get(1).getText().trim()); + Assert.assertEquals(NodeType.BOOKMARK_END, firstParagraphNodes.get(2).getNodeType()); + + // The document builder's cursor is always ahead of the node that we last added with it. + // If the builder's cursor is at the end of the document, its current node will be null. + // The previous node is the bookmark end node that we last added. + // Adding new nodes with the builder will append them to the last node. + Assert.assertNull(builder.getCurrentNode()); + + // If we wish to edit a different part of the document with the builder, + // we will need to bring its cursor to the node we wish to edit. + builder.moveToBookmark("MyBookmark"); + + // Moving it to a bookmark will move it to the first node within the bookmark start and end nodes, the enclosed run. + Assert.assertEquals(firstParagraphNodes.get(1), builder.getCurrentNode()); + + // We can also move the cursor to an individual node like this. + builder.moveTo(doc.getFirstSection().getBody().getFirstParagraph().getChildNodes(NodeType.ANY, false).get(0)); + + Assert.assertEquals(NodeType.BOOKMARK_START, builder.getCurrentNode().getNodeType()); + Assert.assertEquals(doc.getFirstSection().getBody().getFirstParagraph(), builder.getCurrentParagraph()); + Assert.assertTrue(builder.isAtStartOfParagraph()); + + // We can use specific methods to move to the start/end of a document. + builder.moveToDocumentEnd(); + + Assert.assertTrue(builder.isAtEndOfParagraph()); + + builder.moveToDocumentStart(); + + Assert.assertTrue(builder.isAtStartOfParagraph()); + //ExEnd + } + + @Test + public void fillMergeFields() throws Exception { + //ExStart + //ExFor:DocumentBuilder.MoveToMergeField(String) + //ExFor:DocumentBuilder.Bold + //ExFor:DocumentBuilder.Italic + //ExSummary:Shows how to fill MERGEFIELDs with data with a document builder instead of a mail merge. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert some MERGEFIELDS, which accept data from columns of the same name in a data source during a mail merge, + // and then fill them manually. + builder.insertField(" MERGEFIELD Chairman "); + builder.insertField(" MERGEFIELD ChiefFinancialOfficer "); + builder.insertField(" MERGEFIELD ChiefTechnologyOfficer "); + + builder.moveToMergeField("Chairman"); + builder.setBold(true); + builder.writeln("John Doe"); + + builder.moveToMergeField("ChiefFinancialOfficer"); + builder.setItalic(true); + builder.writeln("Jane Doe"); + + builder.moveToMergeField("ChiefTechnologyOfficer"); + builder.setItalic(true); + builder.writeln("John Bloggs"); + + doc.save(getArtifactsDir() + "DocumentBuilder.FillMergeFields.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.FillMergeFields.docx"); + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + Assert.assertTrue(paragraphs.get(0).getRuns().get(0).getFont().getBold()); + Assert.assertEquals("John Doe", paragraphs.get(0).getRuns().get(0).getText().trim()); + + Assert.assertTrue(paragraphs.get(1).getRuns().get(0).getFont().getItalic()); + Assert.assertEquals("Jane Doe", paragraphs.get(1).getRuns().get(0).getText().trim()); + + Assert.assertTrue(paragraphs.get(2).getRuns().get(0).getFont().getItalic()); + Assert.assertEquals("John Bloggs", paragraphs.get(2).getRuns().get(0).getText().trim()); + + } + + @Test + public void insertToc() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertTableOfContents + //ExFor:Document.UpdateFields + //ExFor:DocumentBuilder.#ctor(Document) + //ExFor:ParagraphFormat.StyleIdentifier + //ExFor:DocumentBuilder.InsertBreak + //ExFor:BreakType + //ExSummary:Shows how to insert a Table of contents (TOC) into a document using heading styles as entries. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a table of contents for the first page of the document. + // Configure the table to pick up paragraphs with headings of levels 1 to 3. + // Also, set its entries to be hyperlinks that will take us + // to the location of the heading when left-clicked in Microsoft Word. + builder.insertTableOfContents("\\o \"1-3\" \\h \\z \\u"); + builder.insertBreak(BreakType.PAGE_BREAK); + + // Populate the table of contents by adding paragraphs with heading styles. + // Each such heading with a level between 1 and 3 will create an entry in the table. + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + builder.writeln("Heading 1"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); + builder.writeln("Heading 1.1"); + builder.writeln("Heading 1.2"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + builder.writeln("Heading 2"); + builder.writeln("Heading 3"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); + builder.writeln("Heading 3.1"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_3); + builder.writeln("Heading 3.1.1"); + builder.writeln("Heading 3.1.2"); + builder.writeln("Heading 3.1.3"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_4); + builder.writeln("Heading 3.1.3.1"); + builder.writeln("Heading 3.1.3.2"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); + builder.writeln("Heading 3.2"); + builder.writeln("Heading 3.3"); + + // A table of contents is a field of a type that needs to be updated to show an up-to-date result. + doc.updateFields(); + doc.save(getArtifactsDir() + "DocumentBuilder.InsertToc.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertToc.docx"); + FieldToc tableOfContents = (FieldToc) doc.getRange().getFields().get(0); + + Assert.assertEquals("1-3", tableOfContents.getHeadingLevelRange()); + Assert.assertTrue(tableOfContents.getInsertHyperlinks()); + Assert.assertTrue(tableOfContents.getHideInWebLayout()); + Assert.assertTrue(tableOfContents.getUseParagraphOutlineLevel()); + } + + @Test + public void insertTable() throws Exception { + //ExStart + //ExFor:DocumentBuilder + //ExFor:DocumentBuilder.Write(String) + //ExFor:DocumentBuilder.StartTable + //ExFor:DocumentBuilder.InsertCell + //ExFor:DocumentBuilder.EndRow + //ExFor:DocumentBuilder.EndTable + //ExFor:DocumentBuilder.CellFormat + //ExFor:DocumentBuilder.RowFormat + //ExFor:CellFormat + //ExFor:CellFormat.FitText + //ExFor:CellFormat.Width + //ExFor:CellFormat.VerticalAlignment + //ExFor:CellFormat.Shading + //ExFor:CellFormat.Orientation + //ExFor:CellFormat.WrapText + //ExFor:RowFormat + //ExFor:RowFormat.Borders + //ExFor:RowFormat.ClearFormatting + //ExFor:Shading.ClearFormatting + //ExSummary:Shows how to build a table with custom borders. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startTable(); + + // Setting table formatting options for a document builder + // will apply them to every row and cell that we add with it. + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + + builder.getCellFormat().clearFormatting(); + builder.getCellFormat().setWidth(150.0); + builder.getCellFormat().setVerticalAlignment(CellVerticalAlignment.CENTER); + builder.getCellFormat().getShading().setBackgroundPatternColor(Color.GREEN); + builder.getCellFormat().setWrapText(false); + builder.getCellFormat().setFitText(true); + + builder.getRowFormat().clearFormatting(); + builder.getRowFormat().setHeightRule(HeightRule.EXACTLY); + builder.getRowFormat().setHeight(50.0); + builder.getRowFormat().getBorders().setLineStyle(LineStyle.ENGRAVE_3_D); + builder.getRowFormat().getBorders().setColor(Color.ORANGE); + + builder.insertCell(); + builder.write("Row 1, Col 1"); + + builder.insertCell(); + builder.write("Row 1, Col 2"); + builder.endRow(); + + // Changing the formatting will apply it to the current cell, + // and any new cells that we create with the builder afterward. + // This will not affect the cells that we have added previously. + builder.getCellFormat().getShading().clearFormatting(); + + builder.insertCell(); + builder.write("Row 2, Col 1"); + + builder.insertCell(); + builder.write("Row 2, Col 2"); + + builder.endRow(); + + // Increase row height to fit the vertical text. + builder.insertCell(); + builder.getRowFormat().setHeight(150.0); + builder.getCellFormat().setOrientation(TextOrientation.UPWARD); + builder.write("Row 3, Col 1"); + + builder.insertCell(); + builder.getCellFormat().setOrientation(TextOrientation.DOWNWARD); + builder.write("Row 3, Col 2"); + + builder.endRow(); + builder.endTable(); + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertTable.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertTable.docx"); + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + Assert.assertEquals("Row 1, Col 1", table.getRows().get(0).getCells().get(0).getText().trim()); + Assert.assertEquals("Row 1, Col 2", table.getRows().get(0).getCells().get(1).getText().trim()); + Assert.assertEquals(HeightRule.EXACTLY, table.getRows().get(0).getRowFormat().getHeightRule()); + Assert.assertEquals(50.0d, table.getRows().get(0).getRowFormat().getHeight()); + Assert.assertEquals(LineStyle.ENGRAVE_3_D, table.getRows().get(0).getRowFormat().getBorders().getLineStyle()); + Assert.assertEquals(Color.ORANGE.getRGB(), table.getRows().get(0).getRowFormat().getBorders().getColor().getRGB()); + + for (Cell c : table.getRows().get(0).getCells()) { + Assert.assertEquals(150.0, c.getCellFormat().getWidth()); + Assert.assertEquals(CellVerticalAlignment.CENTER, c.getCellFormat().getVerticalAlignment()); + Assert.assertEquals(Color.GREEN.getRGB(), c.getCellFormat().getShading().getBackgroundPatternColor().getRGB()); + Assert.assertFalse(c.getCellFormat().getWrapText()); + Assert.assertTrue(c.getCellFormat().getFitText()); + + Assert.assertEquals(ParagraphAlignment.CENTER, c.getFirstParagraph().getParagraphFormat().getAlignment()); + } + + Assert.assertEquals("Row 2, Col 1", table.getRows().get(1).getCells().get(0).getText().trim()); + Assert.assertEquals("Row 2, Col 2", table.getRows().get(1).getCells().get(1).getText().trim()); + + + for (Cell c : table.getRows().get(1).getCells()) { + Assert.assertEquals(150.0, c.getCellFormat().getWidth()); + Assert.assertEquals(CellVerticalAlignment.CENTER, c.getCellFormat().getVerticalAlignment()); + Assert.assertEquals(0, c.getCellFormat().getShading().getBackgroundPatternColor().getRGB()); + Assert.assertFalse(c.getCellFormat().getWrapText()); + Assert.assertTrue(c.getCellFormat().getFitText()); + + Assert.assertEquals(ParagraphAlignment.CENTER, c.getFirstParagraph().getParagraphFormat().getAlignment()); + } + + Assert.assertEquals(150.0, table.getRows().get(2).getRowFormat().getHeight()); + + Assert.assertEquals("Row 3, Col 1", table.getRows().get(2).getCells().get(0).getText().trim()); + Assert.assertEquals(TextOrientation.UPWARD, table.getRows().get(2).getCells().get(0).getCellFormat().getOrientation()); + Assert.assertEquals(ParagraphAlignment.CENTER, table.getRows().get(2).getCells().get(0).getFirstParagraph().getParagraphFormat().getAlignment()); + + Assert.assertEquals("Row 3, Col 2", table.getRows().get(2).getCells().get(1).getText().trim()); + Assert.assertEquals(TextOrientation.DOWNWARD, table.getRows().get(2).getCells().get(1).getCellFormat().getOrientation()); + Assert.assertEquals(ParagraphAlignment.CENTER, table.getRows().get(2).getCells().get(1).getFirstParagraph().getParagraphFormat().getAlignment()); + } + + @Test + public void insertTableWithStyle() throws Exception { + //ExStart + //ExFor:Table.StyleIdentifier + //ExFor:Table.StyleOptions + //ExFor:TableStyleOptions + //ExFor:Table.AutoFit + //ExFor:AutoFitBehavior + //ExSummary:Shows how to build a new table while applying a style. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + Table table = builder.startTable(); + + // We must insert at least one row before setting any table formatting. + builder.insertCell(); + + // Set the table style used based on the style identifier. + // Note that not all table styles are available when saving to .doc format. + table.setStyleIdentifier(StyleIdentifier.MEDIUM_SHADING_1_ACCENT_1); + + // Partially apply the style to features of the table based on predicates, then build the table. + table.setStyleOptions(TableStyleOptions.FIRST_COLUMN | TableStyleOptions.ROW_BANDS | TableStyleOptions.FIRST_ROW); + table.autoFit(AutoFitBehavior.AUTO_FIT_TO_CONTENTS); + + builder.writeln("Item"); + builder.getCellFormat().setRightPadding(40.0); + builder.insertCell(); + builder.writeln("Quantity (kg)"); + builder.endRow(); + + builder.insertCell(); + builder.writeln("Apples"); + builder.insertCell(); + builder.writeln("20"); + builder.endRow(); + + builder.insertCell(); + builder.writeln("Bananas"); + builder.insertCell(); + builder.writeln("40"); + builder.endRow(); + + builder.insertCell(); + builder.writeln("Carrots"); + builder.insertCell(); + builder.writeln("50"); + builder.endRow(); + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertTableWithStyle.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertTableWithStyle.docx"); + + doc.expandTableStylesToDirectFormatting(); + + Assert.assertEquals("Medium Shading 1 Accent 1", table.getStyle().getName()); + Assert.assertEquals(TableStyleOptions.FIRST_COLUMN | TableStyleOptions.ROW_BANDS | TableStyleOptions.FIRST_ROW, + table.getStyleOptions()); + Assert.assertEquals(189, (table.getFirstRow().getFirstCell().getCellFormat().getShading().getBackgroundPatternColor().getBlue() & 0xFF)); + Assert.assertEquals(Color.WHITE.getRGB(), table.getFirstRow().getFirstCell().getFirstParagraph().getRuns().get(0).getFont().getColor().getRGB()); + Assert.assertNotEquals(Color.BLUE.getRGB(), + (table.getLastRow().getFirstCell().getCellFormat().getShading().getBackgroundPatternColor().getBlue() & 0xFF)); + Assert.assertEquals(0, table.getLastRow().getFirstCell().getFirstParagraph().getRuns().get(0).getFont().getColor().getRGB()); + } + + @Test + public void insertTableSetHeadingRow() throws Exception { + //ExStart + //ExFor:RowFormat.HeadingFormat + //ExSummary:Shows how to build a table with rows that repeat on every page. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + + // Any rows inserted while the "HeadingFormat" flag is set to "true" + // will show up at the top of the table on every page that it spans. + builder.getRowFormat().setHeadingFormat(true); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.getCellFormat().setWidth(100.0); + builder.insertCell(); + builder.write("Heading row 1"); + builder.endRow(); + builder.insertCell(); + builder.write("Heading row 2"); + builder.endRow(); + + builder.getCellFormat().setWidth(50.0); + builder.getParagraphFormat().clearFormatting(); + builder.getRowFormat().setHeadingFormat(false); + + // Add enough rows for the table to span two pages. + for (int i = 0; i < 50; i++) { + builder.insertCell(); + builder.write(MessageFormat.format("Row {0}, column 1.", table.getRows().toArray().length)); + builder.insertCell(); + builder.write(MessageFormat.format("Row {0}, column 2.", table.getRows().toArray().length)); + builder.endRow(); + } + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertTableSetHeadingRow.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertTableSetHeadingRow.docx"); + table = doc.getFirstSection().getBody().getTables().get(0); + + for (int i = 0; i < table.getRows().getCount(); i++) + Assert.assertEquals(i < 2, table.getRows().get(i).getRowFormat().getHeadingFormat()); + } + + @Test + public void insertTableWithPreferredWidth() throws Exception { + //ExStart + //ExFor:Table.PreferredWidth + //ExFor:PreferredWidth.FromPercent + //ExFor:PreferredWidth + //ExSummary:Shows how to set a table to auto fit to 50% of the width of the page. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + builder.write("Cell #1"); + builder.insertCell(); + builder.write("Cell #2"); + builder.insertCell(); + builder.write("Cell #3"); + + table.setPreferredWidth(PreferredWidth.fromPercent(50.0)); + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertTableWithPreferredWidth.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertTableWithPreferredWidth.docx"); + table = doc.getFirstSection().getBody().getTables().get(0); + + Assert.assertEquals(PreferredWidthType.PERCENT, table.getPreferredWidth().getType()); + Assert.assertEquals(50.0, table.getPreferredWidth().getValue()); + } + + @Test + public void insertCellsWithPreferredWidths() throws Exception { + //ExStart + //ExFor:CellFormat.PreferredWidth + //ExFor:PreferredWidth + //ExFor:PreferredWidth.Auto + //ExFor:PreferredWidth.Equals(PreferredWidth) + //ExFor:PreferredWidth.Equals(Object) + //ExFor:PreferredWidth.FromPoints + //ExFor:PreferredWidth.FromPercent + //ExFor:PreferredWidth.GetHashCode + //ExFor:PreferredWidth.ToString + //ExSummary:Shows how to set a preferred width for table cells. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + Table table = builder.startTable(); + + // There are two ways of applying the "PreferredWidth" class to table cells. + // 1 - Set an absolute preferred width based on points: + builder.insertCell(); + builder.getCellFormat().setPreferredWidth(PreferredWidth.fromPoints(40.0)); + builder.getCellFormat().getShading().setBackgroundPatternColor(Color.YELLOW); + builder.writeln(MessageFormat.format("Cell with a width of {0}.", builder.getCellFormat().getPreferredWidth())); + + // 2 - Set a relative preferred width based on percent of the table's width: + builder.insertCell(); + builder.getCellFormat().setPreferredWidth(PreferredWidth.fromPercent(20.0)); + builder.getCellFormat().getShading().setBackgroundPatternColor(Color.BLUE); + builder.writeln(MessageFormat.format("Cell with a width of {0}.", builder.getCellFormat().getPreferredWidth())); + + builder.insertCell(); + + // A cell with no preferred width specified will take up the rest of the available space. + builder.getCellFormat().setPreferredWidth(PreferredWidth.AUTO); + + // Each configuration of the "PreferredWidth" property creates a new object. + Assert.assertNotEquals(table.getFirstRow().getCells().get(1).getCellFormat().getPreferredWidth().hashCode(), + builder.getCellFormat().getPreferredWidth().hashCode()); + + builder.getCellFormat().getShading().setBackgroundPatternColor(Color.GREEN); + builder.writeln("Automatically sized cell."); + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertCellsWithPreferredWidths.docx"); + //ExEnd + + Assert.assertEquals(100.0d, PreferredWidth.fromPercent(100.0).getValue()); + Assert.assertEquals(100.0d, PreferredWidth.fromPoints(100.0).getValue()); + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertCellsWithPreferredWidths.docx"); + table = doc.getFirstSection().getBody().getTables().get(0); + + Assert.assertEquals(PreferredWidthType.POINTS, table.getFirstRow().getCells().get(0).getCellFormat().getPreferredWidth().getType()); + Assert.assertEquals(40.0d, table.getFirstRow().getCells().get(0).getCellFormat().getPreferredWidth().getValue()); + Assert.assertEquals("Cell with a width of 800.", table.getFirstRow().getCells().get(0).getText().trim()); + + Assert.assertEquals(PreferredWidthType.PERCENT, table.getFirstRow().getCells().get(1).getCellFormat().getPreferredWidth().getType()); + Assert.assertEquals(20.0d, table.getFirstRow().getCells().get(1).getCellFormat().getPreferredWidth().getValue()); + Assert.assertEquals("Cell with a width of 20%.", table.getFirstRow().getCells().get(1).getText().trim()); + + Assert.assertEquals(PreferredWidthType.AUTO, table.getFirstRow().getCells().get(2).getCellFormat().getPreferredWidth().getType()); + Assert.assertEquals(0.0d, table.getFirstRow().getCells().get(2).getCellFormat().getPreferredWidth().getValue()); + Assert.assertEquals("Automatically sized cell.", table.getFirstRow().getCells().get(2).getText().trim()); + } + + @Test + public void insertTableFromHtml() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert the table from HTML. Note that AutoFitSettings does not apply to tables + // inserted from HTML. + builder.insertHtml("" + "" + "" + "" + "" + + "" + "" + "" + "" + "
Row 1, Cell 1Row 1, Cell 2
Row 2, Cell 2Row 2, Cell 2
"); + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertTableFromHtml.docx"); + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertTableFromHtml.docx"); + + Assert.assertEquals(1, doc.getChildNodes(NodeType.TABLE, true).getCount()); + Assert.assertEquals(2, doc.getChildNodes(NodeType.ROW, true).getCount()); + Assert.assertEquals(4, doc.getChildNodes(NodeType.CELL, true).getCount()); + } + + @Test + public void insertNestedTable() throws Exception { + //ExStart + //ExFor:Cell.FirstParagraph + //ExSummary:Shows how to create a nested table using a document builder. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Build the outer table. + Cell cell = builder.insertCell(); + builder.writeln("Outer Table Cell 1"); + builder.insertCell(); + builder.writeln("Outer Table Cell 2"); + builder.endTable(); + + // Move to the first cell of the outer table, the build another table inside the cell. + builder.moveTo(cell.getFirstParagraph()); + builder.insertCell(); + builder.writeln("Inner Table Cell 1"); + builder.insertCell(); + builder.writeln("Inner Table Cell 2"); + builder.endTable(); + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertNestedTable.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertNestedTable.docx"); + + Assert.assertEquals(2, doc.getChildNodes(NodeType.TABLE, true).getCount()); + Assert.assertEquals(4, doc.getChildNodes(NodeType.CELL, true).getCount()); + Assert.assertEquals(1, cell.getTables().get(0).getCount()); + Assert.assertEquals(2, cell.getTables().get(0).getFirstRow().getCells().getCount()); + } + + @Test + public void createTable() throws Exception { + //ExStart + //ExFor:DocumentBuilder + //ExFor:DocumentBuilder.Write(String) + //ExFor:DocumentBuilder.InsertCell + //ExSummary:Shows how to use a document builder to create a table. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Start the table, then populate the first row with two cells. + builder.startTable(); + builder.insertCell(); + builder.write("Row 1, Cell 1."); + builder.insertCell(); + builder.write("Row 1, Cell 2."); + + // Call the builder's "EndRow" method to start a new row. + builder.endRow(); + builder.insertCell(); + builder.write("Row 2, Cell 1."); + builder.insertCell(); + builder.write("Row 2, Cell 2."); + builder.endTable(); + + doc.save(getArtifactsDir() + "DocumentBuilder.CreateTable.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.CreateTable.docx"); + Table table = doc.getFirstSection().getBody().getTables().get(0); + + Assert.assertEquals(4, table.getChildNodes(NodeType.CELL, true).getCount()); + + Assert.assertEquals("Row 1, Cell 1.", table.getRows().get(0).getCells().get(0).getText().trim()); + Assert.assertEquals("Row 1, Cell 2.", table.getRows().get(0).getCells().get(1).getText().trim()); + Assert.assertEquals("Row 2, Cell 1.", table.getRows().get(1).getCells().get(0).getText().trim()); + Assert.assertEquals("Row 2, Cell 2.", table.getRows().get(1).getCells().get(1).getText().trim()); + } + + @Test + public void buildFormattedTable() throws Exception { + //ExStart + //ExFor:RowFormat.Height + //ExFor:RowFormat.HeightRule + //ExFor:Table.LeftIndent + //ExFor:DocumentBuilder.ParagraphFormat + //ExFor:DocumentBuilder.Font + //ExSummary:Shows how to create a formatted table using DocumentBuilder. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + table.setLeftIndent(20.0); + + // Set some formatting options for text and table appearance. + builder.getRowFormat().setHeight(40.0); + builder.getRowFormat().setHeightRule(HeightRule.AT_LEAST); + builder.getCellFormat().getShading().setBackgroundPatternColor(new Color((198), (217), (241))); + + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.getFont().setSize(16.0); + builder.getFont().setName("Arial"); + builder.getFont().setBold(true); + + // Configuring the formatting options in a document builder will apply them + // to the current cell/row its cursor is in, + // as well as any new cells and rows created using that builder. + builder.write("Header Row,\n Cell 1"); + builder.insertCell(); + builder.write("Header Row,\n Cell 2"); + builder.insertCell(); + builder.write("Header Row,\n Cell 3"); + builder.endRow(); + + // Reconfigure the builder's formatting objects for new rows and cells that we are about to make. + // The builder will not apply these to the first row already created so that it will stand out as a header row. + builder.getCellFormat().getShading().setBackgroundPatternColor(Color.WHITE); + builder.getCellFormat().setVerticalAlignment(CellVerticalAlignment.CENTER); + builder.getRowFormat().setHeight(30.0); + builder.getRowFormat().setHeightRule(HeightRule.AUTO); + builder.insertCell(); + builder.getFont().setSize(12.0); + builder.getFont().setBold(false); + + builder.write("Row 1, Cell 1."); + builder.insertCell(); + builder.write("Row 1, Cell 2."); + builder.insertCell(); + builder.write("Row 1, Cell 3."); + builder.endRow(); + builder.insertCell(); + builder.write("Row 2, Cell 1."); + builder.insertCell(); + builder.write("Row 2, Cell 2."); + builder.insertCell(); + builder.write("Row 2, Cell 3."); + builder.endRow(); + builder.endTable(); + + doc.save(getArtifactsDir() + "DocumentBuilder.CreateFormattedTable.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.CreateFormattedTable.docx"); + table = doc.getFirstSection().getBody().getTables().get(0); + + Assert.assertEquals(20.0d, table.getLeftIndent()); + + Assert.assertEquals(HeightRule.AT_LEAST, table.getRows().get(0).getRowFormat().getHeightRule()); + Assert.assertEquals(40.0d, table.getRows().get(0).getRowFormat().getHeight()); + + for (Cell c : (Iterable) doc.getChildNodes(NodeType.CELL, true)) { + Assert.assertEquals(ParagraphAlignment.CENTER, c.getFirstParagraph().getParagraphFormat().getAlignment()); + + for (Run r : c.getFirstParagraph().getRuns()) { + Assert.assertEquals("Arial", r.getFont().getName()); + + if (c.getParentRow() == table.getFirstRow()) { + Assert.assertEquals(16.0, r.getFont().getSize()); + Assert.assertTrue(r.getFont().getBold()); + } else { + Assert.assertEquals(12.0, r.getFont().getSize()); + Assert.assertFalse(r.getFont().getBold()); + } + } + } + } + + @Test + public void tableBordersAndShading() throws Exception { + //ExStart + //ExFor:Shading + //ExFor:Table.SetBorders + //ExFor:BorderCollection.Left + //ExFor:BorderCollection.Right + //ExFor:BorderCollection.Top + //ExFor:BorderCollection.Bottom + //ExSummary:Shows how to apply border and shading color while building a table. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Start a table and set a default color/thickness for its borders. + Table table = builder.startTable(); + table.setBorders(LineStyle.SINGLE, 2.0, Color.BLACK); + + // Create a row with two cells with different background colors. + builder.insertCell(); + builder.getCellFormat().getShading().setBackgroundPatternColor(Color.RED); + builder.writeln("Row 1, Cell 1."); + builder.insertCell(); + builder.getCellFormat().getShading().setBackgroundPatternColor(Color.GREEN); + builder.writeln("Row 1, Cell 2."); + builder.endRow(); + + // Reset cell formatting to disable the background colors + // set a custom border thickness for all new cells created by the builder, + // then build a second row. + builder.getCellFormat().clearFormatting(); + builder.getCellFormat().getBorders().getLeft().setLineWidth(4.0); + builder.getCellFormat().getBorders().getRight().setLineWidth(4.0); + builder.getCellFormat().getBorders().getTop().setLineWidth(4.0); + builder.getCellFormat().getBorders().getBottom().setLineWidth(4.0); + + builder.insertCell(); + builder.writeln("Row 2, Cell 1."); + builder.insertCell(); + builder.writeln("Row 2, Cell 2."); + + doc.save(getArtifactsDir() + "DocumentBuilder.TableBordersAndShading.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.TableBordersAndShading.docx"); + table = doc.getFirstSection().getBody().getTables().get(0); + + for (Cell c : table.getFirstRow()) { + Assert.assertEquals(0.5d, c.getCellFormat().getBorders().getTop().getLineWidth()); + Assert.assertEquals(0.5d, c.getCellFormat().getBorders().getBottom().getLineWidth()); + Assert.assertEquals(0.5d, c.getCellFormat().getBorders().getLeft().getLineWidth()); + Assert.assertEquals(0.5d, c.getCellFormat().getBorders().getRight().getLineWidth()); + + Assert.assertEquals(0, c.getCellFormat().getBorders().getLeft().getColor().getRGB()); + Assert.assertEquals(LineStyle.SINGLE, c.getCellFormat().getBorders().getLeft().getLineStyle()); + } + + Assert.assertEquals(Color.RED.getRGB(), + table.getFirstRow().getFirstCell().getCellFormat().getShading().getBackgroundPatternColor().getRGB()); + Assert.assertEquals(Color.GREEN.getRGB(), + table.getFirstRow().getCells().get(1).getCellFormat().getShading().getBackgroundPatternColor().getRGB()); + + for (Cell c : table.getLastRow()) { + Assert.assertEquals(4.0d, c.getCellFormat().getBorders().getTop().getLineWidth()); + Assert.assertEquals(4.0d, c.getCellFormat().getBorders().getBottom().getLineWidth()); + Assert.assertEquals(4.0d, c.getCellFormat().getBorders().getLeft().getLineWidth()); + Assert.assertEquals(4.0d, c.getCellFormat().getBorders().getRight().getLineWidth()); + + Assert.assertEquals(0, c.getCellFormat().getBorders().getLeft().getColor().getRGB()); + Assert.assertEquals(LineStyle.SINGLE, c.getCellFormat().getBorders().getLeft().getLineStyle()); + Assert.assertEquals(0, c.getCellFormat().getShading().getBackgroundPatternColor().getRGB()); + } + } + + @Test + public void setPreferredTypeConvertUtil() throws Exception { + //ExStart + //ExFor:PreferredWidth.FromPoints + //ExSummary:Shows how to use unit conversion tools while specifying a preferred width for a cell. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.getCellFormat().setPreferredWidth(PreferredWidth.fromPoints(ConvertUtil.inchToPoint(3.0))); + builder.insertCell(); + + Assert.assertEquals(216.0d, table.getFirstRow().getFirstCell().getCellFormat().getPreferredWidth().getValue()); + //ExEnd + } + + @Test + public void insertHyperlinkToLocalBookmark() throws Exception { + //ExStart + //ExFor:DocumentBuilder.StartBookmark + //ExFor:DocumentBuilder.EndBookmark + //ExFor:DocumentBuilder.InsertHyperlink + //ExSummary:Shows how to insert a hyperlink which references a local bookmark. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startBookmark("Bookmark1"); + builder.write("Bookmarked text. "); + builder.endBookmark("Bookmark1"); + builder.writeln("Text outside of the bookmark."); + + // Insert a HYPERLINK field that links to the bookmark. We can pass field switches + // to the "InsertHyperlink" method as part of the argument containing the referenced bookmark's name. + builder.getFont().setColor(Color.BLUE); + builder.getFont().setUnderline(Underline.SINGLE); + FieldHyperlink hyperlink = (FieldHyperlink)builder.insertHyperlink("Link to Bookmark1", "Bookmark1", true); + hyperlink.setScreenTip("Hyperlink Tip"); + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertHyperlinkToLocalBookmark.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertHyperlinkToLocalBookmark.docx"); + hyperlink = (FieldHyperlink)doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_HYPERLINK, " HYPERLINK \\l \"Bookmark1\" \\o \"Hyperlink Tip\" ", "Link to Bookmark1", hyperlink); + Assert.assertEquals("Bookmark1", hyperlink.getSubAddress()); + Assert.assertEquals("Hyperlink Tip", hyperlink.getScreenTip()); + Assert.assertTrue(IterableUtils.matchesAny(doc.getRange().getBookmarks(), b -> b.getName().contains("Bookmark1"))); + } + + @Test + public void cursorPosition() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.write("Hello world!"); + + // If the builder's cursor is at the end of the document, + // there will be no nodes in front of it so that the current node will be null. + Assert.assertNull(builder.getCurrentNode()); + + Assert.assertEquals("Hello world!", builder.getCurrentParagraph().getText().trim()); + + // Move to the beginning of the document and place the cursor at an existing node. + builder.moveToDocumentStart(); + Assert.assertEquals(NodeType.RUN, builder.getCurrentNode().getNodeType()); + } + + @Test + public void moveTo() throws Exception { + //ExStart + //ExFor:Story.LastParagraph + //ExFor:DocumentBuilder.MoveTo(Node) + //ExSummary:Shows how to move a DocumentBuilder's cursor position to a specified node. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Run 1. "); + + // The document builder has a cursor, which acts as the part of the document + // where the builder appends new nodes when we use its document construction methods. + // This cursor functions in the same way as Microsoft Word's blinking cursor, + // and it also always ends up immediately after any node that the builder just inserted. + // To append content to a different part of the document, + // we can move the cursor to a different node with the "MoveTo" method. + Assert.assertEquals(doc.getFirstSection().getBody().getLastParagraph(), builder.getCurrentParagraph()); //ExSkip + builder.moveTo(doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0)); + Assert.assertEquals(doc.getFirstSection().getBody().getFirstParagraph(), builder.getCurrentParagraph()); //ExSkip + + // The cursor is now in front of the node that we moved it to. + // Adding a second run will insert it in front of the first run. + builder.writeln("Run 2. "); + + Assert.assertEquals("Run 2. \rRun 1.", doc.getText().trim()); + + // Move the cursor to the end of the document to continue appending text to the end as before. + builder.moveTo(doc.getLastSection().getBody().getLastParagraph()); + builder.writeln("Run 3. "); + + Assert.assertEquals("Run 2. \rRun 1. \rRun 3.", doc.getText().trim()); + Assert.assertEquals(doc.getFirstSection().getBody().getLastParagraph(), builder.getCurrentParagraph()); //ExSkip + + //ExEnd + } + + @Test + public void moveToParagraph() throws Exception { + //ExStart + //ExFor:DocumentBuilder.MoveToParagraph + //ExSummary:Shows how to move a builder's cursor position to a specified paragraph. + Document doc = new Document(getMyDir() + "Paragraphs.docx"); + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + Assert.assertEquals(22, paragraphs.getCount()); + + // Create document builder to edit the document. The builder's cursor, + // which is the point where it will insert new nodes when we call its document construction methods, + // is currently at the beginning of the document. + DocumentBuilder builder = new DocumentBuilder(doc); + + Assert.assertEquals(0, paragraphs.indexOf(builder.getCurrentParagraph())); + + // Move that cursor to a different paragraph will place that cursor in front of that paragraph. + builder.moveToParagraph(2, 0); + Assert.assertEquals(2, paragraphs.indexOf(builder.getCurrentParagraph())); //ExSkip + + // Any new content that we add will be inserted at that point. + builder.writeln("This is a new third paragraph. "); + //ExEnd + + Assert.assertEquals(3, paragraphs.indexOf(builder.getCurrentParagraph())); + + doc = DocumentHelper.saveOpen(doc); + + Assert.assertEquals("This is a new third paragraph.", doc.getFirstSection().getBody().getParagraphs().get(2).getText().trim()); + } + + @Test + public void moveToCell() throws Exception { + //ExStart + //ExFor:DocumentBuilder.MoveToCell + //ExSummary:Shows how to move a document builder's cursor to a cell in a table. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create an empty 2x2 table. + builder.startTable(); + builder.insertCell(); + builder.insertCell(); + builder.endRow(); + builder.insertCell(); + builder.insertCell(); + builder.endTable(); + + // Because we have ended the table with the EndTable method, + // the document builder's cursor is currently outside the table. + // This cursor has the same function as Microsoft Word's blinking text cursor. + // It can also be moved to a different location in the document using the builder's MoveTo methods. + // We can move the cursor back inside the table to a specific cell. + builder.moveToCell(0, 1, 1, 0); + builder.write("Column 2, cell 2."); + + doc.save(getArtifactsDir() + "DocumentBuilder.MoveToCell.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.MoveToCell.docx"); + + Table table = doc.getFirstSection().getBody().getTables().get(0); + + Assert.assertEquals("Column 2, cell 2.", table.getRows().get(1).getCells().get(1).getText().trim()); + } + + @Test + public void moveToBookmark() throws Exception { + //ExStart + //ExFor:DocumentBuilder.MoveToBookmark(String, Boolean, Boolean) + //ExSummary:Shows how to move a document builder's node insertion point cursor to a bookmark. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // A valid bookmark consists of a BookmarkStart node, a BookmarkEnd node with a + // matching bookmark name somewhere afterward, and contents enclosed by those nodes. + builder.startBookmark("MyBookmark"); + builder.write("Hello world! "); + builder.endBookmark("MyBookmark"); + + // There are 4 ways of moving a document builder's cursor to a bookmark. + // If we are between the BookmarkStart and BookmarkEnd nodes, the cursor will be inside the bookmark. + // This means that any text added by the builder will become a part of the bookmark. + // 1 - Outside of the bookmark, in front of the BookmarkStart node: + Assert.assertTrue(builder.moveToBookmark("MyBookmark", true, false)); + builder.write("1. "); + + Assert.assertEquals("Hello world! ", doc.getRange().getBookmarks().get("MyBookmark").getText()); + Assert.assertEquals("1. Hello world!", doc.getText().trim()); + + // 2 - Inside the bookmark, right after the BookmarkStart node: + Assert.assertTrue(builder.moveToBookmark("MyBookmark", true, true)); + builder.write("2. "); + + Assert.assertEquals("2. Hello world! ", doc.getRange().getBookmarks().get("MyBookmark").getText()); + Assert.assertEquals("1. 2. Hello world!", doc.getText().trim()); + + // 2 - Inside the bookmark, right in front of the BookmarkEnd node: + Assert.assertTrue(builder.moveToBookmark("MyBookmark", false, false)); + builder.write("3. "); + + Assert.assertEquals("2. Hello world! 3. ", doc.getRange().getBookmarks().get("MyBookmark").getText()); + Assert.assertEquals("1. 2. Hello world! 3.", doc.getText().trim()); + + // 4 - Outside of the bookmark, after the BookmarkEnd node: + Assert.assertTrue(builder.moveToBookmark("MyBookmark", false, true)); + builder.write("4."); + + Assert.assertEquals("2. Hello world! 3. ", doc.getRange().getBookmarks().get("MyBookmark").getText()); + Assert.assertEquals("1. 2. Hello world! 3. 4.", doc.getText().trim()); + //ExEnd + } + + @Test + public void buildTable() throws Exception { + //ExStart + //ExFor:Table + //ExFor:DocumentBuilder.StartTable + //ExFor:DocumentBuilder.EndRow + //ExFor:DocumentBuilder.EndTable + //ExFor:DocumentBuilder.CellFormat + //ExFor:DocumentBuilder.RowFormat + //ExFor:DocumentBuilder.Write(String) + //ExFor:DocumentBuilder.Writeln(String) + //ExFor:CellVerticalAlignment + //ExFor:CellFormat.Orientation + //ExFor:TextOrientation + //ExFor:AutoFitBehavior + //ExSummary:Shows how to build a formatted 2x2 table. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + builder.getCellFormat().setVerticalAlignment(CellVerticalAlignment.CENTER); + builder.write("Row 1, cell 1."); + builder.insertCell(); + builder.write("Row 1, cell 2."); + builder.endRow(); + + // While building the table, the document builder will apply its current RowFormat/CellFormat property values + // to the current row/cell that its cursor is in and any new rows/cells as it creates them. + Assert.assertEquals(CellVerticalAlignment.CENTER, table.getRows().get(0).getCells().get(0).getCellFormat().getVerticalAlignment()); + Assert.assertEquals(CellVerticalAlignment.CENTER, table.getRows().get(0).getCells().get(1).getCellFormat().getVerticalAlignment()); + + builder.insertCell(); + builder.getRowFormat().setHeight(100.0); + builder.getRowFormat().setHeightRule(HeightRule.EXACTLY); + builder.getCellFormat().setOrientation(TextOrientation.UPWARD); + builder.write("Row 2, cell 1."); + builder.insertCell(); + builder.getCellFormat().setOrientation(TextOrientation.DOWNWARD); + builder.write("Row 2, cell 2."); + builder.endRow(); + builder.endTable(); + + // Previously added rows and cells are not retroactively affected by changes to the builder's formatting. + Assert.assertEquals(0.0, table.getRows().get(0).getRowFormat().getHeight()); + Assert.assertEquals(HeightRule.AUTO, table.getRows().get(0).getRowFormat().getHeightRule()); + Assert.assertEquals(100.0, table.getRows().get(1).getRowFormat().getHeight()); + Assert.assertEquals(HeightRule.EXACTLY, table.getRows().get(1).getRowFormat().getHeightRule()); + Assert.assertEquals(TextOrientation.UPWARD, table.getRows().get(1).getCells().get(0).getCellFormat().getOrientation()); + Assert.assertEquals(TextOrientation.DOWNWARD, table.getRows().get(1).getCells().get(1).getCellFormat().getOrientation()); + + doc.save(getArtifactsDir() + "DocumentBuilder.BuildTable.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.BuildTable.docx"); + table = doc.getFirstSection().getBody().getTables().get(0); + + Assert.assertEquals(2, table.getRows().getCount()); + Assert.assertEquals(2, table.getRows().get(0).getCells().getCount()); + Assert.assertEquals(2, table.getRows().get(1).getCells().getCount()); + + Assert.assertEquals(0.0, table.getRows().get(0).getRowFormat().getHeight()); + Assert.assertEquals(HeightRule.AUTO, table.getRows().get(0).getRowFormat().getHeightRule()); + Assert.assertEquals(100.0, table.getRows().get(1).getRowFormat().getHeight()); + Assert.assertEquals(HeightRule.EXACTLY, table.getRows().get(1).getRowFormat().getHeightRule()); + + Assert.assertEquals("Row 1, cell 1.", table.getRows().get(0).getCells().get(0).getText().trim()); + Assert.assertEquals(CellVerticalAlignment.CENTER, table.getRows().get(0).getCells().get(0).getCellFormat().getVerticalAlignment()); + + Assert.assertEquals("Row 1, cell 2.", table.getRows().get(0).getCells().get(1).getText().trim()); + + Assert.assertEquals("Row 2, cell 1.", table.getRows().get(1).getCells().get(0).getText().trim()); + Assert.assertEquals(TextOrientation.UPWARD, table.getRows().get(1).getCells().get(0).getCellFormat().getOrientation()); + + Assert.assertEquals("Row 2, cell 2.", table.getRows().get(1).getCells().get(1).getText().trim()); + Assert.assertEquals(TextOrientation.DOWNWARD, table.getRows().get(1).getCells().get(1).getCellFormat().getOrientation()); + } + + @Test + public void tableCellVerticalRotatedFarEastTextOrientation() throws Exception { + Document doc = new Document(getMyDir() + "Rotated cell text.docx"); + + Table table = doc.getFirstSection().getBody().getTables().get(0); + Cell cell = table.getFirstRow().getFirstCell(); + + Assert.assertEquals(cell.getCellFormat().getOrientation(), TextOrientation.VERTICAL_ROTATED_FAR_EAST); + + doc = DocumentHelper.saveOpen(doc); + + table = (Table) doc.getChild(NodeType.TABLE, 0, true); + cell = table.getFirstRow().getFirstCell(); + + Assert.assertEquals(cell.getCellFormat().getOrientation(), TextOrientation.VERTICAL_ROTATED_FAR_EAST); + } + + @Test + public void insertFloatingImage() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertImage(String, RelativeHorizontalPosition, Double, RelativeVerticalPosition, Double, Double, Double, WrapType) + //ExSummary:Shows how to insert an image. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // There are two ways of using a document builder to source an image and then insert it as a floating shape. + // 1 - From a file in the local file system: + builder.insertImage(getImageDir() + "Transparent background logo.png", RelativeHorizontalPosition.MARGIN, 100.0, + RelativeVerticalPosition.MARGIN, 0.0, 200.0, 200.0, WrapType.SQUARE); + + // 2 - From a URL: + builder.insertImage(getAsposelogoUri().toString(), RelativeHorizontalPosition.MARGIN, 100.0, + RelativeVerticalPosition.MARGIN, 250.0, 200.0, 200.0, WrapType.SQUARE); + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertFloatingImage.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertFloatingImage.docx"); + Shape image = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(400, 400, ImageType.PNG, image); + Assert.assertEquals(100.0d, image.getLeft()); + Assert.assertEquals(0.0d, image.getTop()); + Assert.assertEquals(200.0d, image.getWidth()); + Assert.assertEquals(200.0d, image.getHeight()); + Assert.assertEquals(WrapType.SQUARE, image.getWrapType()); + Assert.assertEquals(RelativeHorizontalPosition.MARGIN, image.getRelativeHorizontalPosition()); + Assert.assertEquals(RelativeVerticalPosition.MARGIN, image.getRelativeVerticalPosition()); + + image = (Shape) doc.getChild(NodeType.SHAPE, 1, true); + + TestUtil.verifyImageInShape(272, 92, ImageType.PNG, image); + Assert.assertEquals(100.0d, image.getLeft()); + Assert.assertEquals(250.0d, image.getTop()); + Assert.assertEquals(200.0d, image.getWidth()); + Assert.assertEquals(200.0d, image.getHeight()); + Assert.assertEquals(WrapType.SQUARE, image.getWrapType()); + Assert.assertEquals(RelativeHorizontalPosition.MARGIN, image.getRelativeHorizontalPosition()); + Assert.assertEquals(RelativeVerticalPosition.MARGIN, image.getRelativeVerticalPosition()); + } + + @Test + public void insertImageOriginalSize() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertImage(String, RelativeHorizontalPosition, Double, RelativeVerticalPosition, Double, Double, Double, WrapType) + //ExSummary:Shows how to insert an image from the local file system into a document while preserving its dimensions. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // The InsertImage method creates a floating shape with the passed image in its image data. + // We can specify the dimensions of the shape can be passing them to this method. + Shape imageShape = builder.insertImage(getImageDir() + "Logo.jpg", RelativeHorizontalPosition.MARGIN, 0.0, + RelativeVerticalPosition.MARGIN, 0.0, -1, -1, WrapType.SQUARE); + + // Passing negative values as the intended dimensions will automatically define + // the shape's dimensions based on the dimensions of its image. + Assert.assertEquals(300.0d, imageShape.getWidth()); + Assert.assertEquals(300.0d, imageShape.getHeight()); + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertImageOriginalSize.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertImageOriginalSize.docx"); + imageShape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, imageShape); + Assert.assertEquals(0.0d, imageShape.getLeft()); + Assert.assertEquals(0.0d, imageShape.getTop()); + Assert.assertEquals(300.0d, imageShape.getWidth()); + Assert.assertEquals(300.0d, imageShape.getHeight()); + Assert.assertEquals(WrapType.SQUARE, imageShape.getWrapType()); + Assert.assertEquals(RelativeHorizontalPosition.MARGIN, imageShape.getRelativeHorizontalPosition()); + Assert.assertEquals(RelativeVerticalPosition.MARGIN, imageShape.getRelativeVerticalPosition()); + } + + @Test + public void insertTextInput() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertTextInput + //ExSummary:Shows how to insert a text input form field into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a form that prompts the user to enter text. + builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", "Enter your text here", 0); + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertTextInput.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertTextInput.docx"); + FormField formField = doc.getRange().getFormFields().get(0); + + Assert.assertTrue(formField.getEnabled()); + Assert.assertEquals("TextInput", formField.getName()); + Assert.assertEquals(0, formField.getMaxLength()); + Assert.assertEquals("Enter your text here", formField.getResult()); + Assert.assertEquals(FieldType.FIELD_FORM_TEXT_INPUT, formField.getType()); + Assert.assertEquals("", formField.getTextInputFormat()); + Assert.assertEquals(TextFormFieldType.REGULAR, formField.getTextInputType()); + } + + @Test + public void insertComboBox() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertComboBox + //ExSummary:Shows how to insert a combo box form field into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a form that prompts the user to pick one of the items from the menu. + builder.write("Pick a fruit: "); + String[] items = {"Apple", "Banana", "Cherry"}; + builder.insertComboBox("DropDown", items, 0); + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertComboBox.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertComboBox.docx"); + FormField formField = doc.getRange().getFormFields().get(0); + + Assert.assertTrue(formField.getEnabled()); + Assert.assertEquals("DropDown", formField.getName()); + Assert.assertEquals(0, formField.getDropDownSelectedIndex()); + Assert.assertEquals(items.length, formField.getDropDownItems().getCount()); + Assert.assertEquals(FieldType.FIELD_FORM_DROP_DOWN, formField.getType()); + } + + @Test(description = "WORDSNET-16868, WORDSJAVA-2406", enabled = false) + public void signatureLineProviderId() throws Exception { + //ExStart + //ExFor:SignatureLine.IsSigned + //ExFor:SignatureLine.IsValid + //ExFor:SignatureLine.ProviderId + //ExFor:SignatureLineOptions + //ExFor:SignatureLineOptions.ShowDate + //ExFor:SignatureLineOptions.Email + //ExFor:SignatureLineOptions.DefaultInstructions + //ExFor:SignatureLineOptions.Instructions + //ExFor:SignatureLineOptions.AllowComments + //ExFor:DocumentBuilder.InsertSignatureLine(SignatureLineOptions) + //ExFor:SignOptions.ProviderId + //ExSummary:Shows how to sign a document with a personal certificate and a signature line. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + SignatureLineOptions signatureLineOptions = new SignatureLineOptions(); + signatureLineOptions.setSigner("vderyushev"); + signatureLineOptions.setSignerTitle("QA"); + signatureLineOptions.setEmail("vderyushev@aspose.com"); + signatureLineOptions.setShowDate(true); + signatureLineOptions.setDefaultInstructions(false); + signatureLineOptions.setInstructions("Please sign here."); + signatureLineOptions.setAllowComments(true); + + SignatureLine signatureLine = builder.insertSignatureLine(signatureLineOptions).getSignatureLine(); + signatureLine.setProviderId(UUID.fromString("CF5A7BB4-8F3C-4756-9DF6-BEF7F13259A2")); + + Assert.assertFalse(signatureLine.isSigned()); + Assert.assertFalse(signatureLine.isValid()); + + doc.save(getArtifactsDir() + "DocumentBuilder.SignatureLineProviderId.docx"); + + Date currentDate = new Date(); + + SignOptions signOptions = new SignOptions(); + signOptions.setSignatureLineId(signatureLine.getId()); + signOptions.setProviderId(signatureLine.getProviderId()); + signOptions.setComments("Document was signed by vderyushev"); + signOptions.setSignTime(currentDate); + + CertificateHolder certHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + + DigitalSignatureUtil.sign(getArtifactsDir() + "DocumentBuilder.SignatureLineProviderId.docx", + getArtifactsDir() + "DocumentBuilder.SignatureLineProviderId.Signed.docx", certHolder, signOptions); + + // Re-open our saved document, and verify that the "IsSigned" and "IsValid" properties both equal "true", + // indicating that the signature line contains a signature. + doc = new Document(getArtifactsDir() + "DocumentBuilder.SignatureLineProviderId.Signed.docx"); + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + signatureLine = shape.getSignatureLine(); + + Assert.assertTrue(signatureLine.isSigned()); + Assert.assertTrue(signatureLine.isValid()); + //ExEnd + + Assert.assertEquals("vderyushev", signatureLine.getSigner()); + Assert.assertEquals("QA", signatureLine.getSignerTitle()); + Assert.assertEquals("vderyushev@aspose.com", signatureLine.getEmail()); + Assert.assertTrue(signatureLine.getShowDate()); + Assert.assertFalse(signatureLine.getDefaultInstructions()); + Assert.assertEquals("Please sign here.", signatureLine.getInstructions()); + Assert.assertTrue(signatureLine.getAllowComments()); + Assert.assertTrue(signatureLine.isSigned()); + Assert.assertTrue(signatureLine.isValid()); + + DigitalSignatureCollection signatures = DigitalSignatureUtil.loadSignatures( + getArtifactsDir() + "DocumentBuilder.SignatureLineProviderId.Signed.docx"); + + Assert.assertEquals(1, signatures.getCount()); + Assert.assertTrue(signatures.get(0).isValid()); + Assert.assertEquals("Document was signed by vderyushev", signatures.get(0).getComments()); + Assert.assertEquals(currentDate, signatures.get(0).getSignTime()); + Assert.assertEquals("CN=Morzal.Me", signatures.get(0).getIssuerName()); + Assert.assertEquals(DigitalSignatureType.XML_DSIG, signatures.get(0).getSignatureType()); + } + + @Test + public void signatureLineInline() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertSignatureLine(SignatureLineOptions, RelativeHorizontalPosition, Double, RelativeVerticalPosition, Double, WrapType) + //ExSummary:Shows how to insert an inline signature line into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + SignatureLineOptions options = new SignatureLineOptions(); + options.setSigner("John Doe"); + options.setSignerTitle("Manager"); + options.setEmail("johndoe@aspose.com"); + options.setShowDate(true); + options.setDefaultInstructions(false); + options.setInstructions("Please sign here."); + options.setAllowComments(true); + + builder.insertSignatureLine(options, RelativeHorizontalPosition.RIGHT_MARGIN, 2.0, + RelativeVerticalPosition.PAGE, 3.0, WrapType.INLINE); + + // The signature line can be signed in Microsoft Word by double clicking it. + doc.save(getArtifactsDir() + "DocumentBuilder.SignatureLineInline.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.SignatureLineInline.docx"); + + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + SignatureLine signatureLine = shape.getSignatureLine(); + + Assert.assertEquals(signatureLine.getSigner(), "John Doe"); + Assert.assertEquals(signatureLine.getSignerTitle(), "Manager"); + Assert.assertEquals(signatureLine.getEmail(), "johndoe@aspose.com"); + Assert.assertEquals(signatureLine.getShowDate(), true); + Assert.assertEquals(signatureLine.getDefaultInstructions(), false); + Assert.assertEquals(signatureLine.getInstructions(), "Please sign here."); + Assert.assertEquals(signatureLine.getAllowComments(), true); + Assert.assertEquals(signatureLine.isSigned(), false); + Assert.assertEquals(signatureLine.isValid(), false); + } + + @Test + public void setParagraphFormatting() throws Exception { + //ExStart + //ExFor:ParagraphFormat.RightIndent + //ExFor:ParagraphFormat.LeftIndent + //ExSummary:Shows how to configure paragraph formatting to create off-center text. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Center all text that the document builder writes, and set up indents. + // The indent configuration below will create a body of text that will sit asymmetrically on the page. + // The "center" that we align the text to will be the middle of the body of text, not the middle of the page. + ParagraphFormat paragraphFormat = builder.getParagraphFormat(); + paragraphFormat.setAlignment(ParagraphAlignment.CENTER); + paragraphFormat.setLeftIndent(100.0); + paragraphFormat.setRightIndent(50.0); + paragraphFormat.setSpaceAfter(25.0); + + builder.writeln( + "This paragraph demonstrates how left and right indentation affects word wrapping."); + builder.writeln( + "The space between the above paragraph and this one depends on the DocumentBuilder's paragraph format."); + + doc.save(getArtifactsDir() + "DocumentBuilder.SetParagraphFormatting.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.SetParagraphFormatting.docx"); + + for (Paragraph paragraph : doc.getFirstSection().getBody().getParagraphs()) { + Assert.assertEquals(ParagraphAlignment.CENTER, paragraph.getParagraphFormat().getAlignment()); + Assert.assertEquals(100.0d, paragraph.getParagraphFormat().getLeftIndent()); + Assert.assertEquals(50.0d, paragraph.getParagraphFormat().getRightIndent()); + Assert.assertEquals(25.0d, paragraph.getParagraphFormat().getSpaceAfter()); + } + } + + @Test + public void setCellFormatting() throws Exception { + //ExStart + //ExFor:DocumentBuilder.CellFormat + //ExFor:CellFormat.Width + //ExFor:CellFormat.LeftPadding + //ExFor:CellFormat.RightPadding + //ExFor:CellFormat.TopPadding + //ExFor:CellFormat.BottomPadding + //ExFor:DocumentBuilder.StartTable + //ExFor:DocumentBuilder.EndTable + //ExSummary:Shows how to format cells with a document builder. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + builder.write("Row 1, cell 1."); + + // Insert a second cell, and then configure cell text padding options. + // The builder will apply these settings at its current cell, and any new cells creates afterwards. + builder.insertCell(); + + CellFormat cellFormat = builder.getCellFormat(); + cellFormat.setWidth(250.0); + cellFormat.setLeftPadding(30.0); + cellFormat.setRightPadding(30.0); + cellFormat.setTopPadding(30.0); + cellFormat.setBottomPadding(30.0); + + builder.write("Row 1, cell 2."); + builder.endRow(); + builder.endTable(); + + // The first cell was unaffected by the padding reconfiguration, and still holds the default values. + Assert.assertEquals(0.0d, table.getFirstRow().getCells().get(0).getCellFormat().getWidth()); + Assert.assertEquals(5.4d, table.getFirstRow().getCells().get(0).getCellFormat().getLeftPadding()); + Assert.assertEquals(5.4d, table.getFirstRow().getCells().get(0).getCellFormat().getRightPadding()); + Assert.assertEquals(0.0d, table.getFirstRow().getCells().get(0).getCellFormat().getTopPadding()); + Assert.assertEquals(0.0d, table.getFirstRow().getCells().get(0).getCellFormat().getBottomPadding()); + + Assert.assertEquals(250.0d, table.getFirstRow().getCells().get(1).getCellFormat().getWidth()); + Assert.assertEquals(30.0d, table.getFirstRow().getCells().get(1).getCellFormat().getLeftPadding()); + Assert.assertEquals(30.0d, table.getFirstRow().getCells().get(1).getCellFormat().getRightPadding()); + Assert.assertEquals(30.0d, table.getFirstRow().getCells().get(1).getCellFormat().getTopPadding()); + Assert.assertEquals(30.0d, table.getFirstRow().getCells().get(1).getCellFormat().getBottomPadding()); + + // The first cell will still grow in the output document to match the size of its neighboring cell. + doc.save(getArtifactsDir() + "DocumentBuilder.SetCellFormatting.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.SetCellFormatting.docx"); + table = doc.getFirstSection().getBody().getTables().get(0); + + Assert.assertEquals(157.0d, table.getFirstRow().getCells().get(0).getCellFormat().getWidth()); + Assert.assertEquals(5.4d, table.getFirstRow().getCells().get(0).getCellFormat().getLeftPadding()); + Assert.assertEquals(5.4d, table.getFirstRow().getCells().get(0).getCellFormat().getRightPadding()); + Assert.assertEquals(0.0d, table.getFirstRow().getCells().get(0).getCellFormat().getTopPadding()); + Assert.assertEquals(0.0d, table.getFirstRow().getCells().get(0).getCellFormat().getBottomPadding()); + + Assert.assertEquals(310.0d, table.getFirstRow().getCells().get(1).getCellFormat().getWidth()); + Assert.assertEquals(30.0d, table.getFirstRow().getCells().get(1).getCellFormat().getLeftPadding()); + Assert.assertEquals(30.0d, table.getFirstRow().getCells().get(1).getCellFormat().getRightPadding()); + Assert.assertEquals(30.0d, table.getFirstRow().getCells().get(1).getCellFormat().getTopPadding()); + Assert.assertEquals(30.0d, table.getFirstRow().getCells().get(1).getCellFormat().getBottomPadding()); + } + + @Test + public void setRowFormatting() throws Exception { + //ExStart + //ExFor:DocumentBuilder.RowFormat + //ExFor:HeightRule + //ExFor:RowFormat.Height + //ExFor:RowFormat.HeightRule + //ExSummary:Shows how to format rows with a document builder. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + builder.write("Row 1, cell 1."); + + // Start a second row, and then configure its height. The builder will apply these settings to + // its current row, as well as any new rows it creates afterwards. + builder.endRow(); + + RowFormat rowFormat = builder.getRowFormat(); + rowFormat.setHeight(100.0); + rowFormat.setHeightRule(HeightRule.EXACTLY); + + builder.insertCell(); + builder.write("Row 2, cell 1."); + builder.endTable(); + + // The first row was unaffected by the padding reconfiguration and still holds the default values. + Assert.assertEquals(0.0d, table.getRows().get(0).getRowFormat().getHeight()); + Assert.assertEquals(HeightRule.AUTO, table.getRows().get(0).getRowFormat().getHeightRule()); + + Assert.assertEquals(100.0d, table.getRows().get(1).getRowFormat().getHeight()); + Assert.assertEquals(HeightRule.EXACTLY, table.getRows().get(1).getRowFormat().getHeightRule()); + + doc.save(getArtifactsDir() + "DocumentBuilder.SetRowFormatting.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.SetRowFormatting.docx"); + table = doc.getFirstSection().getBody().getTables().get(0); + + Assert.assertEquals(0.0d, table.getRows().get(0).getRowFormat().getHeight()); + Assert.assertEquals(HeightRule.AUTO, table.getRows().get(0).getRowFormat().getHeightRule()); + + Assert.assertEquals(100.0d, table.getRows().get(1).getRowFormat().getHeight()); + Assert.assertEquals(HeightRule.EXACTLY, table.getRows().get(1).getRowFormat().getHeightRule()); + } + + @Test + public void insertFootnote() throws Exception { + //ExStart + //ExFor:FootnoteType + //ExFor:DocumentBuilder.InsertFootnote(FootnoteType,String) + //ExFor:DocumentBuilder.InsertFootnote(FootnoteType,String,String) + //ExSummary:Shows how to reference text with a footnote and an endnote. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert some text and mark it with a footnote with the IsAuto property set to "true" by default, + // so the marker seen in the body text will be auto-numbered at "1", + // and the footnote will appear at the bottom of the page. + builder.write("This text will be referenced by a footnote."); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote comment regarding referenced text."); + + // Insert more text and mark it with an endnote with a custom reference mark, + // which will be used in place of the number "2" and set "IsAuto" to false. + builder.write("This text will be referenced by an endnote."); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote comment regarding referenced text.", "CustomMark"); + + // Footnotes always appear at the bottom of their referenced text, + // so this page break will not affect the footnote. + // On the other hand, endnotes are always at the end of the document + // so that this page break will push the endnote down to the next page. + builder.insertBreak(BreakType.PAGE_BREAK); + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertFootnote.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertFootnote.docx"); + + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote comment regarding referenced text.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 0, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, false, "CustomMark", + "CustomMark Endnote comment regarding referenced text.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 1, true)); + } + + @Test + public void applyBordersAndShading() throws Exception { + //ExStart + //ExFor:BorderCollection.Item(BorderType) + //ExFor:Shading + //ExFor:TextureIndex + //ExFor:ParagraphFormat.Shading + //ExFor:Shading.Texture + //ExFor:Shading.BackgroundPatternColor + //ExFor:Shading.ForegroundPatternColor + //ExSummary:Shows how to decorate text with borders and shading. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + BorderCollection borders = builder.getParagraphFormat().getBorders(); + borders.setDistanceFromText(20.0); + borders.getByBorderType(BorderType.LEFT).setLineStyle(LineStyle.DOUBLE); + borders.getByBorderType(BorderType.RIGHT).setLineStyle(LineStyle.DOUBLE); + borders.getByBorderType(BorderType.TOP).setLineStyle(LineStyle.DOUBLE); + borders.getByBorderType(BorderType.BOTTOM).setLineStyle(LineStyle.DOUBLE); + + Shading shading = builder.getParagraphFormat().getShading(); + shading.setTexture(TextureIndex.TEXTURE_DIAGONAL_CROSS); + shading.setBackgroundPatternColor(new Color(240, 128, 128)); // Light Coral + shading.setForegroundPatternColor(new Color(255, 160, 122)); // Light Salmon + + builder.write("This paragraph is formatted with a double border and shading."); + doc.save(getArtifactsDir() + "DocumentBuilder.ApplyBordersAndShading.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.ApplyBordersAndShading.docx"); + borders = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat().getBorders(); + + Assert.assertEquals(20.0d, borders.getDistanceFromText()); + Assert.assertEquals(LineStyle.DOUBLE, borders.getByBorderType(BorderType.LEFT).getLineStyle()); + Assert.assertEquals(LineStyle.DOUBLE, borders.getByBorderType(BorderType.RIGHT).getLineStyle()); + Assert.assertEquals(LineStyle.DOUBLE, borders.getByBorderType(BorderType.TOP).getLineStyle()); + Assert.assertEquals(LineStyle.DOUBLE, borders.getByBorderType(BorderType.BOTTOM).getLineStyle()); + + Assert.assertEquals(TextureIndex.TEXTURE_DIAGONAL_CROSS, shading.getTexture()); + Assert.assertEquals(Color.decode("#f08080").getRGB(), shading.getBackgroundPatternColor().getRGB()); + Assert.assertEquals(Color.decode("#ffa07a").getRGB(), shading.getForegroundPatternColor().getRGB()); + } + + @Test + public void deleteRow() throws Exception { + //ExStart + //ExFor:DocumentBuilder.DeleteRow + //ExSummary:Shows how to delete a row from a table. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + builder.write("Row 1, cell 1."); + builder.insertCell(); + builder.write("Row 1, cell 2."); + builder.endRow(); + builder.insertCell(); + builder.write("Row 2, cell 1."); + builder.insertCell(); + builder.write("Row 2, cell 2."); + builder.endTable(); + + Assert.assertEquals(2, table.getRows().getCount()); + + // Delete the first row of the first table in the document. + builder.deleteRow(0, 0); + + Assert.assertEquals(1, table.getRows().getCount()); + Assert.assertEquals("Row 2, cell 1.\u0007Row 2, cell 2.", table.getText().trim()); + //ExEnd + } + + @Test (dataProvider = "appendDocumentAndResolveStylesDataProvider") + public void appendDocumentAndResolveStyles(boolean keepSourceNumbering) throws Exception + { + //ExStart + //ExFor:Document.AppendDocument(Document, ImportFormatMode, ImportFormatOptions) + //ExSummary:Shows how to manage list style clashes while appending a document. + // Load a document with text in a custom style and clone it. + Document srcDoc = new Document(getMyDir() + "Custom list numbering.docx"); + Document dstDoc = srcDoc.deepClone(); + + // We now have two documents, each with an identical style named "CustomStyle". + // Change the text color for one of the styles to set it apart from the other. + dstDoc.getStyles().get("CustomStyle").getFont().setColor(Color.RED); + + // If there is a clash of list styles, apply the list format of the source document. + // Set the "KeepSourceNumbering" property to "false" to not import any list numbers into the destination document. + // Set the "KeepSourceNumbering" property to "true" import all clashing + // list style numbering with the same appearance that it had in the source document. + ImportFormatOptions options = new ImportFormatOptions(); + options.setKeepSourceNumbering(keepSourceNumbering); + + // Joining two documents that have different styles that share the same name causes a style clash. + // We can specify an import format mode while appending documents to resolve this clash. + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_DIFFERENT_STYLES, options); + dstDoc.updateListLabels(); + + dstDoc.save(getArtifactsDir() + "DocumentBuilder.AppendDocumentAndResolveStyles.docx"); + //ExEnd + } + + @DataProvider(name = "appendDocumentAndResolveStylesDataProvider") + public static Object[][] appendDocumentAndResolveStylesDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "insertDocumentAndResolveStylesDataProvider") + public void insertDocumentAndResolveStyles(boolean keepSourceNumbering) throws Exception + { + //ExStart + //ExFor:Document.AppendDocument(Document, ImportFormatMode, ImportFormatOptions) + //ExSummary:Shows how to manage list style clashes while inserting a document. + Document dstDoc = new Document(); + DocumentBuilder builder = new DocumentBuilder(dstDoc); + builder.insertBreak(BreakType.PARAGRAPH_BREAK); + + dstDoc.getLists().add(ListTemplate.NUMBER_DEFAULT); + List list = dstDoc.getLists().get(0); + + builder.getListFormat().setList(list); + + for (int i = 1; i <= 15; i++) + builder.write(MessageFormat.format("List Item {0}\n", i)); + + Document attachDoc = (Document)dstDoc.deepClone(true); + + // If there is a clash of list styles, apply the list format of the source document. + // Set the "KeepSourceNumbering" property to "false" to not import any list numbers into the destination document. + // Set the "KeepSourceNumbering" property to "true" import all clashing + // list style numbering with the same appearance that it had in the source document. + ImportFormatOptions importOptions = new ImportFormatOptions(); + importOptions.setKeepSourceNumbering(keepSourceNumbering); + + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.insertDocument(attachDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING, importOptions); + + dstDoc.save(getArtifactsDir() + "DocumentBuilder.InsertDocumentAndResolveStyles.docx"); + //ExEnd + } + + @DataProvider(name = "insertDocumentAndResolveStylesDataProvider") + public static Object[][] insertDocumentAndResolveStylesDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "loadDocumentWithListNumberingDataProvider") + public void loadDocumentWithListNumbering(boolean keepSourceNumbering) throws Exception + { + //ExStart + //ExFor:Document.AppendDocument(Document, ImportFormatMode, ImportFormatOptions) + //ExSummary:Shows how to manage list style clashes while appending a clone of a document to itself. + Document srcDoc = new Document(getMyDir() + "List item.docx"); + Document dstDoc = new Document(getMyDir() + "List item.docx"); + + // If there is a clash of list styles, apply the list format of the source document. + // Set the "KeepSourceNumbering" property to "false" to not import any list numbers into the destination document. + // Set the "KeepSourceNumbering" property to "true" import all clashing + // list style numbering with the same appearance that it had in the source document. + DocumentBuilder builder = new DocumentBuilder(dstDoc); + builder.moveToDocumentEnd(); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + + ImportFormatOptions options = new ImportFormatOptions(); + options.setKeepSourceNumbering(keepSourceNumbering); + builder.insertDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING, options); + + dstDoc.updateListLabels(); + //ExEnd + } + + @DataProvider(name = "loadDocumentWithListNumberingDataProvider") + public static Object[][] loadDocumentWithListNumberingDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "ignoreTextBoxesDataProvider") + public void ignoreTextBoxes(boolean ignoreTextBoxes) throws Exception + { + //ExStart + //ExFor:ImportFormatOptions.IgnoreTextBoxes + //ExSummary:Shows how to manage text box formatting while appending a document. + // Create a document that will have nodes from another document inserted into it. + Document dstDoc = new Document(); + DocumentBuilder builder = new DocumentBuilder(dstDoc); + + builder.writeln("Hello world!"); + + // Create another document with a text box, which we will import into the first document. + Document srcDoc = new Document(); + builder = new DocumentBuilder(srcDoc); + + Shape textBox = builder.insertShape(ShapeType.TEXT_BOX, 300.0, 100.0); + builder.moveTo(textBox.getFirstParagraph()); + builder.getParagraphFormat().getStyle().getFont().setName("Courier New"); + builder.getParagraphFormat().getStyle().getFont().setSize(24.0); + builder.write("Textbox contents"); + + // Set a flag to specify whether to clear or preserve text box formatting + // while importing them to other documents. + ImportFormatOptions importFormatOptions = new ImportFormatOptions(); + importFormatOptions.setIgnoreTextBoxes(ignoreTextBoxes); + + // Import the text box from the source document into the destination document, + // and then verify whether we have preserved the styling of its text contents. + NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING, importFormatOptions); + Shape importedTextBox = (Shape) importer.importNode(textBox, true); + dstDoc.getFirstSection().getBody().getParagraphs().get(1).appendChild(importedTextBox); + + if (ignoreTextBoxes) { + Assert.assertEquals(12.0d, importedTextBox.getFirstParagraph().getRuns().get(0).getFont().getSize()); + Assert.assertEquals("Times New Roman", importedTextBox.getFirstParagraph().getRuns().get(0).getFont().getName()); + } else { + Assert.assertEquals(24.0d, importedTextBox.getFirstParagraph().getRuns().get(0).getFont().getSize()); + Assert.assertEquals("Courier New", importedTextBox.getFirstParagraph().getRuns().get(0).getFont().getName()); + } + + dstDoc.save(getArtifactsDir() + "DocumentBuilder.IgnoreTextBoxes.docx"); + //ExEnd + } + + @DataProvider(name = "ignoreTextBoxesDataProvider") + public static Object[][] ignoreTextBoxesDataProvider() { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test(dataProvider = "moveToFieldDataProvider") + public void moveToField(boolean moveCursorToAfterTheField) throws Exception { + //ExStart + //ExFor:DocumentBuilder.MoveToField + //ExSummary:Shows how to move a document builder's node insertion point cursor to a specific field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a field using the DocumentBuilder and add a run of text after it. + Field field = builder.insertField(" AUTHOR \"John Doe\" "); + + // The builder's cursor is currently at end of the document. + Assert.assertNull(builder.getCurrentNode()); + + // Move the cursor to the field while specifying whether to place that cursor before or after the field. + builder.moveToField(field, moveCursorToAfterTheField); + + // Note that the cursor is outside of the field in both cases. + // This means that we cannot edit the field using the builder like this. + // To edit a field, we can use the builder's MoveTo method on a field's FieldStart + // or FieldSeparator node to place the cursor inside. + if (moveCursorToAfterTheField) { + Assert.assertNull(builder.getCurrentNode()); + builder.write(" Text immediately after the field."); + + Assert.assertEquals("AUTHOR \"John Doe\" \u0014John Doe\u0015 Text immediately after the field.", + doc.getText().trim()); + } else { + Assert.assertEquals(field.getStart(), builder.getCurrentNode()); + builder.write("Text immediately before the field. "); + + Assert.assertEquals("Text immediately before the field. \u0013 AUTHOR \"John Doe\" \u0014John Doe", + doc.getText().trim()); + } + //ExEnd + } + + @DataProvider(name = "moveToFieldDataProvider") + public static Object[][] moveToFieldDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void insertOleObjectException() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Assert.assertThrows(RuntimeException.class, () -> builder.insertOleObject("", "checkbox", false, true, null)); + } + + @Test + public void insertPieChart() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertChart(ChartType, Double, Double) + //ExSummary:Shows how to insert a pie chart into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Chart chart = builder.insertChart(ChartType.PIE, ConvertUtil.pixelToPoint(300.0), + ConvertUtil.pixelToPoint(300.0)).getChart(); + Assert.assertEquals(225.0d, ConvertUtil.pixelToPoint(300.0)); //ExSkip + chart.getSeries().clear(); + chart.getSeries().add("My fruit", + new String[]{"Apples", "Bananas", "Cherries"}, + new double[]{1.3, 2.2, 1.5}); + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertPieChart.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertPieChart.docx"); + Shape chartShape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals("Chart Title", chartShape.getChart().getTitle().getText()); + Assert.assertEquals(225.0d, chartShape.getWidth()); + Assert.assertEquals(225.0d, chartShape.getHeight()); + } + + @Test + public void insertChartRelativePosition() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertChart(ChartType, RelativeHorizontalPosition, Double, RelativeVerticalPosition, Double, Double, Double, WrapType) + //ExSummary:Shows how to specify position and wrapping while inserting a chart. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertChart(ChartType.PIE, RelativeHorizontalPosition.MARGIN, 100.0, RelativeVerticalPosition.MARGIN, 100.0, 200.0, 100.0, WrapType.SQUARE); + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertedChartRelativePosition.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertedChartRelativePosition.docx"); + Shape chartShape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(100.0d, chartShape.getTop()); + Assert.assertEquals(100.0d, chartShape.getLeft()); + Assert.assertEquals(200.0d, chartShape.getWidth()); + Assert.assertEquals(100.0d, chartShape.getHeight()); + Assert.assertEquals(WrapType.SQUARE, chartShape.getWrapType()); + Assert.assertEquals(RelativeHorizontalPosition.MARGIN, chartShape.getRelativeHorizontalPosition()); + Assert.assertEquals(RelativeVerticalPosition.MARGIN, chartShape.getRelativeVerticalPosition()); + } + + @Test + public void insertField() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertField(String) + //ExFor:Field + //ExFor:Field.Result + //ExFor:Field.GetFieldCode + //ExFor:Field.Type + //ExFor:FieldType + //ExSummary:Shows how to insert a field into a document using a field code. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Field dateField = builder.insertField("DATE \\* MERGEFORMAT"); + + Assert.assertEquals(FieldType.FIELD_DATE, dateField.getType()); + Assert.assertEquals("DATE \\* MERGEFORMAT", dateField.getFieldCode()); + //ExEnd + } + + @Test(dataProvider = "insertFieldAndUpdateDataProvider") + public void insertFieldAndUpdate(boolean updateInsertedFieldsImmediately) throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertField(FieldType, Boolean) + //ExFor:Field.Update + //ExSummary:Shows how to insert a field into a document using FieldType. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert two fields while passing a flag which determines whether to update them as the builder inserts them. + // In some cases, updating fields could be computationally expensive, and it may be a good idea to defer the update. + doc.getBuiltInDocumentProperties().setAuthor("John Doe"); + builder.write("This document was written by "); + builder.insertField(FieldType.FIELD_AUTHOR, updateInsertedFieldsImmediately); + + builder.insertParagraph(); + builder.write("\nThis is page "); + builder.insertField(FieldType.FIELD_PAGE, updateInsertedFieldsImmediately); + + Assert.assertEquals(" AUTHOR ", doc.getRange().getFields().get(0).getFieldCode()); + Assert.assertEquals(" PAGE ", doc.getRange().getFields().get(1).getFieldCode()); + + if (updateInsertedFieldsImmediately) { + Assert.assertEquals("John Doe", doc.getRange().getFields().get(0).getResult()); + Assert.assertEquals("1", doc.getRange().getFields().get(1).getResult()); + } else { + Assert.assertEquals("", doc.getRange().getFields().get(0).getResult()); + Assert.assertEquals("", doc.getRange().getFields().get(1).getResult()); + + // We will need to update these fields using the update methods manually. + doc.getRange().getFields().get(0).update(); + + Assert.assertEquals("John Doe", doc.getRange().getFields().get(0).getResult()); + + doc.updateFields(); + + Assert.assertEquals("1", doc.getRange().getFields().get(1).getResult()); + } + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + + Assert.assertEquals("This document was written by \u0013 AUTHOR \u0014John Doe\u0015" + + "\r\rThis is page \u0013 PAGE \u00141", doc.getText().trim()); + + TestUtil.verifyField(FieldType.FIELD_AUTHOR, " AUTHOR ", "John Doe", doc.getRange().getFields().get(0)); + TestUtil.verifyField(FieldType.FIELD_PAGE, " PAGE ", "1", doc.getRange().getFields().get(1)); + } + + @DataProvider(name = "insertFieldAndUpdateDataProvider") + public static Object[][] insertFieldAndUpdateDataProvider() throws Exception { + return new Object[][] + { + {false}, + {true}, + }; + } + + //ExStart + //ExFor:IFieldResultFormatter + //ExFor:IFieldResultFormatter.Format(Double, GeneralFormat) + //ExFor:IFieldResultFormatter.Format(String, GeneralFormat) + //ExFor:IFieldResultFormatter.FormatDateTime(DateTime, String, CalendarType) + //ExFor:IFieldResultFormatter.FormatNumeric(Double, String) + //ExFor:FieldOptions.ResultFormatter + //ExFor:CalendarType + //ExSummary:Shows how to automatically apply a custom format to field results as the fields are updated. + @Test //ExSkip + public void fieldResultFormatting() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + FieldResultFormatter formatter = new FieldResultFormatter("$%d", "Date: %tb", "Item # %s:"); + doc.getFieldOptions().setResultFormatter(formatter); + + // Our field result formatter applies a custom format to newly created fields of three types of formats. + // Field result formatters apply new formatting to fields as they are updated, + // which happens as soon as we create them using this InsertField method overload. + // 1 - Numeric: + builder.insertField(" = 2 + 3 \\# $###"); + + Assert.assertEquals("$5", doc.getRange().getFields().get(0).getResult()); + Assert.assertEquals(1, formatter.countFormatInvocations(FieldResultFormatter.FormatInvocationType.NUMERIC)); + + // 2 - Date/time: + builder.insertField("DATE \\@ \"d MMMM yyyy\""); + + Assert.assertTrue(doc.getRange().getFields().get(1).getResult().startsWith("Date: ")); + Assert.assertEquals(1, formatter.countFormatInvocations(FieldResultFormatter.FormatInvocationType.DATE_TIME)); + + // 3 - General: + builder.insertField("QUOTE \"2\" \\* Ordinal"); + + Assert.assertEquals("Item # 2:", doc.getRange().getFields().get(2).getResult()); + Assert.assertEquals(1, formatter.countFormatInvocations(FieldResultFormatter.FormatInvocationType.GENERAL)); + + formatter.printFormatInvocations(); + } + + /// + /// When fields with formatting are updated, this formatter will override their formatting + /// with a custom format, while tracking every invocation. + /// + private static class FieldResultFormatter implements IFieldResultFormatter { + public FieldResultFormatter(String numberFormat, String dateFormat, String generalFormat) { + mNumberFormat = numberFormat; + mDateFormat = dateFormat; + mGeneralFormat = generalFormat; + } + + public String formatNumeric(double value, String format) { + if (mNumberFormat.isEmpty()) + return null; + + String newValue = String.format(mNumberFormat, (long) value); + mFormatInvocations.add(new FormatInvocation(FormatInvocationType.NUMERIC, value, format, newValue)); + return newValue; + } + + public String formatDateTime(Date value, String format, int calendarType) { + if (mDateFormat.isEmpty()) + return null; + + String newValue = String.format(mDateFormat, value); + mFormatInvocations.add(new FormatInvocation(FormatInvocationType.DATE_TIME, MessageFormat.format("{0} ({1})", value, calendarType), format, newValue)); + return newValue; + } + + public String format(String value, int format) { + return format((Object) value, format); + } + + public String format(double value, int format) { + return format((Object) value, format); + } + + private String format(Object value, int format) { + if (mGeneralFormat.isEmpty()) + return null; + + String newValue = String.format(mGeneralFormat, new DecimalFormat("#.####").format(value)); + mFormatInvocations.add(new FormatInvocation(FormatInvocationType.GENERAL, value, GeneralFormat.toString(format), newValue)); + return newValue; + } + + public int countFormatInvocations(int formatInvocationType) { + if (formatInvocationType == FormatInvocationType.ALL) + return getFormatInvocations().size(); + + return (int) IterableUtils.countMatches(getFormatInvocations(), i -> i.getFormatInvocationType() == formatInvocationType); + } + + public void printFormatInvocations() { + for (FormatInvocation f : getFormatInvocations()) + System.out.println(MessageFormat.format("Invocation type:\t{0}\n" + + "\tOriginal value:\t\t{1}\n" + + "\tOriginal format:\t{2}\n" + + "\tNew value:\t\t\t{3}\n", f.getFormatInvocationType(), f.getValue(), f.getOriginalFormat(), f.getNewValue())); + } + + private final String mNumberFormat; + private final String mDateFormat; + private final String mGeneralFormat; + + private ArrayList getFormatInvocations() { + return mFormatInvocations; + } + + private final ArrayList mFormatInvocations = new ArrayList<>(); + + private static class FormatInvocation { + public int getFormatInvocationType() { + return mFormatInvocationType; + } + + private final int mFormatInvocationType; + + public Object getValue() { + return mValue; + } + + private final Object mValue; + + public String getOriginalFormat() { + return mOriginalFormat; + } + + private final String mOriginalFormat; + + public String getNewValue() { + return mNewValue; + } + + private final String mNewValue; + + public FormatInvocation(int formatInvocationType, Object value, String originalFormat, String newValue) { + mValue = value; + mFormatInvocationType = formatInvocationType; + mOriginalFormat = originalFormat; + mNewValue = newValue; + } + } + + public final class FormatInvocationType { + private FormatInvocationType() { + } + + public static final int NUMERIC = 0; + public static final int DATE_TIME = 1; + public static final int GENERAL = 2; + public static final int ALL = 3; + + public static final int length = 4; + } + } + //ExEnd + + @Test + public void insertVideoWithUrl() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertOnlineVideo(String, Double, Double) + //ExSummary:Shows how to insert an online video into a document using a URL. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertOnlineVideo("https://youtu.be/g1N9ke8Prmk", 360.0, 270.0); + + // We can watch the video from Microsoft Word by clicking on the shape. + doc.save(getArtifactsDir() + "DocumentBuilder.InsertVideoWithUrl.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertVideoWithUrl.docx"); + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(480, 360, ImageType.JPEG, shape); + + Assert.assertEquals(360.0d, shape.getWidth()); + Assert.assertEquals(270.0d, shape.getHeight()); + } + + @Test + public void insertUnderline() throws Exception { + //ExStart + //ExFor:DocumentBuilder.Underline + //ExSummary:Shows how to format text inserted by a document builder. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.setUnderline(Underline.DASH); + builder.getFont().setColor(Color.BLUE); + builder.getFont().setSize(32.0); + + // The builder applies formatting to its current paragraph and any new text added by it afterward. + builder.writeln("Large, blue, and underlined text."); + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertUnderline.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertUnderline.docx"); + Run firstRun = doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0); + + Assert.assertEquals("Large, blue, and underlined text.", firstRun.getText().trim()); + Assert.assertEquals(Underline.DASH, firstRun.getFont().getUnderline()); + Assert.assertEquals(Color.BLUE.getRGB(), firstRun.getFont().getColor().getRGB()); + Assert.assertEquals(32.0d, firstRun.getFont().getSize()); + } + + @Test + public void currentStory() throws Exception { + //ExStart + //ExFor:DocumentBuilder.CurrentStory + //ExSummary:Shows how to work with a document builder's current story. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // A Story is a type of node that has child Paragraph nodes, such as a Body. + Assert.assertEquals(builder.getCurrentStory(), doc.getFirstSection().getBody()); + Assert.assertEquals(builder.getCurrentStory(), builder.getCurrentParagraph().getParentNode()); + Assert.assertEquals(StoryType.MAIN_TEXT, builder.getCurrentStory().getStoryType()); + + builder.getCurrentStory().appendParagraph("Text added to current Story."); + + // A Story can also contain tables. + Table table = builder.startTable(); + builder.insertCell(); + builder.write("Row 1, cell 1"); + builder.insertCell(); + builder.write("Row 1, cell 2"); + builder.endTable(); + + Assert.assertTrue(builder.getCurrentStory().getTables().contains(table)); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + Assert.assertEquals(1, doc.getFirstSection().getBody().getTables().getCount()); + Assert.assertEquals("Row 1, cell 1\u0007Row 1, cell 2\u0007\u0007\rText added to current Story.", doc.getFirstSection().getBody().getText().trim()); + } + + @Test + public void insertOleObjects() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertOleObject(Stream, String, Boolean, Stream) + //ExSummary:Shows how to use document builder to embed OLE objects in a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a Microsoft Excel spreadsheet from the local file system + // into the document while keeping its default appearance. + InputStream spreadsheetStream = new FileInputStream(getMyDir() + "Spreadsheet.xlsx"); + InputStream representingImage = new FileInputStream(getImageDir() + "Logo.jpg"); + try { + builder.writeln("Spreadsheet Ole object:"); + builder.insertOleObject(spreadsheetStream, "OleObject.xlsx", false, representingImage); + } finally { + if (spreadsheetStream != null) spreadsheetStream.close(); + } + + // Double-click these objects in Microsoft Word to open + // the linked files using their respective applications. + doc.save(getArtifactsDir() + "DocumentBuilder.InsertOleObjects.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertOleObjects.docx"); + + Assert.assertEquals(1, doc.getChildNodes(NodeType.SHAPE, true).getCount()); + + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + Assert.assertEquals("", shape.getOleFormat().getIconCaption()); + Assert.assertFalse(shape.getOleFormat().getOleIcon()); + } + + @Test + public void insertStyleSeparator() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertStyleSeparator + //ExSummary:Shows how to work with style separators. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Each paragraph can only have one style. + // The InsertStyleSeparator method allows us to work around this limitation. + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + builder.write("This text is in a Heading style. "); + builder.insertStyleSeparator(); + + Style paraStyle = builder.getDocument().getStyles().add(StyleType.PARAGRAPH, "MyParaStyle"); + paraStyle.getFont().setBold(false); + paraStyle.getFont().setSize(8.0); + paraStyle.getFont().setName("Arial"); + + builder.getParagraphFormat().setStyleName(paraStyle.getName()); + builder.write("This text is in a custom style. "); + + // Calling the InsertStyleSeparator method creates another paragraph, + // which can have a different style to the previous. There will be no break between paragraphs. + // The text in the output document will look like one paragraph with two styles. + Assert.assertEquals(2, doc.getFirstSection().getBody().getParagraphs().getCount()); + Assert.assertEquals("Heading 1", doc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat().getStyle().getName()); + Assert.assertEquals("MyParaStyle", doc.getFirstSection().getBody().getParagraphs().get(1).getParagraphFormat().getStyle().getName()); + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertStyleSeparator.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertStyleSeparator.docx"); + + Assert.assertEquals(2, doc.getFirstSection().getBody().getParagraphs().getCount()); + Assert.assertEquals("This text is in a Heading style. \r This text is in a custom style.", + doc.getText().trim()); + Assert.assertEquals("Heading 1", doc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat().getStyle().getName()); + Assert.assertEquals("MyParaStyle", doc.getFirstSection().getBody().getParagraphs().get(1).getParagraphFormat().getStyle().getName()); + Assert.assertEquals(" ", doc.getFirstSection().getBody().getParagraphs().get(1).getRuns().get(0).getText()); + TestUtil.docPackageFileContainsString("w:rPr>", + getArtifactsDir() + "DocumentBuilder.InsertStyleSeparator.docx", "document.xml"); + TestUtil.docPackageFileContainsString(" ", + getArtifactsDir() + "DocumentBuilder.InsertStyleSeparator.docx", "document.xml"); + } + + @Test(enabled = false, description = "Bug: does not insert headers and footers, all lists (bullets, numbering, multilevel) breaks") + public void insertDocument() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertDocument(Document, ImportFormatMode) + //ExFor:ImportFormatMode + //ExSummary:Shows how to insert a document into another document. + Document doc = new Document(getMyDir() + "Document.docx"); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.moveToDocumentEnd(); + builder.insertBreak(BreakType.PAGE_BREAK); + + Document docToInsert = new Document(getMyDir() + "Formatted elements.docx"); + + builder.insertDocument(docToInsert, ImportFormatMode.KEEP_SOURCE_FORMATTING); + builder.getDocument().save(getArtifactsDir() + "DocumentBuilder.InsertDocument.docx"); + //ExEnd + + Assert.assertEquals(29, doc.getStyles().getCount()); + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "DocumentBuilder.InsertDocument.docx", + getGoldsDir() + "DocumentBuilder.InsertDocument Gold.docx")); + } + + @Test + public void smartStyleBehavior() throws Exception { + //ExStart + //ExFor:ImportFormatOptions + //ExFor:ImportFormatOptions.SmartStyleBehavior + //ExFor:DocumentBuilder.InsertDocument(Document, ImportFormatMode, ImportFormatOptions) + //ExSummary:Shows how to resolve duplicate styles while inserting documents. + Document dstDoc = new Document(); + DocumentBuilder builder = new DocumentBuilder(dstDoc); + + Style myStyle = builder.getDocument().getStyles().add(StyleType.PARAGRAPH, "MyStyle"); + myStyle.getFont().setSize(14.0); + myStyle.getFont().setName("Courier New"); + myStyle.getFont().setColor(Color.BLUE); + + builder.getParagraphFormat().setStyleName(myStyle.getName()); + builder.writeln("Hello world!"); + + // Clone the document and edit the clone's "MyStyle" style, so it is a different color than that of the original. + // If we insert the clone into the original document, the two styles with the same name will cause a clash. + Document srcDoc = dstDoc.deepClone(); + srcDoc.getStyles().get("MyStyle").getFont().setColor(Color.RED); + + // When we enable SmartStyleBehavior and use the KeepSourceFormatting import format mode, + // Aspose.Words will resolve style clashes by converting source document styles. + // with the same names as destination styles into direct paragraph attributes. + ImportFormatOptions options = new ImportFormatOptions(); + options.setSmartStyleBehavior(true); + + builder.insertDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING, options); + + dstDoc.save(getArtifactsDir() + "DocumentBuilder.SmartStyleBehavior.docx"); + //ExEnd + + dstDoc = new Document(getArtifactsDir() + "DocumentBuilder.SmartStyleBehavior.docx"); + + Assert.assertEquals(Color.BLUE.getRGB(), dstDoc.getStyles().get("MyStyle").getFont().getColor().getRGB()); + Assert.assertEquals("MyStyle", dstDoc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat().getStyle().getName()); + + Assert.assertEquals("Normal", dstDoc.getFirstSection().getBody().getParagraphs().get(1).getParagraphFormat().getStyle().getName()); + Assert.assertEquals(14.0, dstDoc.getFirstSection().getBody().getParagraphs().get(1).getRuns().get(0).getFont().getSize()); + Assert.assertEquals("Courier New", dstDoc.getFirstSection().getBody().getParagraphs().get(1).getRuns().get(0).getFont().getName()); + Assert.assertEquals(Color.RED.getRGB(), dstDoc.getFirstSection().getBody().getParagraphs().get(1).getRuns().get(0).getFont().getColor().getRGB()); + } + + @Test + public void emphasesWarningSourceMarkdown() throws Exception + { + //ExStart + //ExFor:WarningInfo.Source + //ExFor:WarningSource + //ExSummary:Shows how to work with the warning source. + Document doc = new Document(getMyDir() + "Emphases markdown warning.docx"); + + WarningInfoCollection warnings = new WarningInfoCollection(); + doc.setWarningCallback(warnings); + doc.save(getArtifactsDir() + "DocumentBuilder.EmphasesWarningSourceMarkdown.md"); + + for (WarningInfo warningInfo : warnings) { + if (warningInfo.getSource() == WarningSource.MARKDOWN) + Assert.assertEquals("The (*, 0:11) cannot be properly written into Markdown.", warningInfo.getDescription()); + } + //ExEnd + } + + @Test + public void doNotIgnoreHeaderFooter() throws Exception { + //ExStart + //ExFor:ImportFormatOptions.IgnoreHeaderFooter + //ExSummary:Shows how to specifies ignoring or not source formatting of headers/footers content. + Document dstDoc = new Document(getMyDir() + "Document.docx"); + Document srcDoc = new Document(getMyDir() + "Header and footer types.docx"); + + // If 'IgnoreHeaderFooter' is false then the original formatting for header/footer content + // from "Header and footer types.docx" will be used. + // If 'IgnoreHeaderFooter' is true then the formatting for header/footer content + // from "Document.docx" will be used. + ImportFormatOptions importFormatOptions = new ImportFormatOptions(); + importFormatOptions.setIgnoreHeaderFooter(false); + + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING, importFormatOptions); + + dstDoc.save(getArtifactsDir() + "DocumentBuilder.DoNotIgnoreHeaderFooter.docx"); + //ExEnd + } + + public void markdownDocumentEmphases() throws Exception { + DocumentBuilder builder = new DocumentBuilder(); + + // Bold and Italic are represented as Font.Bold and Font.Italic. + builder.getFont().setItalic(true); + builder.writeln("This text will be italic"); + + // Use clear formatting if we don't want to combine styles between paragraphs. + builder.getFont().clearFormatting(); + + builder.getFont().setBold(true); + builder.writeln("This text will be bold"); + + builder.getFont().clearFormatting(); + + builder.getFont().setItalic(true); + builder.write("You "); + builder.getFont().setBold(true); + builder.write("can"); + builder.getFont().setBold(false); + builder.writeln(" combine them"); + + builder.getFont().clearFormatting(); + + builder.getFont().setStrikeThrough(true); + builder.writeln("This text will be strikethrough"); + + // Markdown treats asterisks (*), underscores (_) and tilde (~) as indicators of emphasis. + builder.getDocument().save(getArtifactsDir() + "DocumentBuilder.MarkdownDocument.md"); + } + + public void markdownDocumentInlineCode() throws Exception { + Document doc = new Document(getArtifactsDir() + "DocumentBuilder.MarkdownDocument.md"); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Prepare our created document for further work + // and clear paragraph formatting not to use the previous styles. + builder.moveToDocumentEnd(); + builder.getParagraphFormat().clearFormatting(); + builder.writeln("\n"); + + // Style with name that starts from word InlineCode, followed by optional dot (.) and number of backticks (`). + // If number of backticks is missed, then one backtick will be used by default. + Style inlineCode1BackTicks = doc.getStyles().add(StyleType.CHARACTER, "InlineCode"); + builder.getFont().setStyle(inlineCode1BackTicks); + builder.writeln("Text with InlineCode style with one backtick"); + + // Use optional dot (.) and number of backticks (`). + // There will be 3 backticks. + Style inlineCode3BackTicks = doc.getStyles().add(StyleType.CHARACTER, "InlineCode.3"); + builder.getFont().setStyle(inlineCode3BackTicks); + builder.writeln("Text with InlineCode style with 3 backticks"); + + builder.getDocument().save(getArtifactsDir() + "DocumentBuilder.MarkdownDocument.md"); + } + + public void markdownDocumentHeadings() throws Exception { + Document doc = new Document(getArtifactsDir() + "DocumentBuilder.MarkdownDocument.md"); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Prepare our created document for further work + // and clear paragraph formatting not to use the previous styles. + builder.moveToDocumentEnd(); + builder.getParagraphFormat().clearFormatting(); + builder.writeln("\n"); + + // By default, Heading styles in Word may have bold and italic formatting. + // If we do not want text to be emphasized, set these properties explicitly to false. + // Thus we can't use 'builder.Font.ClearFormatting()' because Bold/Italic will be set to true. + builder.getFont().setBold(false); + builder.getFont().setItalic(false); + + // Create for one heading for each level. + builder.getParagraphFormat().setStyleName("Heading 1"); + builder.getFont().setItalic(true); + builder.writeln("This is an italic H1 tag"); + + // Reset our styles from the previous paragraph to not combine styles between paragraphs. + builder.getFont().setBold(false); + builder.getFont().setItalic(false); + + // Structure-enhanced text heading can be added through style inheritance. + Style setextHeading1 = doc.getStyles().add(StyleType.PARAGRAPH, "SetextHeading1"); + builder.getParagraphFormat().setStyle(setextHeading1); + doc.getStyles().get("SetextHeading1").setBaseStyleName("Heading 1"); + builder.writeln("SetextHeading 1"); + + builder.getParagraphFormat().setStyleName("Heading 2"); + builder.writeln("This is an H2 tag"); + + builder.getFont().setBold(false); + builder.getFont().setItalic(false); + + Style setextHeading2 = doc.getStyles().add(StyleType.PARAGRAPH, "SetextHeading2"); + builder.getParagraphFormat().setStyle(setextHeading2); + doc.getStyles().get("SetextHeading2").setBaseStyleName("Heading 2"); + builder.writeln("SetextHeading 2"); + + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 3")); + builder.writeln("This is an H3 tag"); + + builder.getFont().setBold(false); + builder.getFont().setItalic(false); + + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 4")); + builder.getFont().setBold(true); + builder.writeln("This is an bold H4 tag"); + + builder.getFont().setBold(false); + builder.getFont().setItalic(false); + + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 5")); + builder.getFont().setItalic(true); + builder.getFont().setBold(true); + builder.writeln("This is an italic and bold H5 tag"); + + builder.getFont().setBold(false); + builder.getFont().setItalic(false); + + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 6")); + builder.writeln("This is an H6 tag"); + + doc.save(getArtifactsDir() + "DocumentBuilder.MarkdownDocument.md"); + } + + public void markdownDocumentBlockquotes() throws Exception { + Document doc = new Document(getArtifactsDir() + "DocumentBuilder.MarkdownDocument.md"); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Prepare our created document for further work + // and clear paragraph formatting not to use the previous styles. + builder.moveToDocumentEnd(); + builder.getParagraphFormat().clearFormatting(); + builder.writeln("\n"); + + // By default, the document stores blockquote style for the first level. + builder.getParagraphFormat().setStyleName("Quote"); + builder.writeln("Blockquote"); + + // Create styles for nested levels through style inheritance. + Style quoteLevel2 = doc.getStyles().add(StyleType.PARAGRAPH, "Quote1"); + builder.getParagraphFormat().setStyle(quoteLevel2); + doc.getStyles().get("Quote1").setBaseStyleName("Quote"); + builder.writeln("1. Nested blockquote"); + + Style quoteLevel3 = doc.getStyles().add(StyleType.PARAGRAPH, "Quote2"); + builder.getParagraphFormat().setStyle(quoteLevel3); + doc.getStyles().get("Quote2").setBaseStyleName("Quote1"); + builder.getFont().setItalic(true); + builder.writeln("2. Nested italic blockquote"); + + Style quoteLevel4 = doc.getStyles().add(StyleType.PARAGRAPH, "Quote3"); + builder.getParagraphFormat().setStyle(quoteLevel4); + doc.getStyles().get("Quote3").setBaseStyleName("Quote2"); + builder.getFont().setItalic(false); + builder.getFont().setBold(true); + builder.writeln("3. Nested bold blockquote"); + + Style quoteLevel5 = doc.getStyles().add(StyleType.PARAGRAPH, "Quote4"); + builder.getParagraphFormat().setStyle(quoteLevel5); + doc.getStyles().get("Quote4").setBaseStyleName("Quote3"); + builder.getFont().setBold(false); + builder.writeln("4. Nested blockquote"); + + Style quoteLevel6 = doc.getStyles().add(StyleType.PARAGRAPH, "Quote5"); + builder.getParagraphFormat().setStyle(quoteLevel6); + doc.getStyles().get("Quote5").setBaseStyleName("Quote4"); + builder.writeln("5. Nested blockquote"); + + Style quoteLevel7 = doc.getStyles().add(StyleType.PARAGRAPH, "Quote6"); + builder.getParagraphFormat().setStyle(quoteLevel7); + doc.getStyles().get("Quote6").setBaseStyleName("Quote5"); + builder.getFont().setItalic(true); + builder.getFont().setBold(true); + builder.writeln("6. Nested italic bold blockquote"); + + doc.save(getArtifactsDir() + "DocumentBuilder.MarkdownDocument.md"); + } + + public void markdownDocumentIndentedCode() throws Exception { + Document doc = new Document(getArtifactsDir() + "DocumentBuilder.MarkdownDocument.md"); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Prepare our created document for further work + // and clear paragraph formatting not to use the previous styles. + builder.moveToDocumentEnd(); + builder.writeln("\n"); + builder.getParagraphFormat().clearFormatting(); + builder.writeln("\n"); + + Style indentedCode = doc.getStyles().add(StyleType.PARAGRAPH, "IndentedCode"); + builder.getParagraphFormat().setStyle(indentedCode); + builder.writeln("This is an indented code"); + + doc.save(getArtifactsDir() + "DocumentBuilder.MarkdownDocument.md"); + } + + public void markdownDocumentFencedCode() throws Exception { + Document doc = new Document(getArtifactsDir() + "DocumentBuilder.MarkdownDocument.md"); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Prepare our created document for further work + // and clear paragraph formatting not to use the previous styles. + builder.moveToDocumentEnd(); + builder.writeln("\n"); + builder.getParagraphFormat().clearFormatting(); + builder.writeln("\n"); + + Style fencedCode = doc.getStyles().add(StyleType.PARAGRAPH, "FencedCode"); + builder.getParagraphFormat().setStyle(fencedCode); + builder.writeln("This is a fenced code"); + + Style fencedCodeWithInfo = doc.getStyles().add(StyleType.PARAGRAPH, "FencedCode.C#"); + builder.getParagraphFormat().setStyle(fencedCodeWithInfo); + builder.writeln("This is a fenced code with info string"); + + doc.save(getArtifactsDir() + "DocumentBuilder.MarkdownDocument.md"); + } + + public void markdownDocumentHorizontalRule() throws Exception { + Document doc = new Document(getArtifactsDir() + "DocumentBuilder.MarkdownDocument.md"); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Prepare our created document for further work + // and clear paragraph formatting not to use the previous styles. + builder.moveToDocumentEnd(); + builder.getParagraphFormat().clearFormatting(); + builder.writeln("\n"); + + // Insert HorizontalRule that will be present in .md file as '-----'. + builder.insertHorizontalRule(); + + builder.getDocument().save(getArtifactsDir() + "DocumentBuilder.MarkdownDocument.md"); + } + + public void markdownDocumentBulletedList() throws Exception { + Document doc = new Document(getArtifactsDir() + "DocumentBuilder.MarkdownDocument.md"); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Prepare our created document for further work + // and clear paragraph formatting not to use the previous styles. + builder.moveToDocumentEnd(); + builder.getParagraphFormat().clearFormatting(); + builder.writeln("\n"); + + // Bulleted lists are represented using paragraph numbering. + builder.getListFormat().applyBulletDefault(); + // There can be 3 types of bulleted lists. + // The only diff in a numbering format of the very first level are ‘-’, ‘+’ or ‘*’ respectively. + builder.getListFormat().getList().getListLevels().get(0).setNumberFormat("-"); + + builder.writeln("Item 1"); + builder.writeln("Item 2"); + builder.getListFormat().listIndent(); + builder.writeln("Item 2a"); + builder.writeln("Item 2b"); + + builder.getDocument().save(getArtifactsDir() + "DocumentBuilder.MarkdownDocument.md"); + } + + @Test (description = "WORDSNET-19850", dataProvider = "loadMarkdownDocumentAndAssertContentDataProvider") + public void loadMarkdownDocumentAndAssertContent(String text, String styleName, boolean isItalic, boolean isBold) throws Exception { + // Prepare document to test. + markdownDocumentEmphases(); + markdownDocumentInlineCode(); + markdownDocumentHeadings(); + markdownDocumentBlockquotes(); + markdownDocumentIndentedCode(); + markdownDocumentFencedCode(); + markdownDocumentHorizontalRule(); + markdownDocumentBulletedList(); + + // Load created document from previous tests. + Document doc = new Document(getArtifactsDir() + "DocumentBuilder.MarkdownDocument.md"); + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + for (Paragraph paragraph : paragraphs) { + if (paragraph.getRuns().getCount() != 0) { + // Check that all document text has the necessary styles. + if (paragraph.getRuns().get(0).getText().equals(text) && !text.contains("InlineCode")) { + Assert.assertEquals(styleName, paragraph.getParagraphFormat().getStyle().getName()); + Assert.assertEquals(isItalic, paragraph.getRuns().get(0).getFont().getItalic()); + Assert.assertEquals(isBold, paragraph.getRuns().get(0).getFont().getBold()); + } else if (paragraph.getRuns().get(0).getText().equals(text) && text.contains("InlineCode")) { + Assert.assertEquals(styleName, paragraph.getRuns().get(0).getFont().getStyleName()); + } + } + + // Check that document also has a HorizontalRule present as a shape. + NodeCollection shapesCollection = doc.getFirstSection().getBody().getChildNodes(NodeType.SHAPE, true); + Shape horizontalRuleShape = (Shape) shapesCollection.get(0); + + Assert.assertTrue(shapesCollection.getCount() == 1); + Assert.assertTrue(horizontalRuleShape.isHorizontalRule()); + } + } + + @DataProvider(name = "loadMarkdownDocumentAndAssertContentDataProvider") + public static Object[][] loadMarkdownDocumentAndAssertContentDataProvider() throws Exception { + return new Object[][] + { + {"Italic", "Normal", true, false}, + {"Bold", "Normal", false, true}, + {"ItalicBold", "Normal", true, true}, + {"Text with InlineCode style with one backtick", "InlineCode", false, false}, + {"Text with InlineCode style with 3 backticks", "InlineCode.3", false, false}, + {"This is an italic H1 tag", "Heading 1", true, false}, + {"SetextHeading 1", "SetextHeading1", false, false}, + {"This is an H2 tag", "Heading 2", false, false}, + {"SetextHeading 2", "SetextHeading2", false, false}, + {"This is an H3 tag", "Heading 3", false, false}, + {"This is an bold H4 tag", "Heading 4", false, true}, + {"This is an italic and bold H5 tag", "Heading 5", true, true}, + {"This is an H6 tag", "Heading 6", false, false}, + {"Blockquote", "Quote", false, false}, + {"1. Nested blockquote", "Quote1", false, false}, + {"2. Nested italic blockquote", "Quote2", true, false}, + {"3. Nested bold blockquote", "Quote3", false, true}, + {"4. Nested blockquote", "Quote4", false, false}, + {"5. Nested blockquote", "Quote5", false, false}, + {"6. Nested italic bold blockquote", "Quote6", true, true}, + {"This is an indented code", "IndentedCode", false, false}, + {"This is a fenced code", "FencedCode", false, false}, + {"This is a fenced code with info string", "FencedCode.C#", false, false}, + {"Item 1", "Normal", false, false}, + }; + } + + @Test(dataProvider = "markdownDocumentTableContentAlignmentDataProvider") + public void markdownDocumentTableContentAlignment(int tableContentAlignment) throws Exception { + DocumentBuilder builder = new DocumentBuilder(); + + builder.insertCell(); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.RIGHT); + builder.write("Cell1"); + builder.insertCell(); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.write("Cell2"); + + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + saveOptions.setTableContentAlignment(tableContentAlignment); + + builder.getDocument().save(getArtifactsDir() + "DocumentBuilder.MarkdownDocumentTableContentAlignment.md", saveOptions); + + Document doc = new Document(getArtifactsDir() + "DocumentBuilder.MarkdownDocumentTableContentAlignment.md"); + Table table = doc.getFirstSection().getBody().getTables().get(0); + + switch (tableContentAlignment) { + case TableContentAlignment.AUTO: + Assert.assertEquals(ParagraphAlignment.RIGHT, + table.getFirstRow().getCells().get(0).getFirstParagraph().getParagraphFormat().getAlignment()); + Assert.assertEquals(ParagraphAlignment.CENTER, + table.getFirstRow().getCells().get(1).getFirstParagraph().getParagraphFormat().getAlignment()); + break; + case TableContentAlignment.LEFT: + Assert.assertEquals(ParagraphAlignment.LEFT, + table.getFirstRow().getCells().get(0).getFirstParagraph().getParagraphFormat().getAlignment()); + Assert.assertEquals(ParagraphAlignment.LEFT, + table.getFirstRow().getCells().get(1).getFirstParagraph().getParagraphFormat().getAlignment()); + break; + case TableContentAlignment.CENTER: + Assert.assertEquals(ParagraphAlignment.CENTER, + table.getFirstRow().getCells().get(0).getFirstParagraph().getParagraphFormat().getAlignment()); + Assert.assertEquals(ParagraphAlignment.CENTER, + table.getFirstRow().getCells().get(1).getFirstParagraph().getParagraphFormat().getAlignment()); + break; + case TableContentAlignment.RIGHT: + Assert.assertEquals(ParagraphAlignment.RIGHT, + table.getFirstRow().getCells().get(0).getFirstParagraph().getParagraphFormat().getAlignment()); + Assert.assertEquals(ParagraphAlignment.RIGHT, + table.getFirstRow().getCells().get(1).getFirstParagraph().getParagraphFormat().getAlignment()); + break; + } + } + + @DataProvider(name = "markdownDocumentTableContentAlignmentDataProvider") + public static Object[][] markdownDocumentTableContentAlignmentDataProvider() { + return new Object[][] + { + {TableContentAlignment.LEFT}, + {TableContentAlignment.RIGHT}, + {TableContentAlignment.CENTER}, + {TableContentAlignment.AUTO}, + }; + } + + @Test + public void insertOnlineVideo() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertOnlineVideo(String, RelativeHorizontalPosition, Double, RelativeVerticalPosition, Double, Double, Double, WrapType) + //ExSummary:Shows how to insert an online video into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + String videoUrl = "https://vimeo.com/52477838"; + + // Insert a shape that plays a video from the web when clicked in Microsoft Word. + // This rectangular shape will contain an image based on the first frame of the linked video + // and a "play button" visual prompt. The video has an aspect ratio of 16:9. + // We will set the shape's size to that ratio, so the image does not appear stretched. + builder.insertOnlineVideo(videoUrl, RelativeHorizontalPosition.LEFT_MARGIN, 0.0, + RelativeVerticalPosition.TOP_MARGIN, 0.0, 320.0, 180.0, WrapType.SQUARE); + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertOnlineVideo.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertOnlineVideo.docx"); + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(640, 360, ImageType.JPEG, shape); + + Assert.assertEquals(320.0d, shape.getWidth()); + Assert.assertEquals(180.0d, shape.getHeight()); + Assert.assertEquals(0.0d, shape.getLeft()); + Assert.assertEquals(0.0d, shape.getTop()); + Assert.assertEquals(WrapType.SQUARE, shape.getWrapType()); + Assert.assertEquals(RelativeVerticalPosition.TOP_MARGIN, shape.getRelativeVerticalPosition()); + Assert.assertEquals(RelativeHorizontalPosition.LEFT_MARGIN, shape.getRelativeHorizontalPosition()); + + Assert.assertEquals("https://vimeo.com/52477838", shape.getHRef()); + TestUtil.verifyWebResponseStatusCode(200, new URL(shape.getHRef())); + } + + @Test + public void insertOnlineVideoCustomThumbnail() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertOnlineVideo(String, String, Byte[], Double, Double) + //ExFor:DocumentBuilder.InsertOnlineVideo(String, String, Byte[], RelativeHorizontalPosition, Double, RelativeVerticalPosition, Double, Double, Double, WrapType) + //ExSummary:Shows how to insert an online video into a document with a custom thumbnail. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + String videoUrl = "https://vimeo.com/52477838"; + String videoEmbedCode = ""; + + byte[] thumbnailImageBytes = IOUtils.toByteArray(getAsposelogoUri().toURL().openStream()); + + BufferedImage image = ImageIO.read(new ByteArrayInputStream(thumbnailImageBytes)); + + // Below are two ways of creating a shape with a custom thumbnail, which links to an online video + // that will play when we click on the shape in Microsoft Word. + // 1 - Insert an inline shape at the builder's node insertion cursor: + builder.insertOnlineVideo(videoUrl, videoEmbedCode, thumbnailImageBytes, image.getWidth(), image.getHeight()); + + builder.insertBreak(BreakType.PAGE_BREAK); + + // 2 - Insert a floating shape: + double left = builder.getPageSetup().getRightMargin() - image.getWidth(); + double top = builder.getPageSetup().getBottomMargin() - image.getHeight(); + + builder.insertOnlineVideo(videoUrl, videoEmbedCode, thumbnailImageBytes, + RelativeHorizontalPosition.RIGHT_MARGIN, left, RelativeVerticalPosition.BOTTOM_MARGIN, top, + image.getWidth(), image.getHeight(), WrapType.SQUARE); + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertOnlineVideoCustomThumbnail.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilder.InsertOnlineVideoCustomThumbnail.docx"); + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(272, 92, ImageType.PNG, shape); + Assert.assertEquals(272.0d, shape.getWidth()); + Assert.assertEquals(92.0d, shape.getHeight()); + Assert.assertEquals(0.0d, shape.getLeft()); + Assert.assertEquals(0.0d, shape.getTop()); + Assert.assertEquals(WrapType.INLINE, shape.getWrapType()); + Assert.assertEquals(RelativeVerticalPosition.PARAGRAPH, shape.getRelativeVerticalPosition()); + Assert.assertEquals(RelativeHorizontalPosition.COLUMN, shape.getRelativeHorizontalPosition()); + + Assert.assertEquals("https://vimeo.com/52477838", shape.getHRef()); + + shape = (Shape) doc.getChild(NodeType.SHAPE, 1, true); + + TestUtil.verifyImageInShape(272, 92, ImageType.PNG, shape); + Assert.assertEquals(272, shape.getWidth()); + Assert.assertEquals(92.0d, shape.getHeight()); + Assert.assertEquals(-200.0d, shape.getLeft()); + Assert.assertEquals(-20.0d, shape.getTop()); + Assert.assertEquals(WrapType.SQUARE, shape.getWrapType()); + Assert.assertEquals(RelativeVerticalPosition.BOTTOM_MARGIN, shape.getRelativeVerticalPosition()); + Assert.assertEquals(RelativeHorizontalPosition.RIGHT_MARGIN, shape.getRelativeHorizontalPosition()); + + Assert.assertEquals("https://vimeo.com/52477838", shape.getHRef()); + TestUtil.verifyWebResponseStatusCode(200, new URL(shape.getHRef())); + } + + @Test + public void insertOleObjectAsIcon() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertOleObjectAsIcon(String, String, Boolean, String, String) + //ExFor:DocumentBuilder.InsertOleObjectAsIcon(Stream, String, String, String) + //ExSummary:Shows how to insert an embedded or linked OLE object as icon into the document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // If 'iconFile' and 'iconCaption' are omitted, this overloaded method selects + // the icon according to 'progId' and uses the filename for the icon caption. + builder.insertOleObjectAsIcon(getMyDir() + "Presentation.pptx", "Package", false, getImageDir() + "Logo icon.ico", "My embedded file"); + + builder.insertBreak(BreakType.LINE_BREAK); + + try (FileInputStream stream = new FileInputStream(getMyDir() + "Presentation.pptx")) { + // If 'iconFile' and 'iconCaption' are omitted, this overloaded method selects + // the icon according to the file extension and uses the filename for the icon caption. + Shape shape = builder.insertOleObjectAsIcon(stream, "PowerPoint.Application", getImageDir() + "Logo icon.ico", + "My embedded file stream"); + + OlePackage setOlePackage = shape.getOleFormat().getOlePackage(); + setOlePackage.setFileName("Presentation.pptx"); + setOlePackage.setDisplayName("Presentation.pptx"); + } + + doc.save(getArtifactsDir() + "DocumentBuilder.InsertOleObjectAsIcon.docx"); + //ExEnd + } + + @Test + public void preserveBlocks() throws Exception + { + //ExStart + //ExFor:HtmlInsertOptions + //ExSummary:Shows how to allows better preserve borders and margins seen. + final String HTML = "\n \n
\n
\n

paragraph 1

\n

paragraph 2

\n
\n
\n "; + + // Set the new mode of import HTML block-level elements. + int insertOptions = HtmlInsertOptions.PRESERVE_BLOCKS; + + DocumentBuilder builder = new DocumentBuilder(); + builder.insertHtml(HTML, insertOptions); + builder.getDocument().save(getArtifactsDir() + "DocumentBuilder.PreserveBlocks.docx"); + //ExEnd + } + + @Test + public void phoneticGuide() throws Exception + { + //ExStart + //ExFor:Run.IsPhoneticGuide + //ExFor:Run.PhoneticGuide + //ExFor:PhoneticGuide.BaseText + //ExFor:PhoneticGuide.RubyText + //ExSummary:Shows how to get properties of the phonetic guide. + Document doc = new Document(getMyDir() + "Phonetic guide.docx"); + + RunCollection runs = doc.getFirstSection().getBody().getFirstParagraph().getRuns(); + // Use phonetic guide in the Asian text. + Assert.assertEquals(true, runs.get(0).isPhoneticGuide()); + + PhoneticGuide phoneticGuide = runs.get(0).getPhoneticGuide(); + Assert.assertEquals("base", phoneticGuide.getBaseText()); + Assert.assertEquals("ruby", phoneticGuide.getRubyText()); + //ExEnd + + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExDocumentBuilderImages.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExDocumentBuilderImages.java new file mode 100644 index 00000000..d667a72d --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExDocumentBuilderImages.java @@ -0,0 +1,383 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.apache.commons.io.IOUtils; +import org.testng.Assert; +import org.testng.annotations.Test; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; + +@Test +public class ExDocumentBuilderImages extends ApiExampleBase { + @Test + public void insertImageFromStream() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertImage(Stream) + //ExFor:DocumentBuilder.InsertImage(Stream, Double, Double) + //ExFor:DocumentBuilder.InsertImage(Stream, RelativeHorizontalPosition, Double, RelativeVerticalPosition, Double, Double, Double, WrapType) + //ExSummary:Shows how to insert an image from a stream into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create reusable stream. + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + IOUtils.copy(new FileInputStream(getImageDir() + "Logo.jpg"), byteArrayOutputStream); + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); + + // Below are three ways of inserting an image from a stream. + // 1 - Inline shape with a default size based on the image's original dimensions: + builder.insertImage(byteArrayInputStream); + + builder.insertBreak(BreakType.PAGE_BREAK); + byteArrayInputStream.reset(); + + // 2 - Inline shape with custom dimensions: + builder.insertImage(byteArrayInputStream, ConvertUtil.pixelToPoint(250.0), ConvertUtil.pixelToPoint(144.0)); + + builder.insertBreak(BreakType.PAGE_BREAK); + byteArrayInputStream.reset(); + + // 3 - Floating shape with custom dimensions: + builder.insertImage(byteArrayInputStream, RelativeHorizontalPosition.MARGIN, 100.0, RelativeVerticalPosition.MARGIN, + 100.0, 200.0, 100.0, WrapType.SQUARE); + + doc.save(getArtifactsDir() + "DocumentBuilderImages.InsertImageFromStream.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilderImages.InsertImageFromStream.docx"); + + Shape imageShape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(300.0d, imageShape.getHeight()); + Assert.assertEquals(300.0d, imageShape.getWidth()); + Assert.assertEquals(0.0d, imageShape.getLeft()); + Assert.assertEquals(0.0d, imageShape.getTop()); + + Assert.assertEquals(WrapType.INLINE, imageShape.getWrapType()); + Assert.assertEquals(RelativeHorizontalPosition.COLUMN, imageShape.getRelativeHorizontalPosition()); + Assert.assertEquals(RelativeVerticalPosition.PARAGRAPH, imageShape.getRelativeVerticalPosition()); + + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, imageShape); + Assert.assertEquals(300.0d, imageShape.getImageData().getImageSize().getHeightPoints()); + Assert.assertEquals(300.0d, imageShape.getImageData().getImageSize().getWidthPoints()); + + imageShape = (Shape) doc.getChild(NodeType.SHAPE, 1, true); + + Assert.assertEquals(108.0d, imageShape.getHeight()); + Assert.assertEquals(187.5d, imageShape.getWidth()); + Assert.assertEquals(0.0d, imageShape.getLeft()); + Assert.assertEquals(0.0d, imageShape.getTop()); + + Assert.assertEquals(WrapType.INLINE, imageShape.getWrapType()); + Assert.assertEquals(RelativeHorizontalPosition.COLUMN, imageShape.getRelativeHorizontalPosition()); + Assert.assertEquals(RelativeVerticalPosition.PARAGRAPH, imageShape.getRelativeVerticalPosition()); + + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, imageShape); + Assert.assertEquals(300.0d, imageShape.getImageData().getImageSize().getHeightPoints()); + Assert.assertEquals(300.0d, imageShape.getImageData().getImageSize().getWidthPoints()); + + imageShape = (Shape) doc.getChild(NodeType.SHAPE, 2, true); + + Assert.assertEquals(100.0d, imageShape.getHeight()); + Assert.assertEquals(200.0d, imageShape.getWidth()); + Assert.assertEquals(100.0d, imageShape.getLeft()); + Assert.assertEquals(100.0d, imageShape.getTop()); + + Assert.assertEquals(WrapType.SQUARE, imageShape.getWrapType()); + Assert.assertEquals(RelativeHorizontalPosition.MARGIN, imageShape.getRelativeHorizontalPosition()); + Assert.assertEquals(RelativeVerticalPosition.MARGIN, imageShape.getRelativeVerticalPosition()); + + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, imageShape); + Assert.assertEquals(300.0d, imageShape.getImageData().getImageSize().getHeightPoints()); + Assert.assertEquals(300.0d, imageShape.getImageData().getImageSize().getWidthPoints()); + } + + @Test + public void insertImageFromFilename() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertImage(String) + //ExFor:DocumentBuilder.InsertImage(String, Double, Double) + //ExFor:DocumentBuilder.InsertImage(String, RelativeHorizontalPosition, Double, RelativeVerticalPosition, Double, Double, Double, WrapType) + //ExSummary:Shows how to insert an image from the local file system into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are three ways of inserting an image from a local system filename. + // 1 - Inline shape with a default size based on the image's original dimensions: + builder.insertImage(getImageDir() + "Logo.jpg"); + + builder.insertBreak(BreakType.PAGE_BREAK); + + // 2 - Inline shape with custom dimensions: + builder.insertImage(getImageDir() + "Transparent background logo.png", ConvertUtil.pixelToPoint(250.0), + ConvertUtil.pixelToPoint(144.0)); + + builder.insertBreak(BreakType.PAGE_BREAK); + + // 3 - Floating shape with custom dimensions: + builder.insertImage(getImageDir() + "Windows MetaFile.wmf", RelativeHorizontalPosition.MARGIN, 100.0, + RelativeVerticalPosition.MARGIN, 100.0, 200.0, 100.0, WrapType.SQUARE); + + doc.save(getArtifactsDir() + "DocumentBuilderImages.InsertImageFromFilename.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilderImages.InsertImageFromFilename.docx"); + + Shape imageShape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(300.0d, imageShape.getHeight()); + Assert.assertEquals(300.0d, imageShape.getWidth()); + Assert.assertEquals(0.0d, imageShape.getLeft()); + Assert.assertEquals(0.0d, imageShape.getTop()); + + Assert.assertEquals(WrapType.INLINE, imageShape.getWrapType()); + Assert.assertEquals(RelativeHorizontalPosition.COLUMN, imageShape.getRelativeHorizontalPosition()); + Assert.assertEquals(RelativeVerticalPosition.PARAGRAPH, imageShape.getRelativeVerticalPosition()); + + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, imageShape); + Assert.assertEquals(300.0d, imageShape.getImageData().getImageSize().getHeightPoints()); + Assert.assertEquals(300.0d, imageShape.getImageData().getImageSize().getWidthPoints()); + + imageShape = (Shape) doc.getChild(NodeType.SHAPE, 1, true); + + Assert.assertEquals(108.0d, imageShape.getHeight()); + Assert.assertEquals(187.5d, imageShape.getWidth()); + Assert.assertEquals(0.0d, imageShape.getLeft()); + Assert.assertEquals(0.0d, imageShape.getTop()); + + Assert.assertEquals(WrapType.INLINE, imageShape.getWrapType()); + Assert.assertEquals(RelativeHorizontalPosition.COLUMN, imageShape.getRelativeHorizontalPosition()); + Assert.assertEquals(RelativeVerticalPosition.PARAGRAPH, imageShape.getRelativeVerticalPosition()); + + TestUtil.verifyImageInShape(400, 400, ImageType.PNG, imageShape); + Assert.assertEquals(300.0d, imageShape.getImageData().getImageSize().getHeightPoints()); + Assert.assertEquals(300.0d, imageShape.getImageData().getImageSize().getWidthPoints()); + + imageShape = (Shape) doc.getChild(NodeType.SHAPE, 2, true); + + Assert.assertEquals(100.0d, imageShape.getHeight()); + Assert.assertEquals(200.0d, imageShape.getWidth()); + Assert.assertEquals(100.0d, imageShape.getLeft()); + Assert.assertEquals(100.0d, imageShape.getTop()); + + Assert.assertEquals(WrapType.SQUARE, imageShape.getWrapType()); + Assert.assertEquals(RelativeHorizontalPosition.MARGIN, imageShape.getRelativeHorizontalPosition()); + Assert.assertEquals(RelativeVerticalPosition.MARGIN, imageShape.getRelativeVerticalPosition()); + + TestUtil.verifyImageInShape(1600, 1600, ImageType.WMF, imageShape); + Assert.assertEquals(400.0d, imageShape.getImageData().getImageSize().getHeightPoints()); + Assert.assertEquals(400.0d, imageShape.getImageData().getImageSize().getWidthPoints()); + } + + @Test + public void insertSvgImage() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertImage(String) + //ExSummary:Shows how to determine which image will be inserted. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertImage(getImageDir() + "Scalable Vector Graphics.svg"); + + // Aspose.Words insert SVG image to the document as PNG with svgBlip extension + // that contains the original vector SVG image representation. + doc.save(getArtifactsDir() + "DocumentBuilderImages.InsertSvgImage.SvgWithSvgBlip.docx"); + + // Aspose.Words insert SVG image to the document as PNG, just like Microsoft Word does for old format. + doc.save(getArtifactsDir() + "DocumentBuilderImages.InsertSvgImage.Svg.doc"); + + doc.getCompatibilityOptions().optimizeFor(MsWordVersion.WORD_2003); + + // Aspose.Words insert SVG image to the document as EMF metafile to keep the image in vector representation. + doc.save(getArtifactsDir() + "DocumentBuilderImages.InsertSvgImage.Emf.docx"); + //ExEnd + } + + @Test + public void insertImageFromImageObject() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertImage(Image) + //ExFor:DocumentBuilder.InsertImage(Image, Double, Double) + //ExFor:DocumentBuilder.InsertImage(Image, RelativeHorizontalPosition, Double, RelativeVerticalPosition, Double, Double, Double, WrapType) + //ExSummary:Shows how to insert an image from an object into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + String imageFile = getImageDir() + "Logo.jpg"; + + // Below are three ways of inserting an image from an Image object instance. + // 1 - Inline shape with a default size based on the image's original dimensions: + builder.insertImage(imageFile); + + builder.insertBreak(BreakType.PAGE_BREAK); + + // 2 - Inline shape with custom dimensions: + builder.insertImage(imageFile, ConvertUtil.pixelToPoint(250.0), ConvertUtil.pixelToPoint(144.0)); + + builder.insertBreak(BreakType.PAGE_BREAK); + + // 3 - Floating shape with custom dimensions: + builder.insertImage(imageFile, RelativeHorizontalPosition.MARGIN, 100.0, RelativeVerticalPosition.MARGIN, + 100.0, 200.0, 100.0, WrapType.SQUARE); + + doc.save(getArtifactsDir() + "DocumentBuilderImages.InsertImageFromImageObject.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilderImages.InsertImageFromImageObject.docx"); + + Shape imageShape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(300.0d, imageShape.getHeight(), 1); + Assert.assertEquals(300.0d, imageShape.getWidth(), 1); + Assert.assertEquals(0.0d, imageShape.getLeft()); + Assert.assertEquals(0.0d, imageShape.getTop()); + + Assert.assertEquals(WrapType.INLINE, imageShape.getWrapType()); + Assert.assertEquals(RelativeHorizontalPosition.COLUMN, imageShape.getRelativeHorizontalPosition()); + Assert.assertEquals(RelativeVerticalPosition.PARAGRAPH, imageShape.getRelativeVerticalPosition()); + + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, imageShape); + Assert.assertEquals(300.0d, imageShape.getImageData().getImageSize().getHeightPoints(), 1); + Assert.assertEquals(300.0d, imageShape.getImageData().getImageSize().getWidthPoints(), 1); + + imageShape = (Shape) doc.getChild(NodeType.SHAPE, 1, true); + + Assert.assertEquals(108.0d, imageShape.getHeight()); + Assert.assertEquals(187.5d, imageShape.getWidth()); + Assert.assertEquals(0.0d, imageShape.getLeft()); + Assert.assertEquals(0.0d, imageShape.getTop()); + + Assert.assertEquals(WrapType.INLINE, imageShape.getWrapType()); + Assert.assertEquals(RelativeHorizontalPosition.COLUMN, imageShape.getRelativeHorizontalPosition()); + Assert.assertEquals(RelativeVerticalPosition.PARAGRAPH, imageShape.getRelativeVerticalPosition()); + + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, imageShape); + Assert.assertEquals(300.0d, imageShape.getImageData().getImageSize().getHeightPoints(), 1); + Assert.assertEquals(300.0d, imageShape.getImageData().getImageSize().getWidthPoints(), 1); + + imageShape = (Shape) doc.getChild(NodeType.SHAPE, 2, true); + + Assert.assertEquals(100.0d, imageShape.getHeight()); + Assert.assertEquals(200.0d, imageShape.getWidth()); + Assert.assertEquals(100.0d, imageShape.getLeft()); + Assert.assertEquals(100.0d, imageShape.getTop()); + + Assert.assertEquals(WrapType.SQUARE, imageShape.getWrapType()); + Assert.assertEquals(RelativeHorizontalPosition.MARGIN, imageShape.getRelativeHorizontalPosition()); + Assert.assertEquals(RelativeVerticalPosition.MARGIN, imageShape.getRelativeVerticalPosition()); + + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, imageShape); + Assert.assertEquals(300.0d, imageShape.getImageData().getImageSize().getHeightPoints(), 1); + Assert.assertEquals(300.0d, imageShape.getImageData().getImageSize().getWidthPoints(), 1); + } + + @Test + public void insertImageFromByteArray() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertImage(Byte[]) + //ExFor:DocumentBuilder.InsertImage(Byte[], Double, Double) + //ExFor:DocumentBuilder.InsertImage(Byte[], RelativeHorizontalPosition, Double, RelativeVerticalPosition, Double, Double, Double, WrapType) + //ExSummary:Shows how to insert an image from a byte array into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + byte[] imageByteArray = DocumentHelper.getBytesFromStream(new FileInputStream(getImageDir() + "Logo.jpg")); + + // Below are three ways of inserting an image from a byte array. + // 1 - Inline shape with a default size based on the image's original dimensions: + builder.insertImage(imageByteArray); + + builder.insertBreak(BreakType.PAGE_BREAK); + + // 2 - Inline shape with custom dimensions: + builder.insertImage(imageByteArray, ConvertUtil.pixelToPoint(250.0), ConvertUtil.pixelToPoint(144.0)); + + builder.insertBreak(BreakType.PAGE_BREAK); + + // 3 - Floating shape with custom dimensions: + builder.insertImage(imageByteArray, RelativeHorizontalPosition.MARGIN, 100.0, RelativeVerticalPosition.MARGIN, + 100.0, 200.0, 100.0, WrapType.SQUARE); + + doc.save(getArtifactsDir() + "DocumentBuilderImages.InsertImageFromByteArray.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentBuilderImages.InsertImageFromByteArray.docx"); + + Shape imageShape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(300.0d, imageShape.getHeight(), 0.1d); + Assert.assertEquals(300.0d, imageShape.getWidth(), 0.1d); + Assert.assertEquals(0.0d, imageShape.getLeft()); + Assert.assertEquals(0.0d, imageShape.getTop()); + + Assert.assertEquals(WrapType.INLINE, imageShape.getWrapType()); + Assert.assertEquals(RelativeHorizontalPosition.COLUMN, imageShape.getRelativeHorizontalPosition()); + Assert.assertEquals(RelativeVerticalPosition.PARAGRAPH, imageShape.getRelativeVerticalPosition()); + + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, imageShape); + Assert.assertEquals(300.0d, imageShape.getImageData().getImageSize().getHeightPoints(), 0.1d); + Assert.assertEquals(300.0d, imageShape.getImageData().getImageSize().getWidthPoints(), 0.1d); + + imageShape = (Shape) doc.getChild(NodeType.SHAPE, 1, true); + + Assert.assertEquals(108.0d, imageShape.getHeight()); + Assert.assertEquals(187.5d, imageShape.getWidth()); + Assert.assertEquals(0.0d, imageShape.getLeft()); + Assert.assertEquals(0.0d, imageShape.getTop()); + + Assert.assertEquals(WrapType.INLINE, imageShape.getWrapType()); + Assert.assertEquals(RelativeHorizontalPosition.COLUMN, imageShape.getRelativeHorizontalPosition()); + Assert.assertEquals(RelativeVerticalPosition.PARAGRAPH, imageShape.getRelativeVerticalPosition()); + + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, imageShape); + Assert.assertEquals(300.0d, imageShape.getImageData().getImageSize().getHeightPoints(), 0.1d); + Assert.assertEquals(300.0d, imageShape.getImageData().getImageSize().getWidthPoints(), 0.1d); + + imageShape = (Shape) doc.getChild(NodeType.SHAPE, 2, true); + + Assert.assertEquals(100.0d, imageShape.getHeight()); + Assert.assertEquals(200.0d, imageShape.getWidth()); + Assert.assertEquals(100.0d, imageShape.getLeft()); + Assert.assertEquals(100.0d, imageShape.getTop()); + + Assert.assertEquals(WrapType.SQUARE, imageShape.getWrapType()); + Assert.assertEquals(RelativeHorizontalPosition.MARGIN, imageShape.getRelativeHorizontalPosition()); + Assert.assertEquals(RelativeVerticalPosition.MARGIN, imageShape.getRelativeVerticalPosition()); + + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, imageShape); + Assert.assertEquals(300.0d, imageShape.getImageData().getImageSize().getHeightPoints(), 0.1d); + Assert.assertEquals(300.0d, imageShape.getImageData().getImageSize().getWidthPoints(), 0.1d); + } + + @Test + public void insertGif() throws Exception + { + //ExStart + //ExFor:DocumentBuilder.InsertImage(String) + //ExSummary:Shows how to insert gif image to the document. + DocumentBuilder builder = new DocumentBuilder(); + + // We can insert gif image using path or bytes array. + // It works only if DocumentBuilder optimized to Word version 2010 or higher. + // Note, that access to the image bytes causes conversion Gif to Png. + Shape gifImage = builder.insertImage(getImageDir() + "Graphics Interchange Format.gif"); + + gifImage = builder.insertImage(DocumentHelper.getBytesFromStream(new FileInputStream(getImageDir() + "Graphics Interchange Format.gif"))); + + builder.getDocument().save(getArtifactsDir() + "InsertGif.docx"); + //ExEnd + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExDocumentProperties.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExDocumentProperties.java new file mode 100644 index 00000000..e4c03e97 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExDocumentProperties.java @@ -0,0 +1,625 @@ +package Examples; + +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.apache.commons.io.FileUtils; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.FileInputStream; +import java.text.MessageFormat; +import java.time.Duration; +import java.util.Date; +import java.util.Iterator; + +@Test +public class ExDocumentProperties extends ApiExampleBase { + @Test + public void custom() throws Exception { + //ExStart + //ExFor:BuiltInDocumentProperties.Item(String) + //ExFor:CustomDocumentProperties + //ExFor:DocumentProperty.ToString + //ExFor:DocumentPropertyCollection.Count + //ExFor:DocumentPropertyCollection.Item(int) + //ExSummary:Shows how to work with custom document properties. + Document doc = new Document(getMyDir() + "Properties.docx"); + + // Every document contains a collection of custom properties, which, like the built-in properties, are key-value pairs. + // The document has a fixed list of built-in properties. The user creates all of the custom properties. + Assert.assertEquals("Value of custom document property", doc.getCustomDocumentProperties().get("CustomProperty").toString()); + + doc.getCustomDocumentProperties().add("CustomProperty2", "Value of custom document property #2"); + + System.out.println("Custom Properties:"); + for (DocumentProperty customDocumentProperty : doc.getCustomDocumentProperties()) { + System.out.println(customDocumentProperty.getName()); + System.out.println(MessageFormat.format("\tType:\t{0}", customDocumentProperty.getType())); + System.out.println(MessageFormat.format("\tValue:\t\"{0}\"", customDocumentProperty.getValue())); + } + //ExEnd + + Assert.assertEquals(2, doc.getCustomDocumentProperties().getCount()); + } + + @Test + public void description() throws Exception { + //ExStart + //ExFor:BuiltInDocumentProperties.Author + //ExFor:BuiltInDocumentProperties.Category + //ExFor:BuiltInDocumentProperties.Comments + //ExFor:BuiltInDocumentProperties.Keywords + //ExFor:BuiltInDocumentProperties.Subject + //ExFor:BuiltInDocumentProperties.Title + //ExSummary:Shows how to work with built-in document properties in the "Description" category. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + BuiltInDocumentProperties properties = doc.getBuiltInDocumentProperties(); + + // Below are four built-in document properties that have fields that can display their values in the document body. + // 1 - "Author" property, which we can display using an AUTHOR field: + properties.setAuthor("John Doe"); + builder.write("Author:\t"); + builder.insertField(FieldType.FIELD_AUTHOR, true); + + // 2 - "Title" property, which we can display using a TITLE field: + properties.setTitle("John's Document"); + builder.write("\nDoc title:\t"); + builder.insertField(FieldType.FIELD_TITLE, true); + + // 3 - "Subject" property, which we can display using a SUBJECT field: + properties.setSubject("My subject"); + builder.write("\nSubject:\t"); + builder.insertField(FieldType.FIELD_SUBJECT, true); + + // 4 - "Comments" property, which we can display using a COMMENTS field: + properties.setComments(MessageFormat.format("This is {0}''s document about {1}", properties.getAuthor(), properties.getSubject())); + builder.write("\nComments:\t\""); + builder.insertField(FieldType.FIELD_COMMENTS, true); + builder.write("\""); + + // The "Category" built-in property does not have a field that can display its value. + properties.setCategory("My category"); + + // We can set multiple keywords for a document by separating the string value of the "Keywords" property with semicolons. + properties.setKeywords("Tag 1; Tag 2; Tag 3"); + + // We can right-click this document in Windows Explorer and find these properties in "Properties" -> "Details". + // The "Author" built-in property is in the "Origin" group, and the others are in the "Description" group. + doc.save(getArtifactsDir() + "DocumentProperties.Description.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentProperties.Description.docx"); + + properties = doc.getBuiltInDocumentProperties(); + + Assert.assertEquals("John Doe", properties.getAuthor()); + Assert.assertEquals("My category", properties.getCategory()); + Assert.assertEquals("This is John Doe's document about My subject", properties.getComments()); + Assert.assertEquals("Tag 1; Tag 2; Tag 3", properties.getKeywords()); + Assert.assertEquals("My subject", properties.getSubject()); + Assert.assertEquals("John's Document", properties.getTitle()); + Assert.assertEquals("Author:\t\u0013 AUTHOR \u0014John Doe\u0015\r" + + "Doc title:\t\u0013 TITLE \u0014John's Document\u0015\r" + + "Subject:\t\u0013 SUBJECT \u0014My subject\u0015\r" + + "Comments:\t\"\u0013 COMMENTS \u0014This is John Doe's document about My subject\u0015\"", doc.getText().trim()); + } + + @Test + public void origin() throws Exception { + //ExStart + //ExFor:BuiltInDocumentProperties.Company + //ExFor:BuiltInDocumentProperties.CreatedTime + //ExFor:BuiltInDocumentProperties.LastPrinted + //ExFor:BuiltInDocumentProperties.LastSavedBy + //ExFor:BuiltInDocumentProperties.LastSavedTime + //ExFor:BuiltInDocumentProperties.Manager + //ExFor:BuiltInDocumentProperties.NameOfApplication + //ExFor:BuiltInDocumentProperties.RevisionNumber + //ExFor:BuiltInDocumentProperties.Template + //ExFor:BuiltInDocumentProperties.TotalEditingTime + //ExFor:BuiltInDocumentProperties.Version + //ExSummary:Shows how to work with document properties in the "Origin" category. + // Open a document that we have created and edited using Microsoft Word. + Document doc = new Document(getMyDir() + "Properties.docx"); + BuiltInDocumentProperties properties = doc.getBuiltInDocumentProperties(); + + // The following built-in properties contain information regarding the creation and editing of this document. + // We can right-click this document in Windows Explorer and find + // these properties via "Properties" -> "Details" -> "Origin" category. + // Fields such as PRINTDATE and EDITTIME can display these values in the document body. + System.out.println(MessageFormat.format("Created using {0}, on {1}", properties.getNameOfApplication(), properties.getCreatedTime())); + System.out.println(MessageFormat.format("Minutes spent editing: {0}", properties.getTotalEditingTime())); + System.out.println(MessageFormat.format("Date/time last printed: {0}", properties.getLastPrinted())); + System.out.println(MessageFormat.format("Template document: {0}", properties.getTemplate())); + + // We can also change the values of built-in properties. + properties.setCompany("Doe Ltd."); + properties.setManager("Jane Doe"); + properties.setVersion(5); + properties.setRevisionNumber(properties.getRevisionNumber() + 1); + + // Microsoft Word updates the following properties automatically when we save the document. + // To use these properties with Aspose.Words, we will need to set values for them manually. + properties.setLastSavedBy("John Doe"); + properties.setLastSavedTime(new Date()); + + // We can right-click this document in Windows Explorer and find these properties in "Properties" -> "Details" -> "Origin". + doc.save(getArtifactsDir() + "DocumentProperties.Origin.docx"); + //ExEnd + + properties = new Document(getArtifactsDir() + "DocumentProperties.Origin.docx").getBuiltInDocumentProperties(); + + Assert.assertEquals("Doe Ltd.", properties.getCompany()); + Assert.assertEquals("John Doe", properties.getLastSavedBy()); + TestUtil.verifyDate(new Date(), properties.getLastSavedTime(), Duration.ofSeconds(5)); + Assert.assertEquals("Jane Doe", properties.getManager()); + Assert.assertEquals("Microsoft Office Word", properties.getNameOfApplication()); + Assert.assertEquals(12, properties.getRevisionNumber()); + Assert.assertEquals("Normal", properties.getTemplate()); + Assert.assertEquals(8, properties.getTotalEditingTime()); + Assert.assertEquals(786432, properties.getVersion()); + } + + //ExStart + //ExFor:BuiltInDocumentProperties.Bytes + //ExFor:BuiltInDocumentProperties.Characters + //ExFor:BuiltInDocumentProperties.CharactersWithSpaces + //ExFor:BuiltInDocumentProperties.ContentStatus + //ExFor:BuiltInDocumentProperties.ContentType + //ExFor:BuiltInDocumentProperties.Lines + //ExFor:BuiltInDocumentProperties.LinksUpToDate + //ExFor:BuiltInDocumentProperties.Pages + //ExFor:BuiltInDocumentProperties.Paragraphs + //ExFor:BuiltInDocumentProperties.Words + //ExSummary:Shows how to work with document properties in the "Content" category. + @Test //ExSkip + public void content() throws Exception { + Document doc = new Document(getMyDir() + "Paragraphs.docx"); + BuiltInDocumentProperties properties = doc.getBuiltInDocumentProperties(); + + // By using built in properties, + // we can treat document statistics such as word/page/character counts as metadata that can be glanced at without opening the document + // These properties are accessed by right clicking the file in Windows Explorer and navigating to Properties > Details > Content + // If we want to display this data inside the document, we can use fields such as NUMPAGES, NUMWORDS, NUMCHARS etc. + // Also, these values can also be viewed in Microsoft Word by navigating File > Properties > Advanced Properties > Statistics + // Page count: The PageCount property shows the page count in real time and its value can be assigned to the Pages property + + // The "Pages" property stores the page count of the document. + Assert.assertEquals(6, properties.getPages()); + + // The "Words", "Characters", and "CharactersWithSpaces" built-in properties also display various document statistics, + // but we need to call the "UpdateWordCount" method on the whole document before we can expect them to contain accurate values. + Assert.assertEquals(1054, properties.getWords()); //ExSkip + Assert.assertEquals(6009, properties.getCharacters()); //ExSkip + Assert.assertEquals(7049, properties.getCharactersWithSpaces()); //ExSkip + doc.updateWordCount(); + + Assert.assertEquals(1035, properties.getWords()); + Assert.assertEquals(6026, properties.getCharacters()); + Assert.assertEquals(7041, properties.getCharactersWithSpaces()); + + // Count the number of lines in the document, and then assign the result to the "Lines" built-in property. + LineCounter lineCounter = new LineCounter(doc); + properties.setLines(lineCounter.getLineCount()); + + Assert.assertEquals(142, properties.getLines()); + + // Assign the number of Paragraph nodes in the document to the "Paragraphs" built-in property. + properties.setParagraphs(doc.getChildNodes(NodeType.PARAGRAPH, true).getCount()); + Assert.assertEquals(29, properties.getParagraphs()); + + // Get an estimate of the file size of our document via the "Bytes" built-in property. + Assert.assertEquals(20310, properties.getBytes()); + + // Set a different template for our document, and then update the "Template" built-in property manually to reflect this change. + doc.setAttachedTemplate(getMyDir() + "Business brochure.dotx"); + + Assert.assertEquals("Normal", properties.getTemplate()); + + properties.setTemplate(doc.getAttachedTemplate()); + + // "ContentStatus" is a descriptive built-in property. + properties.setContentStatus("Draft"); + + // Upon saving, the "ContentType" built-in property will contain the MIME type of the output save format. + Assert.assertEquals("", properties.getContentType()); + + // If the document contains links, and they are all up to date, we can set the "LinksUpToDate" property to "true". + Assert.assertFalse(properties.getLinksUpToDate()); + + doc.save(getArtifactsDir() + "DocumentProperties.Content.docx"); + testContent(new Document(getArtifactsDir() + "DocumentProperties.Content.docx")); //ExSkip + } + + /// + /// Counts the lines in a document. + /// Traverses the document's layout entities tree upon construction, + /// counting entities of the "Line" type that also contain real text. + /// + private static class LineCounter { + public LineCounter(Document doc) throws Exception { + mLayoutEnumerator = new LayoutEnumerator(doc); + + countLines(); + } + + public int getLineCount() { + return mLineCount; + } + + private void countLines() throws Exception { + do { + if (mLayoutEnumerator.getType() == LayoutEntityType.LINE) { + mScanningLineForRealText = true; + } + + if (mLayoutEnumerator.moveFirstChild()) { + if (mScanningLineForRealText && mLayoutEnumerator.getKind().startsWith("TEXT")) { + mLineCount++; + mScanningLineForRealText = false; + } + countLines(); + mLayoutEnumerator.moveParent(); + } + } while (mLayoutEnumerator.moveNext()); + } + + private final LayoutEnumerator mLayoutEnumerator; + private int mLineCount; + private boolean mScanningLineForRealText; + } + //ExEnd + + private void testContent(Document doc) { + BuiltInDocumentProperties properties = doc.getBuiltInDocumentProperties(); + + Assert.assertEquals(6, properties.getPages()); + + Assert.assertEquals(1035, properties.getWords()); + Assert.assertEquals(6026, properties.getCharacters()); + Assert.assertEquals(7041, properties.getCharactersWithSpaces()); + Assert.assertEquals(142, properties.getLines()); + Assert.assertEquals(29, properties.getParagraphs()); + Assert.assertEquals(15800.0, properties.getBytes(), 200.0); + Assert.assertEquals(getMyDir().replace("\\\\", "\\") + "Business brochure.dotx", properties.getTemplate()); + Assert.assertEquals("Draft", properties.getContentStatus()); + Assert.assertEquals("", properties.getContentType()); + Assert.assertFalse(properties.getLinksUpToDate()); + } + + @Test + public void thumbnail() throws Exception { + //ExStart + //ExFor:BuiltInDocumentProperties.Thumbnail + //ExFor:DocumentProperty.ToByteArray + //ExSummary:Shows how to add a thumbnail to a document that we save as an Epub. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + // If we save a document, whose "Thumbnail" property contains image data that we added, as an Epub, + // a reader that opens that document may display the image before the first page. + BuiltInDocumentProperties properties = doc.getBuiltInDocumentProperties(); + + byte[] thumbnailBytes = DocumentHelper.getBytesFromStream(new FileInputStream(getImageDir() + "Logo.jpg")); + properties.setThumbnail(thumbnailBytes); + + doc.save(getArtifactsDir() + "DocumentProperties.Thumbnail.epub"); + + // We can extract a document's thumbnail image and save it to the local file system. + DocumentProperty thumbnail = doc.getBuiltInDocumentProperties().get("Thumbnail"); + FileUtils.writeByteArrayToFile(new File(getArtifactsDir() + "DocumentProperties.Thumbnail.gif"), thumbnail.toByteArray()); + //ExEnd + } + + @Test + public void hyperlinkBase() throws Exception { + //ExStart + //ExFor:BuiltInDocumentProperties.HyperlinkBase + //ExSummary:Shows how to store the base part of a hyperlink in the document's properties. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a relative hyperlink to a document in the local file system named "Document.docx". + // Clicking on the link in Microsoft Word will open the designated document, if it is available. + builder.insertHyperlink("Relative hyperlink", "Document.docx", false); + + // This link is relative. If there is no "Document.docx" in the same folder + // as the document that contains this link, the link will be broken. + Assert.assertFalse(new File(getArtifactsDir() + "Document.docx").exists()); + doc.save(getArtifactsDir() + "DocumentProperties.HyperlinkBase.BrokenLink.docx"); + + // The document we are trying to link to is in a different directory to the one we are planning to save the document in. + // We could fix links like this by putting an absolute filename in each one. + // Alternatively, we could provide a base link that every hyperlink with a relative filename + // will prepend to its link when we click on it. + BuiltInDocumentProperties properties = doc.getBuiltInDocumentProperties(); + properties.setHyperlinkBase(getMyDir()); + + Assert.assertTrue(new File(properties.getHyperlinkBase() + ((FieldHyperlink) doc.getRange().getFields().get(0)).getAddress()).exists()); + + doc.save(getArtifactsDir() + "DocumentProperties.HyperlinkBase.WorkingLink.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentProperties.HyperlinkBase.BrokenLink.docx"); + properties = doc.getBuiltInDocumentProperties(); + + Assert.assertEquals("", properties.getHyperlinkBase()); + + doc = new Document(getArtifactsDir() + "DocumentProperties.HyperlinkBase.WorkingLink.docx"); + properties = doc.getBuiltInDocumentProperties(); + + Assert.assertEquals(getMyDir(), properties.getHyperlinkBase()); + Assert.assertTrue(new File(properties.getHyperlinkBase() + ((FieldHyperlink) doc.getRange().getFields().get(0)).getAddress()).exists()); + } + + @Test + public void headingPairs() throws Exception { + //ExStart + //ExFor:BuiltInDocumentProperties.HeadingPairs + //ExFor:BuiltInDocumentProperties.TitlesOfParts + //ExSummary:Shows the relationship between "HeadingPairs" and "TitlesOfParts" properties. + Document doc = new Document(getMyDir() + "Heading pairs and titles of parts.docx"); + + // We can find the combined values of these collections via + // "File" -> "Properties" -> "Advanced Properties" -> "Contents" tab. + // The HeadingPairs property is a collection of pairs that + // determines how many document parts a heading spans across. + Object[] headingPairs = doc.getBuiltInDocumentProperties().getHeadingPairs(); + + // The TitlesOfParts property contains the names of parts that belong to the above headings. + String[] titlesOfParts = doc.getBuiltInDocumentProperties().getTitlesOfParts(); + + int headingPairsIndex = 0; + int titlesOfPartsIndex = 0; + while (headingPairsIndex < headingPairs.length) { + System.out.println(MessageFormat.format("Parts for {0}:", headingPairs[headingPairsIndex++])); + int partsCount = (int) headingPairs[headingPairsIndex++]; + + for (int i = 0; i < partsCount; i++) + System.out.println(MessageFormat.format("\t\"{0}\"", titlesOfParts[titlesOfPartsIndex++])); + } + //ExEnd + + // There are 6 array elements designating 3 heading/part count pairs + Assert.assertEquals(6, headingPairs.length); + Assert.assertEquals("Title", headingPairs[0].toString()); + Assert.assertEquals("1", headingPairs[1].toString()); + Assert.assertEquals("Heading 1", headingPairs[2].toString()); + Assert.assertEquals("5", headingPairs[3].toString()); + Assert.assertEquals("Heading 2", headingPairs[4].toString()); + Assert.assertEquals("2", headingPairs[5].toString()); + + Assert.assertEquals(8, titlesOfParts.length); + // "Title" + Assert.assertEquals("", titlesOfParts[0]); + // "Heading 1" + Assert.assertEquals("Part1", titlesOfParts[1]); + Assert.assertEquals("Part2", titlesOfParts[2]); + Assert.assertEquals("Part3", titlesOfParts[3]); + Assert.assertEquals("Part4", titlesOfParts[4]); + Assert.assertEquals("Part5", titlesOfParts[5]); + // "Heading 2" + Assert.assertEquals("Part6", titlesOfParts[6]); + Assert.assertEquals("Part7", titlesOfParts[7]); + } + + @Test + public void security() throws Exception { + //ExStart + //ExFor:BuiltInDocumentProperties.Security + //ExFor:DocumentSecurity + //ExSummary:Shows how to use document properties to display the security level of a document. + Document doc = new Document(); + + Assert.assertEquals(DocumentSecurity.NONE, doc.getBuiltInDocumentProperties().getSecurity()); + + // If we configure a document to be read-only, it will display this status using the "Security" built-in property. + doc.getWriteProtection().setReadOnlyRecommended(true); + doc.save(getArtifactsDir() + "DocumentProperties.Security.ReadOnlyRecommended.docx"); + + Assert.assertEquals(DocumentSecurity.READ_ONLY_RECOMMENDED, + new Document(getArtifactsDir() + "DocumentProperties.Security.ReadOnlyRecommended.docx").getBuiltInDocumentProperties().getSecurity()); + + // Write-protect a document, and then verify its security level. + doc = new Document(); + + Assert.assertFalse(doc.getWriteProtection().isWriteProtected()); + + doc.getWriteProtection().setPassword("MyPassword"); + + Assert.assertTrue(doc.getWriteProtection().validatePassword("MyPassword")); + Assert.assertTrue(doc.getWriteProtection().isWriteProtected()); + + doc.save(getArtifactsDir() + "DocumentProperties.Security.ReadOnlyEnforced.docx"); + + Assert.assertEquals(DocumentSecurity.READ_ONLY_ENFORCED, + new Document(getArtifactsDir() + "DocumentProperties.Security.ReadOnlyEnforced.docx").getBuiltInDocumentProperties().getSecurity()); + + // "Security" is a descriptive property. We can edit its value manually. + doc = new Document(); + + doc.protect(ProtectionType.ALLOW_ONLY_COMMENTS, "MyPassword"); + doc.getBuiltInDocumentProperties().setSecurity(DocumentSecurity.READ_ONLY_EXCEPT_ANNOTATIONS); + doc.save(getArtifactsDir() + "DocumentProperties.Security.ReadOnlyExceptAnnotations.docx"); + + Assert.assertEquals(DocumentSecurity.READ_ONLY_EXCEPT_ANNOTATIONS, + new Document(getArtifactsDir() + "DocumentProperties.Security.ReadOnlyExceptAnnotations.docx").getBuiltInDocumentProperties().getSecurity()); + //ExEnd + } + + @Test + public void customNamedAccess() throws Exception { + //ExStart + //ExFor:DocumentPropertyCollection.Item(String) + //ExFor:CustomDocumentProperties.Add(String,DateTime) + //ExFor:DocumentProperty.ToDateTime + //ExSummary:Shows how to create a custom document property which contains a date and time. + Document doc = new Document(); + + doc.getCustomDocumentProperties().add("AuthorizationDate", new Date()); + + System.out.println(MessageFormat.format("Document authorized on {0}", doc.getCustomDocumentProperties().get("AuthorizationDate"))); + //ExEnd + + TestUtil.verifyDate(new Date(), + DocumentHelper.saveOpen(doc).getCustomDocumentProperties().get("AuthorizationDate").toDateTime(), + Duration.ofSeconds(1)); + } + + @Test + public void linkCustomDocumentPropertiesToBookmark() throws Exception { + //ExStart + //ExFor:CustomDocumentProperties.AddLinkToContent(String, String) + //ExFor:DocumentProperty.IsLinkToContent + //ExFor:DocumentProperty.LinkSource + //ExSummary:Shows how to link a custom document property to a bookmark. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startBookmark("MyBookmark"); + builder.write("Hello world!"); + builder.endBookmark("MyBookmark"); + + // Link a new custom property to a bookmark. The value of this property + // will be the contents of the bookmark that it references in the "LinkSource" member. + CustomDocumentProperties customProperties = doc.getCustomDocumentProperties(); + DocumentProperty customProperty = customProperties.addLinkToContent("Bookmark", "MyBookmark"); + + Assert.assertEquals(true, customProperty.isLinkToContent()); + Assert.assertEquals("MyBookmark", customProperty.getLinkSource()); + Assert.assertEquals("Hello world!", customProperty.getValue()); + + doc.save(getArtifactsDir() + "DocumentProperties.LinkCustomDocumentPropertiesToBookmark.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "DocumentProperties.LinkCustomDocumentPropertiesToBookmark.docx"); + customProperty = doc.getCustomDocumentProperties().get("Bookmark"); + + Assert.assertEquals(true, customProperty.isLinkToContent()); + Assert.assertEquals("MyBookmark", customProperty.getLinkSource()); + Assert.assertEquals("Hello world!", customProperty.getValue()); + } + + @Test + public void documentPropertyCollection() throws Exception { + //ExStart + //ExFor:CustomDocumentProperties.Add(String,String) + //ExFor:CustomDocumentProperties.Add(String,Boolean) + //ExFor:CustomDocumentProperties.Add(String,int) + //ExFor:CustomDocumentProperties.Add(String,DateTime) + //ExFor:CustomDocumentProperties.Add(String,Double) + //ExFor:DocumentProperty.Type + //ExFor:DocumentPropertyCollection + //ExFor:DocumentPropertyCollection.Clear + //ExFor:DocumentPropertyCollection.Contains(String) + //ExFor:DocumentPropertyCollection.GetEnumerator + //ExFor:DocumentPropertyCollection.IndexOf(String) + //ExFor:DocumentPropertyCollection.RemoveAt(Int32) + //ExFor:DocumentPropertyCollection.Remove + //ExFor:PropertyType + //ExSummary:Shows how to work with a document's custom properties. + Document doc = new Document(); + CustomDocumentProperties properties = doc.getCustomDocumentProperties(); + + Assert.assertEquals(0, properties.getCount()); + + // Custom document properties are key-value pairs that we can add to the document. + properties.add("Authorized", true); + properties.add("Authorized By", "John Doe"); + properties.add("Authorized Date", new Date()); + properties.add("Authorized Revision", doc.getBuiltInDocumentProperties().getRevisionNumber()); + properties.add("Authorized Amount", 123.45); + + // The collection sorts the custom properties in alphabetic order. + Assert.assertEquals(1, properties.indexOf("Authorized Amount")); + Assert.assertEquals(5, properties.getCount()); + + // Print every custom property in the document. + Iterator enumerator = properties.iterator(); + while (enumerator.hasNext()) { + DocumentProperty property = enumerator.next(); + System.out.println(MessageFormat.format("Name: \"{0}\"\n\tType: \"{1}\"\n\tValue: \"{2}\"", property.getName(), property.getType(), property.getValue())); + } + + // Display the value of a custom property using a DOCPROPERTY field. + DocumentBuilder builder = new DocumentBuilder(doc); + FieldDocProperty field = (FieldDocProperty) builder.insertField(" DOCPROPERTY \"Authorized By\""); + field.update(); + + Assert.assertEquals("John Doe", field.getResult()); + + // We can find these custom properties in Microsoft Word via "File" -> "Properties" > "Advanced Properties" > "Custom". + doc.save(getArtifactsDir() + "DocumentProperties.DocumentPropertyCollection.docx"); + + // Below are three ways or removing custom properties from a document. + // 1 - Remove by index: + properties.removeAt(1); + + Assert.assertFalse(properties.contains("Authorized Amount")); + Assert.assertEquals(4, properties.getCount()); + + // 2 - Remove by name: + properties.remove("Authorized Revision"); + + Assert.assertFalse(properties.contains("Authorized Revision")); + Assert.assertEquals(3, properties.getCount()); + + // 3 - Empty the entire collection at once: + properties.clear(); + + Assert.assertEquals(0, properties.getCount()); + //ExEnd + } + + @Test + public void propertyTypes() throws Exception { + //ExStart + //ExFor:DocumentProperty.ToBool + //ExFor:DocumentProperty.ToInt + //ExFor:DocumentProperty.ToDouble + //ExFor:DocumentProperty.ToString + //ExFor:DocumentProperty.ToDateTime + //ExSummary:Shows various type conversion methods of custom document properties. + Document doc = new Document(); + CustomDocumentProperties properties = doc.getCustomDocumentProperties(); + + Date authDate = new Date(); + properties.add("Authorized", true); + properties.add("Authorized By", "John Doe"); + properties.add("Authorized Date", authDate); + properties.add("Authorized Revision", doc.getBuiltInDocumentProperties().getRevisionNumber()); + properties.add("Authorized Amount", 123.45); + + Assert.assertEquals(true, properties.get("Authorized").toBool()); + Assert.assertEquals("John Doe", properties.get("Authorized By").toString()); + Assert.assertEquals(authDate, properties.get("Authorized Date").toDateTime()); + Assert.assertEquals(1, properties.get("Authorized Revision").toInt()); + Assert.assertEquals(123.45d, properties.get("Authorized Amount").toDouble()); + //ExEnd + } + + @Test + public void extendedProperties() throws Exception + { + //ExStart:ExtendedProperties + //GistId:72d57eeddb7fb342fd51b26e5fcf9642 + //ExFor:BuiltInDocumentProperties.ScaleCrop + //ExFor:BuiltInDocumentProperties.SharedDocument + //ExFor:BuiltInDocumentProperties.HyperlinksChanged + //ExSummary:Shows how to get extended properties. + Document doc = new Document(getMyDir() + "Extended properties.docx"); + Assert.assertTrue(doc.getBuiltInDocumentProperties().getScaleCrop()); + Assert.assertTrue(doc.getBuiltInDocumentProperties().getSharedDocument()); + Assert.assertTrue(doc.getBuiltInDocumentProperties().getHyperlinksChanged()); + //ExEnd:ExtendedProperties + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExDocumentVisitor.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExDocumentVisitor.java new file mode 100644 index 00000000..fb8e5e49 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExDocumentVisitor.java @@ -0,0 +1,1220 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.text.MessageFormat; + +@Test +public class ExDocumentVisitor extends ApiExampleBase { + //ExStart + //ExFor:Document.Accept(DocumentVisitor) + //ExFor:Section.Accept(DocumentVisitor) + //ExFor:SubDocument.Accept(DocumentVisitor) + //ExFor:CompositeNode.AcceptEnd(DocumentVisitor) + //ExFor:CompositeNode.AcceptStart(DocumentVisitor) + //ExFor:Document.AcceptEnd(DocumentVisitor) + //ExFor:Document.AcceptStart(DocumentVisitor) + //ExFor:DocumentVisitor + //ExFor:DocumentVisitor.VisitRun(Run) + //ExFor:DocumentVisitor.VisitDocumentEnd(Document) + //ExFor:DocumentVisitor.VisitDocumentStart(Document) + //ExFor:DocumentVisitor.VisitSectionEnd(Section) + //ExFor:DocumentVisitor.VisitSectionStart(Section) + //ExFor:DocumentVisitor.VisitBodyStart(Body) + //ExFor:DocumentVisitor.VisitBodyEnd(Body) + //ExFor:DocumentVisitor.VisitParagraphStart(Paragraph) + //ExFor:DocumentVisitor.VisitParagraphEnd(Paragraph) + //ExFor:DocumentVisitor.VisitSubDocument(SubDocument) + //ExFor:DocumentVisitor.VisitStructuredDocumentTagRangeEnd(StructuredDocumentTagRangeEnd) + //ExFor:DocumentVisitor.VisitStructuredDocumentTagRangeStart(StructuredDocumentTagRangeStart) + //ExSummary:Shows how to use a document visitor to print a document's node structure. + @Test //ExSkip + public void docStructureToText() throws Exception { + Document doc = new Document(getMyDir() + "DocumentVisitor-compatible features.docx"); + DocStructurePrinter visitor = new DocStructurePrinter(); + + // When we get a composite node to accept a document visitor, the visitor visits the accepting node, + // and then traverses all the node's children in a depth-first manner. + // The visitor can read and modify each visited node. + doc.accept(visitor); + + System.out.println(visitor.getText()); + testDocStructureToText(visitor); //ExSkip + } + + /// + /// Traverses a node's tree of child nodes. + /// Creates a map of this tree in the form of a string. + /// + public static class DocStructurePrinter extends DocumentVisitor { + public DocStructurePrinter() { + mAcceptingNodeChildTree = new StringBuilder(); + } + + public String getText() { + return mAcceptingNodeChildTree.toString(); + } + + /// + /// Called when a Document node is encountered. + /// + public int visitDocumentStart(Document doc) { + int childNodeCount = doc.getChildNodes(NodeType.ANY, true).getCount(); + + indentAndAppendLine("[Document start] Child nodes: " + childNodeCount); + mDocTraversalDepth++; + + // Allow the visitor to continue visiting other nodes. + return VisitorAction.CONTINUE; + } + + /// + /// Called after all the child nodes of a Document node have been visited. + /// + public int visitDocumentEnd(Document doc) { + mDocTraversalDepth--; + indentAndAppendLine("[Document end]"); + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a Section node is encountered in the document. + /// + public int visitSectionStart(final Section section) { + // Get the index of our section within the document + NodeCollection docSections = section.getDocument().getChildNodes(NodeType.SECTION, false); + int sectionIndex = docSections.indexOf(section); + + indentAndAppendLine("[Section start] Section index: " + sectionIndex); + mDocTraversalDepth++; + + return VisitorAction.CONTINUE; + } + + /// + /// Called after all the child nodes of a Section node have been visited. + /// + public int visitSectionEnd(final Section section) { + mDocTraversalDepth--; + indentAndAppendLine("[Section end]"); + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a Body node is encountered in the document. + /// + public int visitBodyStart(final Body body) { + int paragraphCount = body.getParagraphs().getCount(); + indentAndAppendLine("[Body start] Paragraphs: " + paragraphCount); + mDocTraversalDepth++; + + return VisitorAction.CONTINUE; + } + + /// + /// Called after all the child nodes of a Body node have been visited. + /// + public int visitBodyEnd(final Body body) { + mDocTraversalDepth--; + indentAndAppendLine("[Body end]"); + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a Paragraph node is encountered in the document. + /// + public int visitParagraphStart(final Paragraph paragraph) { + indentAndAppendLine("[Paragraph start]"); + mDocTraversalDepth++; + + return VisitorAction.CONTINUE; + } + + /// + /// Called after all the child nodes of a Paragraph node have been visited. + /// + public int visitParagraphEnd(final Paragraph paragraph) { + mDocTraversalDepth--; + indentAndAppendLine("[Paragraph end]"); + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a Run node is encountered in the document. + /// + public int visitRun(final Run run) { + indentAndAppendLine("[Run] \"" + run.getText() + "\""); + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a SubDocument node is encountered in the document. + /// + public int visitSubDocument(final SubDocument subDocument) { + indentAndAppendLine("[SubDocument]"); + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a SubDocument node is encountered in the document. + /// + public /*override*/ /*VisitorAction*/int visitStructuredDocumentTagRangeStart(StructuredDocumentTagRangeStart sdtRangeStart) + { + indentAndAppendLine("[SdtRangeStart]"); + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a SubDocument node is encountered in the document. + /// + public /*override*/ /*VisitorAction*/int visitStructuredDocumentTagRangeEnd(StructuredDocumentTagRangeEnd sdtRangeEnd) + { + indentAndAppendLine("[SdtRangeEnd]"); + + return VisitorAction.CONTINUE; + } + + /// + /// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree. + /// + /// + private void indentAndAppendLine(final String text) { + for (int i = 0; i < mDocTraversalDepth; i++) { + mAcceptingNodeChildTree.append("| "); + } + + mAcceptingNodeChildTree.append(text + "\r\n"); + } + + private int mDocTraversalDepth; + private final StringBuilder mAcceptingNodeChildTree; + } + //ExEnd + + private void testDocStructureToText(DocStructurePrinter visitor) { + String visitorText = visitor.getText(); + + Assert.assertTrue(visitorText.contains("[Document start]")); + Assert.assertTrue(visitorText.contains("[Document end]")); + Assert.assertTrue(visitorText.contains("[Section start]")); + Assert.assertTrue(visitorText.contains("[Section end]")); + Assert.assertTrue(visitorText.contains("[Body start]")); + Assert.assertTrue(visitorText.contains("[Body end]")); + Assert.assertTrue(visitorText.contains("[Paragraph start]")); + Assert.assertTrue(visitorText.contains("[Paragraph end]")); + Assert.assertTrue(visitorText.contains("[Run]")); + Assert.assertTrue(visitorText.contains("[SubDocument]")); + } + + //ExStart + //ExFor:Cell.Accept(DocumentVisitor) + //ExFor:Cell.AcceptStart(DocumentVisitor) + //ExFor:Cell.AcceptEnd(DocumentVisitor) + //ExFor:Cell.IsFirstCell + //ExFor:Cell.IsLastCell + //ExFor:DocumentVisitor.VisitTableEnd(Table) + //ExFor:DocumentVisitor.VisitTableStart(Table) + //ExFor:DocumentVisitor.VisitRowEnd(Row) + //ExFor:DocumentVisitor.VisitRowStart(Row) + //ExFor:DocumentVisitor.VisitCellStart(Cell) + //ExFor:DocumentVisitor.VisitCellEnd(Cell) + //ExFor:Row.Accept(DocumentVisitor) + //ExFor:Row.AcceptStart(DocumentVisitor) + //ExFor:Row.AcceptEnd(DocumentVisitor) + //ExFor:Row.FirstCell + //ExFor:Row.GetText + //ExFor:Row.IsFirstRow + //ExFor:Row.LastCell + //ExFor:Row.ParentTable + //ExSummary:Shows how to print the node structure of every table in a document. + @Test //ExSkip + public void tableToText() throws Exception { + Document doc = new Document(getMyDir() + "DocumentVisitor-compatible features.docx"); + TableStructurePrinter visitor = new TableStructurePrinter(); + + // When we get a composite node to accept a document visitor, the visitor visits the accepting node, + // and then traverses all the node's children in a depth-first manner. + // The visitor can read and modify each visited node. + doc.accept(visitor); + + System.out.println(visitor.getText()); + testTableToText(visitor); //ExSkip + } + + /// + /// Traverses a node's non-binary tree of child nodes. + /// Creates a map in the form of a string of all encountered Table nodes and their children. + /// + public static class TableStructurePrinter extends DocumentVisitor { + public TableStructurePrinter() { + mVisitedTables = new StringBuilder(); + mVisitorIsInsideTable = false; + } + + public String getText() { + return mVisitedTables.toString(); + } + + /// + /// Called when a Run node is encountered in the document. + /// Runs that are not within tables are not recorded. + /// + public /*override*/ /*VisitorAction*/int visitRun(Run run) { + if (mVisitorIsInsideTable) indentAndAppendLine("[Run] \"" + run.getText() + "\""); + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a Table is encountered in the document. + /// + public int visitTableStart(final Table table) { + int rows = 0; + int columns = 0; + + if (table.getRows().getCount() > 0) { + rows = table.getRows().getCount(); + columns = table.getFirstRow().getCount(); + } + + indentAndAppendLine("[Table start] Size: " + rows + "x" + columns); + mDocTraversalDepth++; + mVisitorIsInsideTable = true; + + return VisitorAction.CONTINUE; + } + + /// + /// Called after all the child nodes of a Table node have been visited. + /// + public int visitTableEnd(final Table table) { + mDocTraversalDepth--; + indentAndAppendLine("[Table end]"); + mVisitorIsInsideTable = false; + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a Row node is encountered in the document. + /// + public int visitRowStart(final Row row) { + String rowContents = row.getText().replaceAll("\\u0007", ", ").replaceAll(", , ", ""); + int rowWidth = row.indexOf(row.getLastCell()) + 1; + int rowIndex = row.getParentTable().indexOf(row); + String rowStatusInTable = row.isFirstRow() && row.isLastRow() ? "only" : row.isFirstRow() ? "first" : row.isLastRow() ? "last" : ""; + if (!"".equals(rowStatusInTable)) { + rowStatusInTable = MessageFormat.format(", the {0} row in this table,", rowStatusInTable); + } + + indentAndAppendLine(MessageFormat.format("[Row start] Row #{0}{1} width {2}, \"{3}\"", ++rowIndex, rowStatusInTable, rowWidth, rowContents)); + mDocTraversalDepth++; + + return VisitorAction.CONTINUE; + } + + /// + /// Called after all the child nodes of a Row node have been visited. + /// + public int visitRowEnd(final Row row) { + mDocTraversalDepth--; + indentAndAppendLine("[Row end]"); + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a Cell node is encountered in the document. + /// + public int visitCellStart(final Cell cell) { + Row row = cell.getParentRow(); + Table table = row.getParentTable(); + String cellStatusInRow = cell.isFirstCell() && cell.isLastCell() ? "only" : cell.isFirstCell() ? "first" : cell.isLastCell() ? "last" : ""; + if (!"".equals(cellStatusInRow)) { + cellStatusInRow = MessageFormat.format(", the {0} cell in this row", cellStatusInRow); + } + + indentAndAppendLine(MessageFormat.format("[Cell start] Row {0}, Col {1}{2}", table.indexOf(row) + 1, row.indexOf(cell) + 1, cellStatusInRow)); + mDocTraversalDepth++; + + return VisitorAction.CONTINUE; + } + + /// + /// Called after all the child nodes of a Cell node have been visited. + /// + public int visitCellEnd(final Cell cell) { + mDocTraversalDepth--; + indentAndAppendLine("[Cell end]"); + return VisitorAction.CONTINUE; + } + + /// + /// Append a line to the StringBuilder, and indent it depending on how deep the visitor is + /// into the current table's tree of child nodes. + /// + /// + private void indentAndAppendLine(final String text) { + for (int i = 0; i < mDocTraversalDepth; i++) { + mVisitedTables.append("| "); + } + + mVisitedTables.append(text + "\r\n"); + } + + private boolean mVisitorIsInsideTable; + private int mDocTraversalDepth; + private final /*final*/ StringBuilder mVisitedTables; + } + //ExEnd + + private void testTableToText(TableStructurePrinter visitor) { + String visitorText = visitor.getText(); + + Assert.assertTrue(visitorText.contains("[Table start]")); + Assert.assertTrue(visitorText.contains("[Table end]")); + Assert.assertTrue(visitorText.contains("[Row start]")); + Assert.assertTrue(visitorText.contains("[Row end]")); + Assert.assertTrue(visitorText.contains("[Cell start]")); + Assert.assertTrue(visitorText.contains("[Cell end]")); + Assert.assertTrue(visitorText.contains("[Run]")); + } + + //ExStart + //ExFor:DocumentVisitor.VisitCommentStart(Comment) + //ExFor:DocumentVisitor.VisitCommentEnd(Comment) + //ExFor:DocumentVisitor.VisitCommentRangeEnd(CommentRangeEnd) + //ExFor:DocumentVisitor.VisitCommentRangeStart(CommentRangeStart) + //ExSummary:Shows how to print the node structure of every comment and comment range in a document. + @Test //ExSkip + public void commentsToText() throws Exception { + Document doc = new Document(getMyDir() + "DocumentVisitor-compatible features.docx"); + CommentStructurePrinter visitor = new CommentStructurePrinter(); + + // When we get a composite node to accept a document visitor, the visitor visits the accepting node, + // and then traverses all the node's children in a depth-first manner. + // The visitor can read and modify each visited node. + doc.accept(visitor); + + System.out.println(visitor.getText()); + testCommentsToText(visitor); //ExSkip + } + + /// + /// Traverses a node's non-binary tree of child nodes. + /// Creates a map in the form of a string of all encountered Comment/CommentRange nodes and their children. + /// + public static class CommentStructurePrinter extends DocumentVisitor { + public CommentStructurePrinter() { + mBuilder = new StringBuilder(); + mVisitorIsInsideComment = false; + } + + public String getText() { + return mBuilder.toString(); + } + + /// + /// Called when a Run node is encountered in the document. + /// A Run is only recorded if it is a child of a Comment or CommentRange node. + /// + public int visitRun(final Run run) { + if (mVisitorIsInsideComment) { + indentAndAppendLine("[Run] \"" + run.getText() + "\""); + } + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a CommentRangeStart node is encountered in the document. + /// + public int visitCommentRangeStart(final CommentRangeStart commentRangeStart) { + indentAndAppendLine("[Comment range start] ID: " + commentRangeStart.getId()); + mDocTraversalDepth++; + mVisitorIsInsideComment = true; + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a CommentRangeEnd node is encountered in the document. + /// + public int visitCommentRangeEnd(final CommentRangeEnd commentRangeEnd) { + mDocTraversalDepth--; + indentAndAppendLine("[Comment range end]"); + mVisitorIsInsideComment = false; + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a Comment node is encountered in the document. + /// + public int visitCommentStart(final Comment comment) { + indentAndAppendLine(MessageFormat.format("[Comment start] For comment range ID {0}, By {1} on {2}", comment.getId(), + comment.getAuthor(), comment.getDateTime())); + mDocTraversalDepth++; + mVisitorIsInsideComment = true; + + return VisitorAction.CONTINUE; + } + + /// + /// Called after all the child nodes of a Comment node have been visited. + /// + public int visitCommentEnd(final Comment comment) { + mDocTraversalDepth--; + indentAndAppendLine("[Comment end]"); + mVisitorIsInsideComment = false; + + return VisitorAction.CONTINUE; + } + + /// + /// Append a line to the StringBuilder, and indent it depending on how deep the visitor is + /// into a comment/comment range's tree of child nodes. + /// + /// + private void indentAndAppendLine(final String text) { + for (int i = 0; i < mDocTraversalDepth; i++) { + mBuilder.append("| "); + } + + mBuilder.append(text + "\r\n"); + } + + private boolean mVisitorIsInsideComment; + private int mDocTraversalDepth; + private final StringBuilder mBuilder; + } + //ExEnd + + private void testCommentsToText(CommentStructurePrinter visitor) { + String visitorText = visitor.getText(); + + Assert.assertTrue(visitorText.contains("[Comment range start]")); + Assert.assertTrue(visitorText.contains("[Comment range end]")); + Assert.assertTrue(visitorText.contains("[Comment start]")); + Assert.assertTrue(visitorText.contains("[Comment end]")); + Assert.assertTrue(visitorText.contains("[Run]")); + } + + //ExStart + //ExFor:DocumentVisitor.VisitFieldStart + //ExFor:DocumentVisitor.VisitFieldEnd + //ExFor:DocumentVisitor.VisitFieldSeparator + //ExSummary:Shows how to print the node structure of every field in a document. + @Test //ExSkip + public void fieldToText() throws Exception { + Document doc = new Document(getMyDir() + "DocumentVisitor-compatible features.docx"); + FieldStructurePrinter visitor = new FieldStructurePrinter(); + + // When we get a composite node to accept a document visitor, the visitor visits the accepting node, + // and then traverses all the node's children in a depth-first manner. + // The visitor can read and modify each visited node. + doc.accept(visitor); + + System.out.println(visitor.getText()); + testFieldToText(visitor); //ExSkip + } + + /// + /// Traverses a node's non-binary tree of child nodes. + /// Creates a map in the form of a string of all encountered Field nodes and their children. + /// + public static class FieldStructurePrinter extends DocumentVisitor { + public FieldStructurePrinter() { + mBuilder = new StringBuilder(); + mVisitorIsInsideField = false; + } + + public String getText() { + return mBuilder.toString(); + } + + /// + /// Called when a Run node is encountered in the document. + /// + public int visitRun(final Run run) { + if (mVisitorIsInsideField) { + indentAndAppendLine("[Run] \"" + run.getText() + "\""); + } + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a FieldStart node is encountered in the document. + /// + public int visitFieldStart(final FieldStart fieldStart) { + indentAndAppendLine("[Field start] FieldType: " + fieldStart.getFieldType()); + mDocTraversalDepth++; + mVisitorIsInsideField = true; + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a FieldEnd node is encountered in the document. + /// + public int visitFieldEnd(final FieldEnd fieldEnd) { + mDocTraversalDepth--; + indentAndAppendLine("[Field end]"); + mVisitorIsInsideField = false; + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a FieldSeparator node is encountered in the document. + /// + public int visitFieldSeparator(final FieldSeparator fieldSeparator) { + indentAndAppendLine("[FieldSeparator]"); + + return VisitorAction.CONTINUE; + } + + /// + /// Append a line to the StringBuilder, and indent it depending on how deep the visitor is + /// into the field's tree of child nodes. + /// + /// + private void indentAndAppendLine(final String text) { + for (int i = 0; i < mDocTraversalDepth; i++) { + mBuilder.append("| "); + } + + mBuilder.append(text + "\r\n"); + } + + private boolean mVisitorIsInsideField; + private int mDocTraversalDepth; + private final StringBuilder mBuilder; + } + //ExEnd + + private void testFieldToText(FieldStructurePrinter visitor) { + String visitorText = visitor.getText(); + + Assert.assertTrue(visitorText.contains("[Field start]")); + Assert.assertTrue(visitorText.contains("[Field end]")); + Assert.assertTrue(visitorText.contains("[FieldSeparator]")); + Assert.assertTrue(visitorText.contains("[Run]")); + } + + //ExStart + //ExFor:DocumentVisitor.VisitHeaderFooterStart(HeaderFooter) + //ExFor:DocumentVisitor.VisitHeaderFooterEnd(HeaderFooter) + //ExFor:HeaderFooter.Accept(DocumentVisitor) + //ExFor:HeaderFooter.AcceptStart(DocumentVisitor) + //ExFor:HeaderFooter.AcceptEnd(DocumentVisitor) + //ExFor:HeaderFooterCollection.ToArray + //ExFor:Run.Accept(DocumentVisitor) + //ExFor:Run.GetText + //ExSummary:Shows how to print the node structure of every header and footer in a document. + @Test //ExSkip + public void headerFooterToText() throws Exception { + Document doc = new Document(getMyDir() + "DocumentVisitor-compatible features.docx"); + HeaderFooterStructurePrinter visitor = new HeaderFooterStructurePrinter(); + + // When we get a composite node to accept a document visitor, the visitor visits the accepting node, + // and then traverses all the node's children in a depth-first manner. + // The visitor can read and modify each visited node. + doc.accept(visitor); + + System.out.println(visitor.getText()); + + // An alternative way of accessing a document's header/footers section-by-section is by accessing the collection. + HeaderFooter[] headerFooters = doc.getFirstSection().getHeadersFooters().toArray(); + Assert.assertEquals(3, headerFooters.length); + testHeaderFooterToText(visitor); //ExSkip + } + + /// + /// Traverses a node's non-binary tree of child nodes. + /// Creates a map in the form of a string of all encountered HeaderFooter nodes and their children. + /// + public static class HeaderFooterStructurePrinter extends DocumentVisitor { + public HeaderFooterStructurePrinter() { + mBuilder = new StringBuilder(); + mVisitorIsInsideHeaderFooter = false; + } + + public String getText() { + return mBuilder.toString(); + } + + /// + /// Called when a Run node is encountered in the document. + /// + public int visitRun(final Run run) { + if (mVisitorIsInsideHeaderFooter) indentAndAppendLine("[Run] \"" + run.getText() + "\""); + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a HeaderFooter node is encountered in the document. + /// + public int visitHeaderFooterStart(final HeaderFooter headerFooter) { + indentAndAppendLine("[HeaderFooter start] HeaderFooterType: " + headerFooter.getHeaderFooterType()); + mDocTraversalDepth++; + mVisitorIsInsideHeaderFooter = true; + + return VisitorAction.CONTINUE; + } + + /// + /// Called after all the child nodes of a HeaderFooter node have been visited. + /// + public int visitHeaderFooterEnd(final HeaderFooter headerFooter) { + mDocTraversalDepth--; + indentAndAppendLine("[HeaderFooter end]"); + mVisitorIsInsideHeaderFooter = false; + + return VisitorAction.CONTINUE; + } + + /// + /// Append a line to the StringBuilder, and indent it depending on how deep the visitor is into the document tree. + /// + /// + private void indentAndAppendLine(final String text) { + for (int i = 0; i < mDocTraversalDepth; i++) { + mBuilder.append("| "); + } + + mBuilder.append(text + "\r\n"); + } + + private boolean mVisitorIsInsideHeaderFooter; + private int mDocTraversalDepth; + private final StringBuilder mBuilder; + } + //ExEnd + + private void testHeaderFooterToText(HeaderFooterStructurePrinter visitor) { + String visitorText = visitor.getText(); + + Assert.assertTrue(visitorText.contains(MessageFormat.format("[HeaderFooter start] HeaderFooterType: {0}", HeaderFooterType.HEADER_PRIMARY))); + Assert.assertTrue(visitorText.contains("[HeaderFooter end]")); + Assert.assertTrue(visitorText.contains(MessageFormat.format("[HeaderFooter start] HeaderFooterType: {0}", HeaderFooterType.HEADER_FIRST))); + Assert.assertTrue(visitorText.contains(MessageFormat.format("[HeaderFooter start] HeaderFooterType: {0}", HeaderFooterType.HEADER_EVEN))); + Assert.assertTrue(visitorText.contains(MessageFormat.format("[HeaderFooter start] HeaderFooterType: {0}", HeaderFooterType.FOOTER_PRIMARY))); + Assert.assertTrue(visitorText.contains(MessageFormat.format("[HeaderFooter start] HeaderFooterType: {0}", HeaderFooterType.FOOTER_FIRST))); + Assert.assertTrue(visitorText.contains(MessageFormat.format("[HeaderFooter start] HeaderFooterType: {0}", HeaderFooterType.FOOTER_EVEN))); + Assert.assertTrue(visitorText.contains("[Run]")); + } + + //ExStart + //ExFor:DocumentVisitor.VisitEditableRangeEnd(EditableRangeEnd) + //ExFor:DocumentVisitor.VisitEditableRangeStart(EditableRangeStart) + //ExSummary:Shows how to print the node structure of every editable range in a document. + @Test //ExSkip + public void editableRangeToText() throws Exception { + Document doc = new Document(getMyDir() + "DocumentVisitor-compatible features.docx"); + EditableRangeStructurePrinter visitor = new EditableRangeStructurePrinter(); + + // When we get a composite node to accept a document visitor, the visitor visits the accepting node, + // and then traverses all the node's children in a depth-first manner. + // The visitor can read and modify each visited node. + doc.accept(visitor); + + System.out.println(visitor.getText()); + testEditableRangeToText(visitor); //ExSkip + } + + /// + /// Traverses a node's non-binary tree of child nodes. + /// Creates a map in the form of a string of all encountered EditableRange nodes and their children. + /// + public static class EditableRangeStructurePrinter extends DocumentVisitor { + public EditableRangeStructurePrinter() { + mBuilder = new StringBuilder(); + mVisitorIsInsideEditableRange = false; + } + + /// + /// Gets the plain text of the document that was accumulated by the visitor. + /// + public String getText() { + return mBuilder.toString(); + } + + /// + /// Called when a Run node is encountered in the document. + /// + public int visitRun(final Run run) { + // We want to print the contents of runs, but only if they are inside shapes, as they would be in the case of text boxes. + if (mVisitorIsInsideEditableRange) { + indentAndAppendLine("[Run] \"" + run.getText() + "\""); + } + + return VisitorAction.CONTINUE; + } + + /// + /// Called when an EditableRange node is encountered in the document. + /// + public int visitEditableRangeStart(final EditableRangeStart editableRangeStart) { + indentAndAppendLine("[EditableRange start] ID: " + editableRangeStart.getId() + " Owner: " + + editableRangeStart.getEditableRange().getSingleUser()); + mDocTraversalDepth++; + mVisitorIsInsideEditableRange = true; + + return VisitorAction.CONTINUE; + } + + /// + /// Called when the visiting of a EditableRange node is ended. + /// + public int visitEditableRangeEnd(final EditableRangeEnd editableRangeEnd) { + mDocTraversalDepth--; + indentAndAppendLine("[EditableRange end]"); + mVisitorIsInsideEditableRange = false; + + return VisitorAction.CONTINUE; + } + + /// + /// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree. + /// + /// + private void indentAndAppendLine(final String text) { + for (int i = 0; i < mDocTraversalDepth; i++) { + mBuilder.append("| "); + } + + mBuilder.append(text + "\r\n"); + } + + private boolean mVisitorIsInsideEditableRange; + private int mDocTraversalDepth; + private final StringBuilder mBuilder; + } + //ExEnd + + private void testEditableRangeToText(EditableRangeStructurePrinter visitor) { + String visitorText = visitor.getText(); + + Assert.assertTrue(visitorText.contains("[EditableRange start]")); + Assert.assertTrue(visitorText.contains("[EditableRange end]")); + Assert.assertTrue(visitorText.contains("[Run]")); + } + + //ExStart + //ExFor:DocumentVisitor.VisitFootnoteEnd(Footnote) + //ExFor:DocumentVisitor.VisitFootnoteStart(Footnote) + //ExFor:Footnote.Accept(DocumentVisitor) + //ExFor:Footnote.AcceptStart(DocumentVisitor) + //ExFor:Footnote.AcceptEnd(DocumentVisitor) + //ExSummary:Shows how to print the node structure of every footnote in a document. + @Test //ExSkip + public void footnoteToText() throws Exception { + Document doc = new Document(getMyDir() + "DocumentVisitor-compatible features.docx"); + FootnoteStructurePrinter visitor = new FootnoteStructurePrinter(); + + // When we get a composite node to accept a document visitor, the visitor visits the accepting node, + // and then traverses all the node's children in a depth-first manner. + // The visitor can read and modify each visited node. + doc.accept(visitor); + + System.out.println(visitor.getText()); + testFootnoteToText(visitor); //ExSkip + } + + /// + /// Traverses a node's non-binary tree of child nodes. + /// Creates a map in the form of a string of all encountered Footnote nodes and their children. + /// + public static class FootnoteStructurePrinter extends DocumentVisitor { + public FootnoteStructurePrinter() { + mBuilder = new StringBuilder(); + mVisitorIsInsideFootnote = false; + } + + /// + /// Gets the plain text of the document that was accumulated by the visitor. + /// + public String getText() { + return mBuilder.toString(); + } + + /// + /// Called when a Footnote node is encountered in the document. + /// + public int visitFootnoteStart(final Footnote footnote) { + indentAndAppendLine("[Footnote start] Type: " + footnote.getFootnoteType()); + mDocTraversalDepth++; + mVisitorIsInsideFootnote = true; + + return VisitorAction.CONTINUE; + } + + /// + /// Called after all the child nodes of a Footnote node have been visited. + /// + public int visitFootnoteEnd(final Footnote footnote) { + mDocTraversalDepth--; + indentAndAppendLine("[Footnote end]"); + mVisitorIsInsideFootnote = false; + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a Run node is encountered in the document. + /// + public int visitRun(final Run run) { + if (mVisitorIsInsideFootnote) { + indentAndAppendLine("[Run] \"" + run.getText() + "\""); + } + + return VisitorAction.CONTINUE; + } + + /// + /// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree. + /// + /// + private void indentAndAppendLine(final String text) { + for (int i = 0; i < mDocTraversalDepth; i++) { + mBuilder.append("| "); + } + + mBuilder.append(text + "\r\n"); + } + + private boolean mVisitorIsInsideFootnote; + private int mDocTraversalDepth; + private final StringBuilder mBuilder; + } + //ExEnd + + private void testFootnoteToText(FootnoteStructurePrinter visitor) { + String visitorText = visitor.getText(); + + Assert.assertTrue(visitorText.contains(MessageFormat.format("[Footnote start] Type: {0}", FootnoteType.FOOTNOTE))); + Assert.assertTrue(visitorText.contains("[Footnote end]")); + Assert.assertTrue(visitorText.contains("[Run]")); + } + + //ExStart + //ExFor:DocumentVisitor.VisitOfficeMathEnd(OfficeMath) + //ExFor:DocumentVisitor.VisitOfficeMathStart(OfficeMath) + //ExFor:MathObjectType + //ExFor:OfficeMath.Accept(DocumentVisitor) + //ExFor:OfficeMath.AcceptStart(DocumentVisitor) + //ExFor:OfficeMath.AcceptEnd(DocumentVisitor) + //ExFor:OfficeMath.MathObjectType + //ExSummary:Shows how to print the node structure of every office math node in a document. + @Test //ExSkip + public void officeMathToText() throws Exception { + Document doc = new Document(getMyDir() + "DocumentVisitor-compatible features.docx"); + OfficeMathStructurePrinter visitor = new OfficeMathStructurePrinter(); + + // When we get a composite node to accept a document visitor, the visitor visits the accepting node, + // and then traverses all the node's children in a depth-first manner. + // The visitor can read and modify each visited node. + doc.accept(visitor); + + System.out.println(visitor.getText()); + testOfficeMathToText(visitor); //ExSkip + } + + /// + /// Traverses a node's non-binary tree of child nodes. + /// Creates a map in the form of a string of all encountered OfficeMath nodes and their children. + /// + public static class OfficeMathStructurePrinter extends DocumentVisitor { + public OfficeMathStructurePrinter() { + mBuilder = new StringBuilder(); + mVisitorIsInsideOfficeMath = false; + } + + /// + /// Gets the plain text of the document that was accumulated by the visitor. + /// + public String getText() { + return mBuilder.toString(); + } + + /// + /// Called when a Run node is encountered in the document. + /// + public int visitRun(final Run run) { + if (mVisitorIsInsideOfficeMath) { + indentAndAppendLine("[Run] \"" + run.getText() + "\""); + } + + return VisitorAction.CONTINUE; + } + + /// + /// Called when an OfficeMath node is encountered in the document. + /// + public int visitOfficeMathStart(final OfficeMath officeMath) { + indentAndAppendLine("[OfficeMath start] Math object type: " + officeMath.getMathObjectType()); + mDocTraversalDepth++; + mVisitorIsInsideOfficeMath = true; + + return VisitorAction.CONTINUE; + } + + /// + /// Called after all the child nodes of an OfficeMath node have been visited. + /// + public int visitOfficeMathEnd(final OfficeMath officeMath) { + mDocTraversalDepth--; + indentAndAppendLine("[OfficeMath end]"); + mVisitorIsInsideOfficeMath = false; + + return VisitorAction.CONTINUE; + } + + /// + /// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree. + /// + /// + private void indentAndAppendLine(final String text) { + for (int i = 0; i < mDocTraversalDepth; i++) { + mBuilder.append("| "); + } + + mBuilder.append(text + "\r\n"); + } + + private boolean mVisitorIsInsideOfficeMath; + private int mDocTraversalDepth; + private final StringBuilder mBuilder; + } + //ExEnd + + private void testOfficeMathToText(OfficeMathStructurePrinter visitor) { + String visitorText = visitor.getText(); + + Assert.assertTrue(visitorText.contains(MessageFormat.format("[OfficeMath start] Math object type: {0}", MathObjectType.O_MATH_PARA))); + Assert.assertTrue(visitorText.contains(MessageFormat.format("[OfficeMath start] Math object type: {0}", MathObjectType.O_MATH))); + Assert.assertTrue(visitorText.contains(MessageFormat.format("[OfficeMath start] Math object type: {0}", MathObjectType.ARGUMENT))); + Assert.assertTrue(visitorText.contains(MessageFormat.format("[OfficeMath start] Math object type: {0}", MathObjectType.SUPERCRIPT))); + Assert.assertTrue(visitorText.contains(MessageFormat.format("[OfficeMath start] Math object type: {0}", MathObjectType.SUPERSCRIPT_PART))); + Assert.assertTrue(visitorText.contains(MessageFormat.format("[OfficeMath start] Math object type: {0}", MathObjectType.FRACTION))); + Assert.assertTrue(visitorText.contains(MessageFormat.format("[OfficeMath start] Math object type: {0}", MathObjectType.NUMERATOR))); + Assert.assertTrue(visitorText.contains(MessageFormat.format("[OfficeMath start] Math object type: {0}", MathObjectType.DENOMINATOR))); + Assert.assertTrue(visitorText.contains("[OfficeMath end]")); + Assert.assertTrue(visitorText.contains("[Run]")); + } + + //ExStart + //ExFor:DocumentVisitor.VisitSmartTagEnd(SmartTag) + //ExFor:DocumentVisitor.VisitSmartTagStart(SmartTag) + //ExSummary:Shows how to print the node structure of every smart tag in a document. + @Test //ExSkip + public void smartTagToText() throws Exception { + Document doc = new Document(getMyDir() + "Smart tags.doc"); + SmartTagStructurePrinter visitor = new SmartTagStructurePrinter(); + + // When we get a composite node to accept a document visitor, the visitor visits the accepting node, + // and then traverses all the node's children in a depth-first manner. + // The visitor can read and modify each visited node. + doc.accept(visitor); + + System.out.println(visitor.getText()); + testSmartTagToText(visitor); //ExSkip + } + + /// + /// Traverses a node's non-binary tree of child nodes. + /// Creates a map in the form of a string of all encountered SmartTag nodes and their children. + /// + public static class SmartTagStructurePrinter extends DocumentVisitor { + public SmartTagStructurePrinter() { + mBuilder = new StringBuilder(); + mVisitorIsInsideSmartTag = false; + } + + /// + /// Gets the plain text of the document that was accumulated by the visitor. + /// + public String getText() { + return mBuilder.toString(); + } + + /// + /// Called when a Run node is encountered in the document. + /// + public int visitRun(final Run run) { + if (mVisitorIsInsideSmartTag) { + indentAndAppendLine("[Run] \"" + run.getText() + "\""); + } + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a SmartTag node is encountered in the document. + /// + public int visitSmartTagStart(final SmartTag smartTag) { + indentAndAppendLine("[SmartTag start] Name: " + smartTag.getElement()); + mDocTraversalDepth++; + mVisitorIsInsideSmartTag = true; + + return VisitorAction.CONTINUE; + } + + /// + /// Called after all the child nodes of a SmartTag node have been visited. + /// + public int visitSmartTagEnd(final SmartTag smartTag) { + mDocTraversalDepth--; + indentAndAppendLine("[SmartTag end]"); + mVisitorIsInsideSmartTag = false; + + return VisitorAction.CONTINUE; + } + + /// + /// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree. + /// + /// + private void indentAndAppendLine(final String text) { + for (int i = 0; i < mDocTraversalDepth; i++) { + mBuilder.append("| "); + } + + mBuilder.append(text + "\r\n"); + } + + private boolean mVisitorIsInsideSmartTag; + private int mDocTraversalDepth; + private final StringBuilder mBuilder; + } + //ExEnd + + private void testSmartTagToText(SmartTagStructurePrinter visitor) { + String visitorText = visitor.getText(); + + Assert.assertTrue(visitorText.contains("[SmartTag start] Name: address")); + Assert.assertTrue(visitorText.contains("[SmartTag start] Name: Street")); + Assert.assertTrue(visitorText.contains("[SmartTag start] Name: PersonName")); + Assert.assertTrue(visitorText.contains("[SmartTag start] Name: title")); + Assert.assertTrue(visitorText.contains("[SmartTag start] Name: GivenName")); + Assert.assertTrue(visitorText.contains("[SmartTag start] Name: Sn")); + Assert.assertTrue(visitorText.contains("[SmartTag start] Name: stockticker")); + Assert.assertTrue(visitorText.contains("[SmartTag start] Name: date")); + Assert.assertTrue(visitorText.contains("[SmartTag end]")); + Assert.assertTrue(visitorText.contains("[Run]")); + } + + //ExStart + //ExFor:StructuredDocumentTag.Accept(DocumentVisitor) + //ExFor:StructuredDocumentTag.AcceptStart(DocumentVisitor) + //ExFor:StructuredDocumentTag.AcceptEnd(DocumentVisitor) + //ExFor:DocumentVisitor.VisitStructuredDocumentTagEnd(StructuredDocumentTag) + //ExFor:DocumentVisitor.VisitStructuredDocumentTagStart(StructuredDocumentTag) + //ExSummary:Shows how to print the node structure of every structured document tag in a document. + @Test //ExSkip + public void structuredDocumentTagToText() throws Exception { + Document doc = new Document(getMyDir() + "DocumentVisitor-compatible features.docx"); + StructuredDocumentTagNodePrinter visitor = new StructuredDocumentTagNodePrinter(); + + // When we get a composite node to accept a document visitor, the visitor visits the accepting node, + // and then traverses all the node's children in a depth-first manner. + // The visitor can read and modify each visited node. + doc.accept(visitor); + + System.out.println(visitor.getText()); + testStructuredDocumentTagToText(visitor); //ExSkip + } + + /// + /// Traverses a node's non-binary tree of child nodes. + /// Creates a map in the form of a string of all encountered StructuredDocumentTag nodes and their children. + /// + public static class StructuredDocumentTagNodePrinter extends DocumentVisitor { + public StructuredDocumentTagNodePrinter() { + mBuilder = new StringBuilder(); + mVisitorIsInsideStructuredDocumentTag = false; + } + + /// + /// Gets the plain text of the document that was accumulated by the visitor. + /// + public String getText() { + return mBuilder.toString(); + } + + /// + /// Called when a Run node is encountered in the document. + /// + public int visitRun(final Run run) { + if (mVisitorIsInsideStructuredDocumentTag) { + indentAndAppendLine("[Run] \"" + run.getText() + "\""); + } + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a StructuredDocumentTag node is encountered in the document. + /// + public int visitStructuredDocumentTagStart(final StructuredDocumentTag sdt) { + indentAndAppendLine("[StructuredDocumentTag start] Title: " + sdt.getTitle()); + mDocTraversalDepth++; + + return VisitorAction.CONTINUE; + } + + /// + /// Called after all the child nodes of a StructuredDocumentTag node have been visited. + /// + public int visitStructuredDocumentTagEnd(final StructuredDocumentTag sdt) { + mDocTraversalDepth--; + indentAndAppendLine("[StructuredDocumentTag end]"); + + return VisitorAction.CONTINUE; + } + + /// + /// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree. + /// + /// + private void indentAndAppendLine(final String text) { + for (int i = 0; i < mDocTraversalDepth; i++) { + mBuilder.append("| "); + } + + mBuilder.append(text + "\r\n"); + } + + private final boolean mVisitorIsInsideStructuredDocumentTag; + private int mDocTraversalDepth; + private final StringBuilder mBuilder; + } + //ExEnd + + private void testStructuredDocumentTagToText(StructuredDocumentTagNodePrinter visitor) { + String visitorText = visitor.getText(); + + Assert.assertTrue(visitorText.contains("[StructuredDocumentTag start]")); + Assert.assertTrue(visitorText.contains("[StructuredDocumentTag end]")); + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExDotNetVsJava.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExDotNetVsJava.java new file mode 100644 index 00000000..cde1a87f --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExDotNetVsJava.java @@ -0,0 +1,36 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.HeaderFooter; + +/** + * Examples for the .NET vs Java Differences in Aspose.Words in the Programmers Guide. + */ +public class ExDotNetVsJava { + // The saveFormat parameter is a SaveFormat enum value + void save(final String fileName, final int saveFormat) { + // Do nothing + } + + public class HeaderFooterCollection { + // Get by index is an indexer + public HeaderFooter get(final int index) //ExSkip + { //ExSkip + return null; //ExSkip + } //ExSkip + + // Get by header footer type is an overloaded indexer + public HeaderFooter getByHeaderFooterType(final int headerFooterType) //ExSkip + { //ExSkip + return null; //ExSkip + } //ExSkip + } +} + diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExDrawing.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExDrawing.java new file mode 100644 index 00000000..17479789 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExDrawing.java @@ -0,0 +1,664 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.Shape; +import com.aspose.words.Stroke; +import com.aspose.words.*; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; +import org.testng.Assert; +import org.testng.annotations.Test; + +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.stream.ImageInputStream; +import java.awt.*; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.io.*; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Iterator; + +import static org.apache.commons.io.FileUtils.copyInputStreamToFile; + +@Test +public class ExDrawing extends ApiExampleBase { + @Test + public void variousShapes() throws Exception { + //ExStart + //ExFor:ArrowLength + //ExFor:ArrowType + //ExFor:ArrowWidth + //ExFor:DashStyle + //ExFor:EndCap + //ExFor:Fill.ForeColor + //ExFor:Fill.ImageBytes + //ExFor:Fill.Visible + //ExFor:JoinStyle + //ExFor:Shape.Stroke + //ExFor:Stroke.Color + //ExFor:Stroke.StartArrowLength + //ExFor:Stroke.StartArrowType + //ExFor:Stroke.StartArrowWidth + //ExFor:Stroke.EndArrowLength + //ExFor:Stroke.EndArrowWidth + //ExFor:Stroke.DashStyle + //ExFor:Stroke.EndArrowType + //ExFor:Stroke.EndCap + //ExFor:Stroke.Opacity + //ExSummary:Shows to create a variety of shapes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are four examples of shapes that we can insert into our documents. + // 1 - Dotted, horizontal, half-transparent red line + // with an arrow on the left end and a diamond on the right end: + Shape arrow = new Shape(doc, ShapeType.LINE); + arrow.setWidth(200.0); + arrow.getStroke().setColor(Color.RED); + arrow.getStroke().setStartArrowType(ArrowType.ARROW); + arrow.getStroke().setStartArrowLength(ArrowLength.LONG); + arrow.getStroke().setStartArrowWidth(ArrowWidth.WIDE); + arrow.getStroke().setEndArrowType(ArrowType.DIAMOND); + arrow.getStroke().setEndArrowLength(ArrowLength.LONG); + arrow.getStroke().setEndArrowWidth(ArrowWidth.WIDE); + arrow.getStroke().setDashStyle(DashStyle.DASH); + arrow.getStroke().setOpacity(0.5); + + Assert.assertEquals(arrow.getStroke().getJoinStyle(), JoinStyle.MITER); + + builder.insertNode(arrow); + + // 2 - Thick black diagonal line with rounded ends: + Shape line = new Shape(doc, ShapeType.LINE); + line.setTop(40.0); + line.setWidth(200.0); + line.setHeight(20.0); + line.setStrokeWeight(5.0); + line.getStroke().setEndCap(EndCap.ROUND); + + builder.insertNode(line); + + // 3 - Arrow with a green fill: + Shape filledInArrow = new Shape(doc, ShapeType.ARROW); + filledInArrow.setWidth(200.0); + filledInArrow.setHeight(40.0); + filledInArrow.setTop(100.0); + filledInArrow.getFill().setForeColor(Color.GREEN); + filledInArrow.getFill().setVisible(true); + + builder.insertNode(filledInArrow); + + // 4 - Arrow with a flipped orientation filled in with the Aspose logo: + Shape filledInArrowImg = new Shape(doc, ShapeType.ARROW); + filledInArrowImg.setWidth(200.0); + filledInArrowImg.setHeight(40.0); + filledInArrowImg.setTop(160.0); + filledInArrowImg.setFlipOrientation(FlipOrientation.BOTH); + + BufferedImage image = ImageIO.read(getAsposelogoUri().toURL().openStream()); + Graphics2D graphics2D = image.createGraphics(); + + // When we flip the orientation of our arrow, we also flip the image that the arrow contains. + // Flip the image the other way to cancel this out before getting the shape to display it. + AffineTransform at = new AffineTransform(); + at.concatenate(AffineTransform.getScaleInstance(1, -1)); + at.concatenate(AffineTransform.getTranslateInstance(0, -image.getHeight())); + graphics2D.transform(at); + graphics2D.drawImage(image, 0, 0, null); + graphics2D.dispose(); + + filledInArrowImg.getImageData().setImage(image); + builder.insertNode(filledInArrowImg); + + doc.save(getArtifactsDir() + "Drawing.VariousShapes.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Drawing.VariousShapes.docx"); + + Assert.assertEquals(4, doc.getChildNodes(NodeType.SHAPE, true).getCount()); + + arrow = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(ShapeType.LINE, arrow.getShapeType()); + Assert.assertEquals(200.0d, arrow.getWidth()); + Assert.assertEquals(Color.RED.getRGB(), arrow.getStroke().getColor().getRGB()); + Assert.assertEquals(ArrowType.ARROW, arrow.getStroke().getStartArrowType()); + Assert.assertEquals(ArrowLength.LONG, arrow.getStroke().getStartArrowLength()); + Assert.assertEquals(ArrowWidth.WIDE, arrow.getStroke().getStartArrowWidth()); + Assert.assertEquals(ArrowType.DIAMOND, arrow.getStroke().getEndArrowType()); + Assert.assertEquals(ArrowLength.LONG, arrow.getStroke().getEndArrowLength()); + Assert.assertEquals(ArrowWidth.WIDE, arrow.getStroke().getEndArrowWidth()); + Assert.assertEquals(DashStyle.DASH, arrow.getStroke().getDashStyle()); + Assert.assertEquals(0.5d, arrow.getStroke().getOpacity()); + + line = (Shape) doc.getChild(NodeType.SHAPE, 1, true); + + Assert.assertEquals(ShapeType.LINE, line.getShapeType()); + Assert.assertEquals(40.0d, line.getTop()); + Assert.assertEquals(200.0d, line.getWidth()); + Assert.assertEquals(20.0d, line.getHeight()); + Assert.assertEquals(5.0d, line.getStrokeWeight()); + Assert.assertEquals(EndCap.ROUND, line.getStroke().getEndCap()); + + filledInArrow = (Shape) doc.getChild(NodeType.SHAPE, 2, true); + + Assert.assertEquals(ShapeType.ARROW, filledInArrow.getShapeType()); + Assert.assertEquals(200.0d, filledInArrow.getWidth()); + Assert.assertEquals(40.0d, filledInArrow.getHeight()); + Assert.assertEquals(100.0d, filledInArrow.getTop()); + Assert.assertEquals(Color.GREEN.getRGB(), filledInArrow.getFill().getForeColor().getRGB()); + Assert.assertTrue(filledInArrow.getFill().getVisible()); + + filledInArrowImg = (Shape) doc.getChild(NodeType.SHAPE, 3, true); + + Assert.assertEquals(ShapeType.ARROW, filledInArrowImg.getShapeType()); + Assert.assertEquals(200.0d, filledInArrowImg.getWidth()); + Assert.assertEquals(40.0d, filledInArrowImg.getHeight()); + Assert.assertEquals(160.0d, filledInArrowImg.getTop()); + Assert.assertEquals(FlipOrientation.BOTH, filledInArrowImg.getFlipOrientation()); + } + + @Test + public void typeOfImage() throws Exception { + //ExStart + //ExFor:ImageType + //ExSummary:Shows how to add an image to a shape and check its type. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + BufferedImage image = ImageIO.read(getAsposelogoUri().toURL().openStream()); + + // The image in the URL is a .gif. Inserting it into a document converts it into a .png. + Shape imgShape = builder.insertImage(image); + Assert.assertEquals(imgShape.getImageData().getImageType(), ImageType.PNG); + //ExEnd + } + + @Test + public void fillSolid() throws Exception + { + //ExStart + //ExFor:Fill.Color + //ExFor:FillType + //ExFor:Fill.FillType + //ExFor:Fill.Solid + //ExFor:Fill.Transparency + //ExFor:Font.Fill + //ExSummary:Shows how to convert any of the fills back to solid fill. + Document doc = new Document(getMyDir() + "Two color gradient.docx"); + + // Get Fill object for Font of the first Run. + Fill fill = doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0).getFont().getFill(); + + // Check Fill properties of the Font. + System.out.println(MessageFormat.format("The type of the fill is: {0}",fill.getFillType())); + System.out.println(MessageFormat.format("The foreground color of the fill is: {0}",fill.getForeColor())); + System.out.println(MessageFormat.format("The fill is transparent at {0}%",fill.getTransparency() * 100.0)); + + // Change type of the fill to Solid with uniform green color. + fill.solid(Color.GREEN); + System.out.println("\nThe fill is changed:"); + System.out.println(MessageFormat.format("The type of the fill is: {0}",fill.getFillType())); + System.out.println(MessageFormat.format("The foreground color of the fill is: {0}",fill.getForeColor())); + System.out.println(MessageFormat.format("The fill transparency is {0}%",fill.getTransparency() * 100.0)); + + doc.save(getArtifactsDir() + "Drawing.FillSolid.docx"); + //ExEnd + } + + @Test + public void saveAllImages() throws Exception { + //ExStart + //ExFor:ImageData.HasImage + //ExFor:ImageData.ToImage + //ExFor:ImageData.Save(Stream) + //ExSummary:Shows how to save all images from a document to the file system. + Document imgSourceDoc = new Document(getMyDir() + "Images.docx"); + + // Shapes with the "HasImage" flag set store and display all the document's images. + NodeCollection shapes = imgSourceDoc.getChildNodes(NodeType.SHAPE, true); + Assert.assertEquals(shapes.getCount(), 10); + + // Go through each shape and save its image. + for (int i = 0; i < shapes.getCount(); i++) { + Shape shape = (Shape) shapes.get(i); + ImageData imageData = shape.getImageData(); + + if (imageData.hasImage()) { + InputStream format = imageData.toStream(); + + ImageInputStream iis = ImageIO.createImageInputStream(format); + Iterator imageReaders = ImageIO.getImageReaders(iis); + + while (imageReaders.hasNext()) { + ImageReader reader = imageReaders.next(); + String fileExtension = reader.getFormatName(); + + OutputStream fileStream = new FileOutputStream(getArtifactsDir() + MessageFormat.format("Drawing.SaveAllImages.{0}.{1}", i, fileExtension)); + try { + imageData.save(fileStream); + } finally { + if (fileStream != null) fileStream.close(); + } + } + } + } + //ExEnd + + ArrayList imageFileNames = DocumentHelper.directoryGetFiles(getArtifactsDir(), "Drawing.SaveAllImages.*"); + + TestUtil.verifyImage(2467, 1500, imageFileNames.get(0)); + Assert.assertEquals("JPEG", FilenameUtils.getExtension(imageFileNames.get(0))); + TestUtil.verifyImage(400, 400, imageFileNames.get(1)); + Assert.assertEquals("png", FilenameUtils.getExtension(imageFileNames.get(1))); + TestUtil.verifyImage(1260, 660, imageFileNames.get(2)); + Assert.assertEquals("JPEG", FilenameUtils.getExtension(imageFileNames.get(2))); + TestUtil.verifyImage(1125, 1500, imageFileNames.get(3)); + Assert.assertEquals("JPEG", FilenameUtils.getExtension(imageFileNames.get(3))); + TestUtil.verifyImage(1027, 1500, imageFileNames.get(4)); + Assert.assertEquals("JPEG", FilenameUtils.getExtension(imageFileNames.get(4))); + TestUtil.verifyImage(1200, 1500, imageFileNames.get(5)); + Assert.assertEquals("JPEG", FilenameUtils.getExtension(imageFileNames.get(5))); + } + + @Test + public void importImage() throws Exception { + //ExStart + //ExFor:ImageData.SetImage(Image) + //ExFor:ImageData.SetImage(Stream) + //ExSummary:Shows how to display images from the local file system in a document. + Document doc = new Document(); + + // Below are two ways of getting an image from a file in the local file system. + // 1 - Create an image object from an image file: + BufferedImage srcImage = ImageIO.read(new File(getImageDir() + "Logo.jpg")); + + // To display an image in a document, we will need to create a shape + // which will contain an image, and then append it to the document's body. + Shape imgShape = new Shape(doc, ShapeType.IMAGE); + doc.getFirstSection().getBody().getFirstParagraph().appendChild(imgShape); + imgShape.getImageData().setImage(srcImage); + srcImage.flush(); + + // 2 - Open an image file from the local file system using a stream: + InputStream stream = new FileInputStream(getImageDir() + "Logo.jpg"); + try { + imgShape = new Shape(doc, ShapeType.IMAGE); + doc.getFirstSection().getBody().getFirstParagraph().appendChild(imgShape); + imgShape.getImageData().setImage(stream); + imgShape.setLeft(150.0f); + } finally { + if (stream != null) stream.close(); + } + + doc.save(getArtifactsDir() + "Drawing.ImportImage.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Drawing.ImportImage.docx"); + + Assert.assertEquals(2, doc.getChildNodes(NodeType.SHAPE, true).getCount()); + + imgShape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(400, 400, ImageType.PNG, imgShape); + Assert.assertEquals(0.0d, imgShape.getLeft()); + Assert.assertEquals(0.0d, imgShape.getTop()); + Assert.assertEquals(300.0d, imgShape.getHeight(), 1); + Assert.assertEquals(300.0d, imgShape.getWidth(), 1); + TestUtil.verifyImageInShape(400, 400, ImageType.PNG, imgShape); + + imgShape = (Shape) doc.getChild(NodeType.SHAPE, 1, true); + + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, imgShape); + Assert.assertEquals(150.0d, imgShape.getLeft()); + Assert.assertEquals(0.0d, imgShape.getTop()); + Assert.assertEquals(300.0d, imgShape.getHeight(), 1); + Assert.assertEquals(300.0d, imgShape.getWidth(), 1); + } + + @Test + public void strokePattern() throws Exception { + //ExStart + //ExFor:Stroke.Color2 + //ExFor:Stroke.ImageBytes + //ExSummary:Shows how to process shape stroke features. + Document doc = new Document(getMyDir() + "Shape stroke pattern border.docx"); + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + Stroke stroke = shape.getStroke(); + + // Strokes can have two colors, which are used to create a pattern defined by two-tone image data. + // Strokes with a single color do not use the Color2 property. + Assert.assertEquals(new Color((128), (0), (0), (255)), stroke.getColor()); + Assert.assertEquals(new Color((255), (255), (0), (255)), stroke.getColor2()); + + Assert.assertNotNull(stroke.getImageBytes()); + FileUtils.writeByteArrayToFile(new File(getArtifactsDir() + "Drawing.StrokePattern.png"), stroke.getImageBytes()); + //ExEnd + + TestUtil.verifyImage(8, 8, getArtifactsDir() + "Drawing.StrokePattern.png"); + } + + //ExStart + //ExFor:DocumentVisitor.VisitShapeEnd(Shape) + //ExFor:DocumentVisitor.VisitShapeStart(Shape) + //ExFor:DocumentVisitor.VisitGroupShapeEnd(GroupShape) + //ExFor:DocumentVisitor.VisitGroupShapeStart(GroupShape) + //ExFor:GroupShape + //ExFor:GroupShape.#ctor(DocumentBase) + //ExFor:GroupShape.Accept(DocumentVisitor) + //ExFor:GroupShape.AcceptStart(DocumentVisitor) + //ExFor:GroupShape.AcceptEnd(DocumentVisitor) + //ExFor:ShapeBase.IsGroup + //ExFor:ShapeBase.ShapeType + //ExSummary:Shows how to create a group of shapes, and print its contents using a document visitor. + @Test //ExSkip + public void groupOfShapes() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // If you need to create "NonPrimitive" shapes, such as SingleCornerSnipped, TopCornersSnipped, DiagonalCornersSnipped, + // TopCornersOneRoundedOneSnipped, SingleCornerRounded, TopCornersRounded, DiagonalCornersRounded + // please use DocumentBuilder.InsertShape methods. + Shape balloon = new Shape(doc, ShapeType.BALLOON); + balloon.setWidth(200.0); + balloon.setHeight(200.0); + balloon.setStrokeColor(Color.RED); + + Shape cube = new Shape(doc, ShapeType.CUBE); + cube.setWidth(100.0); + cube.setHeight(100.0); + cube.setStrokeColor(Color.BLUE); + + GroupShape group = new GroupShape(doc); + group.appendChild(balloon); + group.appendChild(cube); + + Assert.assertTrue(group.isGroup()); + builder.insertNode(group); + + ShapeInfoPrinter printer = new ShapeInfoPrinter(); + group.accept(printer); + + System.out.println(printer.getText()); + testGroupShapes(doc); //ExSkip + } + + /// + /// Prints the contents of a visited shape group to the console. + /// + public static class ShapeInfoPrinter extends DocumentVisitor { + public ShapeInfoPrinter() { + mBuilder = new StringBuilder(); + } + + public String getText() { + return mBuilder.toString(); + } + + public int visitGroupShapeStart(final GroupShape groupShape) { + mBuilder.append("Shape group started:\r\n"); + return VisitorAction.CONTINUE; + } + + public int visitGroupShapeEnd(final GroupShape groupShape) { + mBuilder.append("End of shape group\r\n"); + return VisitorAction.CONTINUE; + } + + public int visitShapeStart(final Shape shape) { + mBuilder.append("\tShape - " + shape.getShapeType() + ":\r\n"); + mBuilder.append("\t\tWidth: " + shape.getWidth() + "\r\n"); + mBuilder.append("\t\tHeight: " + shape.getHeight() + "\r\n"); + mBuilder.append("\t\tStroke color: " + shape.getStroke().getColor() + "\r\n"); + mBuilder.append("\t\tFill color: " + shape.getFill().getForeColor() + "\r\n"); + return VisitorAction.CONTINUE; + } + + public int visitShapeEnd(final Shape shape) { + mBuilder.append("\tEnd of shape\r\n"); + return VisitorAction.CONTINUE; + } + + private final StringBuilder mBuilder; + } + //ExEnd + + private void testGroupShapes(Document doc) throws Exception { + doc = DocumentHelper.saveOpen(doc); + GroupShape shapes = (GroupShape) doc.getChild(NodeType.GROUP_SHAPE, 0, true); + + Assert.assertEquals(2, shapes.getChildNodes(NodeType.ANY, false).getCount()); + + Shape shape = (Shape) shapes.getChildNodes(NodeType.ANY, false).get(0); + + Assert.assertEquals(ShapeType.BALLOON, shape.getShapeType()); + Assert.assertEquals(200.0d, shape.getWidth()); + Assert.assertEquals(200.0d, shape.getHeight()); + Assert.assertEquals(Color.RED.getRGB(), shape.getStrokeColor().getRGB()); + + shape = (Shape) shapes.getChildNodes(NodeType.ANY, false).get(1); + + Assert.assertEquals(ShapeType.CUBE, shape.getShapeType()); + Assert.assertEquals(100.0d, shape.getWidth()); + Assert.assertEquals(100.0d, shape.getHeight()); + Assert.assertEquals(Color.BLUE.getRGB(), shape.getStrokeColor().getRGB()); + } + + @Test + public void textBox() throws Exception { + //ExStart + //ExFor:LayoutFlow + //ExSummary:Shows how to add text to a text box, and change its orientation. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape textbox = new Shape(doc, ShapeType.TEXT_BOX); + textbox.setWidth(100.0); + textbox.setHeight(100.0); + textbox.getTextBox().setLayoutFlow(LayoutFlow.BOTTOM_TO_TOP); + + textbox.appendChild(new Paragraph(doc)); + builder.insertNode(textbox); + + builder.moveTo(textbox.getFirstParagraph()); + builder.write("This text is flipped 90 degrees to the left."); + + doc.save(getArtifactsDir() + "Drawing.TextBox.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Drawing.TextBox.docx"); + textbox = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(ShapeType.TEXT_BOX, textbox.getShapeType()); + Assert.assertEquals(100.0d, textbox.getWidth()); + Assert.assertEquals(100.0d, textbox.getHeight()); + Assert.assertEquals(LayoutFlow.BOTTOM_TO_TOP, textbox.getTextBox().getLayoutFlow()); + Assert.assertEquals("This text is flipped 90 degrees to the left.", textbox.getText().trim()); + } + + @Test + public void getDataFromImage() throws Exception { + //ExStart + //ExFor:ImageData.ImageBytes + //ExFor:ImageData.ToByteArray + //ExFor:ImageData.ToStream + //ExSummary:Shows how to create an image file from a shape's raw image data. + Document imgSourceDoc = new Document(getMyDir() + "Images.docx"); + Assert.assertEquals(10, imgSourceDoc.getChildNodes(NodeType.SHAPE, true).getCount()); //ExSkip + + Shape imgShape = (Shape) imgSourceDoc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertTrue(imgShape.hasImage()); + + // ToByteArray() returns the array stored in the ImageBytes property. + Assert.assertEquals(imgShape.getImageData().getImageBytes(), imgShape.getImageData().toByteArray()); + + // Save the shape's image data to an image file in the local file system. + InputStream imgStream = imgShape.getImageData().toStream(); + + try { + File imageFile = new File(getArtifactsDir() + "Drawing.GetDataFromImage.png"); + imageFile.createNewFile(); + copyInputStreamToFile(imgStream, imageFile); + } finally { + if (imgStream != null) imgStream.close(); + } + //ExEnd + + TestUtil.verifyImage(2467, 1500, getArtifactsDir() + "Drawing.GetDataFromImage.png"); + } + + @Test + public void imageData() throws Exception { + //ExStart + //ExFor:ImageData.BiLevel + //ExFor:ImageData.Borders + //ExFor:ImageData.Brightness + //ExFor:ImageData.ChromaKey + //ExFor:ImageData.Contrast + //ExFor:ImageData.CropBottom + //ExFor:ImageData.CropLeft + //ExFor:ImageData.CropRight + //ExFor:ImageData.CropTop + //ExFor:ImageData.GrayScale + //ExFor:ImageData.IsLink + //ExFor:ImageData.IsLinkOnly + //ExFor:ImageData.Title + //ExSummary:Shows how to edit a shape's image data. + Document imgSourceDoc = new Document(getMyDir() + "Images.docx"); + + Shape sourceShape = (Shape) imgSourceDoc.getChildNodes(NodeType.SHAPE, true).get(0); + + Document dstDoc = new Document(); + + // Import a shape from the source document and append it to the first paragraph. + Shape importedShape = (Shape) dstDoc.importNode(sourceShape, true); + dstDoc.getFirstSection().getBody().getFirstParagraph().appendChild(importedShape); + + // The imported shape contains an image. We can access the image's properties and raw data via the ImageData object. + ImageData imageData = importedShape.getImageData(); + imageData.setTitle("Imported Image"); + + Assert.assertTrue(imageData.hasImage()); + + // If an image has no borders, its ImageData object will define the border color as empty. + Assert.assertEquals(imageData.getBorders().getCount(), 4); + Assert.assertEquals(imageData.getBorders().get(0).getColor(), new Color(0, true)); + + // This image does not link to another shape or image file in the local file system. + Assert.assertFalse(imageData.isLink()); + Assert.assertFalse(imageData.isLinkOnly()); + + // The "Brightness" and "Contrast" properties define image brightness and contrast + // on a 0-1 scale, with the default value at 0.5. + imageData.setBrightness(0.8d); + imageData.setContrast(1.0d); + + // The above brightness and contrast values have created an image with a lot of white. + // We can select a color with the ChromaKey property to replace with transparency, such as white. + imageData.setChromaKey(Color.WHITE); + + // Import the source shape again and set the image to monochrome. + importedShape = (Shape) dstDoc.importNode(sourceShape, true); + dstDoc.getFirstSection().getBody().getFirstParagraph().appendChild(importedShape); + + importedShape.getImageData().setGrayScale(true); + + // Import the source shape again to create a third image and set it to BiLevel. + // BiLevel sets every pixel to either black or white, whichever is closer to the original color. + importedShape = (Shape) dstDoc.importNode(sourceShape, true); + dstDoc.getFirstSection().getBody().getFirstParagraph().appendChild(importedShape); + + importedShape.getImageData().setBiLevel(true); + + // Cropping is determined on a 0-1 scale. Cropping a side by 0.3 + // will crop 30% of the image out at the cropped side. + importedShape.getImageData().setCropBottom(0.3d); + importedShape.getImageData().setCropLeft(0.3d); + importedShape.getImageData().setCropTop(0.3d); + importedShape.getImageData().setCropRight(0.3d); + + dstDoc.save(getArtifactsDir() + "Drawing.ImageData.docx"); + //ExEnd + + imgSourceDoc = new Document(getArtifactsDir() + "Drawing.ImageData.docx"); + sourceShape = (Shape) imgSourceDoc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(2467, 1500, ImageType.JPEG, sourceShape); + Assert.assertEquals("Imported Image", sourceShape.getImageData().getTitle()); + Assert.assertEquals(0.8d, sourceShape.getImageData().getBrightness(), 0.1d); + Assert.assertEquals(1.0d, sourceShape.getImageData().getContrast(), 0.1d); + Assert.assertEquals(Color.WHITE.getRGB(), sourceShape.getImageData().getChromaKey().getRGB()); + + sourceShape = (Shape) imgSourceDoc.getChild(NodeType.SHAPE, 1, true); + + TestUtil.verifyImageInShape(2467, 1500, ImageType.JPEG, sourceShape); + Assert.assertTrue(sourceShape.getImageData().getGrayScale()); + + sourceShape = (Shape) imgSourceDoc.getChild(NodeType.SHAPE, 2, true); + + TestUtil.verifyImageInShape(2467, 1500, ImageType.JPEG, sourceShape); + Assert.assertTrue(sourceShape.getImageData().getBiLevel()); + Assert.assertEquals(0.3d, sourceShape.getImageData().getCropBottom(), 0.1d); + Assert.assertEquals(0.3d, sourceShape.getImageData().getCropLeft(), 0.1d); + Assert.assertEquals(0.3d, sourceShape.getImageData().getCropTop(), 0.1d); + Assert.assertEquals(0.3d, sourceShape.getImageData().getCropRight(), 0.1d); + } + + @Test + public void imageSize() throws Exception { + //ExStart + //ExFor:ImageSize.HeightPixels + //ExFor:ImageSize.HorizontalResolution + //ExFor:ImageSize.VerticalResolution + //ExFor:ImageSize.WidthPixels + //ExSummary:Shows how to read the properties of an image in a shape. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a shape into the document which contains an image taken from our local file system. + Shape shape = builder.insertImage(getImageDir() + "Logo.jpg"); + + // If the shape contains an image, its ImageData property will be valid, + // and it will contain an ImageSize object. + ImageSize imageSize = shape.getImageData().getImageSize(); + + // The ImageSize object contains read-only information about the image within the shape. + Assert.assertEquals(imageSize.getHeightPixels(), 400); + Assert.assertEquals(imageSize.getWidthPixels(), 400); + + final double delta = 0.05; + Assert.assertEquals(imageSize.getHorizontalResolution(), 95.98d, delta); + Assert.assertEquals(imageSize.getVerticalResolution(), 95.98d, delta); + + // We can base the size of the shape on the size of its image to avoid stretching the image. + shape.setWidth(imageSize.getWidthPoints() * 2.0); + shape.setHeight(imageSize.getHeightPoints() * 2.0); + + doc.save(getArtifactsDir() + "Drawing.ImageSize.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Drawing.ImageSize.docx"); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, shape); + Assert.assertEquals(600.0d, shape.getWidth()); + Assert.assertEquals(600.0d, shape.getHeight()); + + imageSize = shape.getImageData().getImageSize(); + + Assert.assertEquals(400, imageSize.getHeightPixels()); + Assert.assertEquals(400, imageSize.getWidthPixels()); + Assert.assertEquals(95.98d, imageSize.getHorizontalResolution(), 0.5); + Assert.assertEquals(95.98d, imageSize.getVerticalResolution(), 0.5); + } +} \ No newline at end of file diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExEditableRange.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExEditableRange.java new file mode 100644 index 00000000..14c10cf7 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExEditableRange.java @@ -0,0 +1,287 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.text.MessageFormat; + +public class ExEditableRange extends ApiExampleBase { + @Test + public void createAndRemove() throws Exception { + //ExStart + //ExFor:DocumentBuilder.StartEditableRange + //ExFor:DocumentBuilder.EndEditableRange + //ExFor:EditableRange + //ExFor:EditableRange.EditableRangeEnd + //ExFor:EditableRange.EditableRangeStart + //ExFor:EditableRange.Id + //ExFor:EditableRange.Remove + //ExFor:EditableRangeEnd.EditableRangeStart + //ExFor:EditableRangeEnd.Id + //ExFor:EditableRangeEnd.NodeType + //ExFor:EditableRangeStart.EditableRange + //ExFor:EditableRangeStart.Id + //ExFor:EditableRangeStart.NodeType + //ExSummary:Shows how to work with an editable range. + Document doc = new Document(); + doc.protect(ProtectionType.READ_ONLY, "MyPassword"); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world! Since we have set the document's protection level to read-only," + + " we cannot edit this paragraph without the password."); + + // Editable ranges allow us to leave parts of protected documents open for editing. + EditableRangeStart editableRangeStart = builder.startEditableRange(); + builder.writeln("This paragraph is inside an editable range, and can be edited."); + EditableRangeEnd editableRangeEnd = builder.endEditableRange(); + + // A well-formed editable range has a start node, and end node. + // These nodes have matching IDs and encompass editable nodes. + EditableRange editableRange = editableRangeStart.getEditableRange(); + + Assert.assertEquals(editableRangeStart.getId(), editableRange.getId()); + Assert.assertEquals(editableRangeEnd.getId(), editableRange.getId()); + + // Different parts of the editable range link to each other. + Assert.assertEquals(editableRangeStart.getId(), editableRange.getEditableRangeStart().getId()); + Assert.assertEquals(editableRangeStart.getId(), editableRangeEnd.getEditableRangeStart().getId()); + Assert.assertEquals(editableRange.getId(), editableRangeStart.getEditableRange().getId()); + Assert.assertEquals(editableRangeEnd.getId(), editableRange.getEditableRangeEnd().getId()); + + // We can access the node types of each part like this. The editable range itself is not a node, + // but an entity which consists of a start, an end, and their enclosed contents. + Assert.assertEquals(NodeType.EDITABLE_RANGE_START, editableRangeStart.getNodeType()); + Assert.assertEquals(NodeType.EDITABLE_RANGE_END, editableRangeEnd.getNodeType()); + + builder.writeln("This paragraph is outside the editable range, and cannot be edited."); + + doc.save(getArtifactsDir() + "EditableRange.CreateAndRemove.docx"); + + // Remove an editable range. All the nodes that were inside the range will remain intact. + editableRange.remove(); + //ExEnd + + Assert.assertEquals("Hello world! Since we have set the document's protection level to read-only, we cannot edit this paragraph without the password.\r" + + "This paragraph is inside an editable range, and can be edited.\r" + + "This paragraph is outside the editable range, and cannot be edited.", doc.getText().trim()); + Assert.assertEquals(0, doc.getChildNodes(NodeType.EDITABLE_RANGE_START, true).getCount()); + + doc = new Document(getArtifactsDir() + "EditableRange.CreateAndRemove.docx"); + + Assert.assertEquals(ProtectionType.READ_ONLY, doc.getProtectionType()); + Assert.assertEquals("Hello world! Since we have set the document's protection level to read-only, we cannot edit this paragraph without the password.\r" + + "This paragraph is inside an editable range, and can be edited.\r" + + "This paragraph is outside the editable range, and cannot be edited.", doc.getText().trim()); + + editableRange = ((EditableRangeStart) doc.getChild(NodeType.EDITABLE_RANGE_START, 0, true)).getEditableRange(); + + TestUtil.verifyEditableRange(0, "", EditorType.UNSPECIFIED, editableRange); + } + + @Test + public void nested() throws Exception { + //ExStart + //ExFor:DocumentBuilder.StartEditableRange + //ExFor:DocumentBuilder.EndEditableRange(EditableRangeStart) + //ExFor:EditableRange.EditorGroup + //ExSummary:Shows how to create nested editable ranges. + Document doc = new Document(); + doc.protect(ProtectionType.READ_ONLY, "MyPassword"); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world! Since we have set the document's protection level to read-only, " + + "we cannot edit this paragraph without the password."); + + // Create two nested editable ranges. + EditableRangeStart outerEditableRangeStart = builder.startEditableRange(); + builder.writeln("This paragraph inside the outer editable range and can be edited."); + + EditableRangeStart innerEditableRangeStart = builder.startEditableRange(); + builder.writeln("This paragraph inside both the outer and inner editable ranges and can be edited."); + + // Currently, the document builder's node insertion cursor is in more than one ongoing editable range. + // When we want to end an editable range in this situation, + // we need to specify which of the ranges we wish to end by passing its EditableRangeStart node. + builder.endEditableRange(innerEditableRangeStart); + + builder.writeln("This paragraph inside the outer editable range and can be edited."); + + builder.endEditableRange(outerEditableRangeStart); + + builder.writeln("This paragraph is outside any editable ranges, and cannot be edited."); + + // If a region of text has two overlapping editable ranges with specified groups, + // the combined group of users excluded by both groups are prevented from editing it. + outerEditableRangeStart.getEditableRange().setEditorGroup(EditorType.EVERYONE); + innerEditableRangeStart.getEditableRange().setEditorGroup(EditorType.CONTRIBUTORS); + + doc.save(getArtifactsDir() + "EditableRange.Nested.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "EditableRange.Nested.docx"); + + Assert.assertEquals("Hello world! Since we have set the document's protection level to read-only, we cannot edit this paragraph without the password.\r" + + "This paragraph inside the outer editable range and can be edited.\r" + + "This paragraph inside both the outer and inner editable ranges and can be edited.\r" + + "This paragraph inside the outer editable range and can be edited.\r" + + "This paragraph is outside any editable ranges, and cannot be edited.", doc.getText().trim()); + + EditableRange editableRange = ((EditableRangeStart) doc.getChild(NodeType.EDITABLE_RANGE_START, 0, true)).getEditableRange(); + + TestUtil.verifyEditableRange(0, "", EditorType.EVERYONE, editableRange); + + editableRange = ((EditableRangeStart) doc.getChild(NodeType.EDITABLE_RANGE_START, 1, true)).getEditableRange(); + + TestUtil.verifyEditableRange(1, "", EditorType.CONTRIBUTORS, editableRange); + } + + //ExStart + //ExFor:EditableRange + //ExFor:EditableRange.EditorGroup + //ExFor:EditableRange.SingleUser + //ExFor:EditableRangeEnd + //ExFor:EditableRangeEnd.Accept(DocumentVisitor) + //ExFor:EditableRangeStart + //ExFor:EditableRangeStart.Accept(DocumentVisitor) + //ExFor:EditorType + //ExSummary:Shows how to limit the editing rights of editable ranges to a specific group/user. + @Test //ExSkip + public void visitor() throws Exception { + Document doc = new Document(); + doc.protect(ProtectionType.READ_ONLY, "MyPassword"); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world! Since we have set the document's protection level to read-only," + + " we cannot edit this paragraph without the password."); + + // When we write-protect documents, editable ranges allow us to pick specific areas that users may edit. + // There are two mutually exclusive ways to narrow down the list of allowed editors. + // 1 - Specify a user: + EditableRange editableRange = builder.startEditableRange().getEditableRange(); + editableRange.setSingleUser("john.doe@myoffice.com"); + builder.writeln(MessageFormat.format("This paragraph is inside the first editable range, can only be edited by {0}.", editableRange.getSingleUser())); + builder.endEditableRange(); + + Assert.assertEquals(EditorType.UNSPECIFIED, editableRange.getEditorGroup()); + + // 2 - Specify a group that allowed users are associated with: + editableRange = builder.startEditableRange().getEditableRange(); + editableRange.setEditorGroup(EditorType.ADMINISTRATORS); + builder.writeln(MessageFormat.format("This paragraph is inside the first editable range, can only be edited by {0}.", editableRange.getEditorGroup())); + builder.endEditableRange(); + + Assert.assertEquals("", editableRange.getSingleUser()); + + builder.writeln("This paragraph is outside the editable range, and cannot be edited by anybody."); + + // Print details and contents of every editable range in the document. + EditableRangePrinter editableRangePrinter = new EditableRangePrinter(); + + doc.accept(editableRangePrinter); + + System.out.println(editableRangePrinter.toText()); + } + + /// + /// Collects properties and contents of visited editable ranges in a string. + /// + public static class EditableRangePrinter extends DocumentVisitor { + public EditableRangePrinter() { + mBuilder = new StringBuilder(); + } + + public String toText() { + return mBuilder.toString(); + } + + public void reset() { + mBuilder.setLength(0); + mInsideEditableRange = false; + } + + /// + /// Called when an EditableRangeStart node is encountered in the document. + /// + public /*override*/ /*VisitorAction*/int visitEditableRangeStart(EditableRangeStart editableRangeStart) { + mBuilder.append(" -- Editable range found! -- "); + mBuilder.append("\tID:\t\t" + editableRangeStart.getId()); + if (editableRangeStart.getEditableRange().getSingleUser().equals("")) + mBuilder.append("\tGroup:\t" + editableRangeStart.getEditableRange().getEditorGroup()); + else + mBuilder.append("\tUser:\t" + editableRangeStart.getEditableRange().getSingleUser()); + mBuilder.append("\tContents:"); + + mInsideEditableRange = true; + + return VisitorAction.CONTINUE; + } + + /// + /// Called when an EditableRangeEnd node is encountered in the document. + /// + public int visitEditableRangeEnd(final EditableRangeEnd editableRangeEnd) { + mBuilder.append(" -- End of editable range -- " + "\r\n"); + + mInsideEditableRange = false; + + return VisitorAction.CONTINUE; + } + + /// + /// Called when a Run node is encountered in the document. This visitor only records runs that are inside editable ranges. + /// + public int visitRun(final Run run) { + if (mInsideEditableRange) { + mBuilder.append("\t\"" + run.getText() + "\"" + "\r\n"); + } + + return VisitorAction.CONTINUE; + } + + private boolean mInsideEditableRange; + private final StringBuilder mBuilder; + } + //ExEnd + + @Test + public void incorrectStructureException() throws Exception { + Document doc = new Document(); + + DocumentBuilder builder = new DocumentBuilder(doc); + + // Assert that isn't valid structure for the current document. + Assert.assertThrows(IllegalStateException.class, () -> builder.endEditableRange()); + + builder.startEditableRange(); + } + + @Test + public void incorrectStructureDoNotAdded() throws Exception { + Document doc = DocumentHelper.createDocumentFillWithDummyText(); + DocumentBuilder builder = new DocumentBuilder(doc); + + EditableRangeStart startRange1 = builder.startEditableRange(); + + builder.writeln("EditableRange_1_1"); + builder.writeln("EditableRange_1_2"); + + startRange1.getEditableRange().setEditorGroup(EditorType.EVERYONE); + doc = DocumentHelper.saveOpen(doc); + + // Assert that it's not valid structure and editable ranges aren't added to the current document. + NodeCollection startNodes = doc.getChildNodes(NodeType.EDITABLE_RANGE_START, true); + Assert.assertEquals(startNodes.getCount(), 0); + + NodeCollection endNodes = doc.getChildNodes(NodeType.EDITABLE_RANGE_END, true); + Assert.assertEquals(endNodes.getCount(), 0); + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExField.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExField.java new file mode 100644 index 00000000..f5a179ec --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExField.java @@ -0,0 +1,7569 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.barcode.barcoderecognition.BarCodeReader; +import com.aspose.barcode.barcoderecognition.BarCodeResult; +import com.aspose.barcode.barcoderecognition.DecodeType; +import com.aspose.pdf.facades.PdfExtractor; +import com.aspose.words.List; +import com.aspose.words.Shape; +import com.aspose.words.*; +import com.aspose.words.net.System.Data.DataColumn; +import com.aspose.words.net.System.Data.DataTable; +import com.aspose.words.net.System.Globalization.CultureInfo; +import org.apache.commons.collections4.IterableUtils; +import org.apache.poi.util.LocaleUtil; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.io.*; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.regex.Pattern; + +public class ExField extends ApiExampleBase { + @Test + public void getFieldFromDocument() throws Exception { + //ExStart + //ExFor:FieldType + //ExFor:FieldChar + //ExFor:FieldChar.FieldType + //ExFor:FieldChar.IsDirty + //ExFor:FieldChar.IsLocked + //ExFor:FieldChar.GetField + //ExFor:Field.IsLocked + //ExSummary:Shows how to work with a FieldStart node. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + FieldDate field = (FieldDate) builder.insertField(FieldType.FIELD_DATE, true); + field.getFormat().setDateTimeFormat("dddd, MMMM dd, yyyy"); + field.update(); + + FieldChar fieldStart = field.getStart(); + + Assert.assertEquals(FieldType.FIELD_DATE, fieldStart.getFieldType()); + Assert.assertEquals(false, fieldStart.isDirty()); + Assert.assertEquals(false, fieldStart.isLocked()); + + // Retrieve the facade object which represents the field in the document. + field = (FieldDate) fieldStart.getField(); + + Assert.assertEquals(false, field.isLocked()); + Assert.assertEquals(" DATE \\@ \"dddd, MMMM dd, yyyy\"", field.getFieldCode()); + + // Update the field to show the current date. + field.update(); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + + TestUtil.verifyField(FieldType.FIELD_DATE, " DATE \\@ \"dddd, MMMM dd, yyyy\"", new SimpleDateFormat("EEEEE, MMMM dd, yyyy").format(new Date()), doc.getRange().getFields().get(0)); + } + + @Test + public void getFieldData() throws Exception + { + //ExStart + //ExFor:FieldStart.FieldData + //ExSummary:Shows how to get data associated with the field. + Document doc = new Document(getMyDir() + "Field sample - Field with data.docx"); + + Field field = doc.getRange().getFields().get(2); + System.out.println(new String(field.getStart().getFieldData(), StandardCharsets.UTF_8)); + //ExEnd + } + + @Test + public void getFieldCode() throws Exception { + //ExStart + //ExFor:Field.GetFieldCode + //ExFor:Field.GetFieldCode(bool) + //ExSummary:Shows how to get a field's field code. + // Open a document which contains a MERGEFIELD inside an IF field. + Document doc = new Document(getMyDir() + "Nested fields.docx"); + FieldIf fieldIf = (FieldIf) doc.getRange().getFields().get(0); + + // There are two ways of getting a field's field code: + // 1 - Omit its inner fields: + Assert.assertEquals(" IF > 0 \" (surplus of ) \" \"\" ", fieldIf.getFieldCode(false)); + + // 2 - Include its inner fields: + Assert.assertEquals(" IF \u0013 MERGEFIELD NetIncome \u0014\u0015 > 0 \" (surplus of \u0013 MERGEFIELD NetIncome \\f $ \u0014\u0015) \" \"\" ", + fieldIf.getFieldCode(true)); + + // By default, the GetFieldCode method displays inner fields. + Assert.assertEquals(fieldIf.getFieldCode(), fieldIf.getFieldCode(true)); + //ExEnd + } + + @Test + public void displayResult() throws Exception { + //ExStart + //ExFor:Field.DisplayResult + //ExSummary:Shows how to get the real text that a field displays in the document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("This document was written by "); + FieldAuthor fieldAuthor = (FieldAuthor) builder.insertField(FieldType.FIELD_AUTHOR, true); + fieldAuthor.setAuthorName("John Doe"); + + // We can use the DisplayResult property to verify what exact text + // a field would display in its place in the document. + Assert.assertEquals("", fieldAuthor.getDisplayResult()); + + // Fields do not maintain accurate result values in real-time. + // To make sure our fields display accurate results at any given time, + // such as right before a save operation, we need to update them manually. + fieldAuthor.update(); + + Assert.assertEquals("John Doe", fieldAuthor.getDisplayResult()); + + doc.save(getArtifactsDir() + "Field.DisplayResult.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.DisplayResult.docx"); + + Assert.assertEquals("John Doe", doc.getRange().getFields().get(0).getDisplayResult()); + } + + @Test + public void createWithFieldBuilder() throws Exception { + //ExStart + //ExFor:FieldBuilder.#ctor(FieldType) + //ExFor:FieldBuilder.BuildAndInsert(Inline) + //ExSummary:Shows how to create and insert a field using a field builder. + Document doc = new Document(); + + // A convenient way of adding text content to a document is with a document builder. + DocumentBuilder builder = new DocumentBuilder(doc); + builder.write(" Hello world! This text is one Run, which is an inline node."); + + // Fields have their builder, which we can use to construct a field code piece by piece. + // In this case, we will construct a BARCODE field representing a US postal code, + // and then insert it in front of a Run. + FieldBuilder fieldBuilder = new FieldBuilder(FieldType.FIELD_BARCODE); + fieldBuilder.addArgument("90210"); + fieldBuilder.addSwitch("\\f", "A"); + fieldBuilder.addSwitch("\\u"); + + fieldBuilder.buildAndInsert(doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0)); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.CreateWithFieldBuilder.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.CreateWithFieldBuilder.docx"); + + TestUtil.verifyField(FieldType.FIELD_BARCODE, " BARCODE 90210 \\f A \\u ", "", doc.getRange().getFields().get(0)); + + Assert.assertEquals(doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(11).getPreviousSibling(), doc.getRange().getFields().get(0).getEnd()); + Assert.assertEquals(MessageFormat.format("BARCODE 90210 \\f A \\u {0} Hello world! This text is one Run, which is an inline node.", ControlChar.FIELD_END_CHAR), + doc.getText().trim()); + } + + @Test + public void revNum() throws Exception { + //ExStart + //ExFor:BuiltInDocumentProperties.RevisionNumber + //ExFor:FieldRevNum + //ExSummary:Shows how to work with REVNUM fields. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Current revision #"); + + // Insert a REVNUM field, which displays the document's current revision number property. + FieldRevNum field = (FieldRevNum) builder.insertField(FieldType.FIELD_REVISION_NUM, true); + + Assert.assertEquals(" REVNUM ", field.getFieldCode()); + Assert.assertEquals("1", field.getResult()); + Assert.assertEquals(1, doc.getBuiltInDocumentProperties().getRevisionNumber()); + + // This property counts how many times a document has been saved in Microsoft Word, + // and is unrelated to tracked revisions. We can find it by right clicking the document in Windows Explorer + // via Properties -> Details. We can update this property manually. + doc.getBuiltInDocumentProperties().setRevisionNumber(doc.getBuiltInDocumentProperties().getRevisionNumber() + 1)/*Property++*/; + Assert.assertEquals("1", field.getResult()); //ExSkip + field.update(); + + Assert.assertEquals("2", field.getResult()); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + Assert.assertEquals(2, doc.getBuiltInDocumentProperties().getRevisionNumber()); + + TestUtil.verifyField(FieldType.FIELD_REVISION_NUM, " REVNUM ", "2", doc.getRange().getFields().get(0)); + } + + @Test + public void insertFieldNone() throws Exception { + //ExStart + //ExFor:FieldUnknown + //ExSummary:Shows how to work with 'FieldNone' field in a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a field that does not denote an objective field type in its field code. + Field field = builder.insertField(" NOTAREALFIELD //a"); + + // The "FieldNone" field type is reserved for fields such as these. + Assert.assertEquals(FieldType.FIELD_NONE, field.getType()); + + // We can also still work with these fields and assign them as instances of the FieldUnknown class. + FieldUnknown fieldUnknown = (FieldUnknown) field; + Assert.assertEquals(" NOTAREALFIELD //a", fieldUnknown.getFieldCode()); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + + TestUtil.verifyField(FieldType.FIELD_NONE, " NOTAREALFIELD //a", "Error! Bookmark not defined.", doc.getRange().getFields().get(0)); + } + + @Test + public void insertTcField() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a TC field at the current document builder position. + builder.insertField("TC \"Entry Text\" \\f t"); + } + + @Test + public void insertTcFieldsAtText() throws Exception { + Document doc = new Document(); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setReplacingCallback(new InsertTcFieldHandler("Chapter 1", "\\l 1")); + + // Insert a TC field which displays "Chapter 1" just before the text "The Beginning" in the document. + doc.getRange().replace(Pattern.compile("The Beginning"), "", options); + } + + private static class InsertTcFieldHandler implements IReplacingCallback { + // Store the text and switches to be used for the TC fields. + private final String mFieldText; + private final String mFieldSwitches; + + /// + /// The display text and switches to use for each TC field. Display name can be an empty String or null. + /// + public InsertTcFieldHandler(String text, String switches) { + mFieldText = text; + mFieldSwitches = switches; + } + + public int replacing(ReplacingArgs args) throws Exception { + DocumentBuilder builder = new DocumentBuilder((Document) args.getMatchNode().getDocument()); + builder.moveTo(args.getMatchNode()); + + String insertText; + // If the user-specified text is used in the field as display text, use that, otherwise + // use the match String as the display text. + if (mFieldText.equals("")) { + insertText = mFieldText; + } else { + insertText = args.getMatch().group(0); + } + + // Insert the TC field before this node using the specified String + // as the display text and user-defined switches. + builder.insertField(MessageFormat.format("TC \"{0}\" {1}", insertText, mFieldSwitches)); + + return ReplaceAction.SKIP; + } + } + + @Test + public void fieldLocale() throws Exception { + //ExStart + //ExFor:Field.LocaleId + //ExSummary:Shows how to insert a field and work with its locale. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a DATE field, and then print the date it will display. + // Your thread's current culture determines the formatting of the date. + Field field = builder.insertField("DATE"); + System.out.println(MessageFormat.format("Today''s date, as displayed in the \"{0}\" culture: {1}", Locale.getDefault().getDisplayLanguage(), field.getResult())); + + Assert.assertEquals(1033, field.getLocaleId()); + Assert.assertEquals(FieldUpdateCultureSource.CURRENT_THREAD, doc.getFieldOptions().getFieldUpdateCultureSource()); //ExSkip + + // Changing the culture of our thread will impact the result of the DATE field. + // Another way to get the DATE field to display a date in a different culture is to use its LocaleId property. + // This way allows us to avoid changing the thread's culture to get this effect. + doc.getFieldOptions().setFieldUpdateCultureSource(FieldUpdateCultureSource.FIELD_CODE); + CultureInfo de = new CultureInfo("de-DE"); + field.setLocaleId(1031); + field.update(); + + System.out.println(MessageFormat.format("Today''s date, as displayed according to the \"{0}\" culture: {1}", Locale.forLanguageTag(LocaleUtil.getLocaleFromLCID(field.getLocaleId())).getDisplayLanguage(), field.getResult())); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + field = doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_DATE, "DATE", new SimpleDateFormat(de.getDateTimeFormat().getShortDatePattern()).format(new Date()), field); + Assert.assertEquals(1031, field.getLocaleId()); + } + + @Test(dataProvider = "updateDirtyFieldsDataProvider") + public void updateDirtyFields(boolean updateDirtyFields) throws Exception { + //ExStart + //ExFor:Field.IsDirty + //ExFor:LoadOptions.UpdateDirtyFields + //ExSummary:Shows how to use special property for updating field result. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Give the document's built-in "Author" property value, and then display it with a field. + doc.getBuiltInDocumentProperties().setAuthor("John Doe"); + FieldAuthor field = (FieldAuthor) builder.insertField(FieldType.FIELD_AUTHOR, true); + + Assert.assertFalse(field.isDirty()); + Assert.assertEquals("John Doe", field.getResult()); + + // Update the property. The field still displays the old value. + doc.getBuiltInDocumentProperties().setAuthor("John & Jane Doe"); + + Assert.assertEquals("John Doe", field.getResult()); + + // Since the field's value is out of date, we can mark it as "dirty". + // This value will stay out of date until we update the field manually with the Field.Update() method. + field.isDirty(true); + + // If we save without calling an update method, + // the field will keep displaying the out of date value in the output document. + doc.save(getArtifactsDir() + "Filed.UpdateDirtyFields.docx"); + + // The LoadOptions object has an option to update all fields + // marked as "dirty" when loading the document. + LoadOptions options = new LoadOptions(); + options.setUpdateDirtyFields(updateDirtyFields); + + doc = new Document(getArtifactsDir() + "Filed.UpdateDirtyFields.docx", options); + + Assert.assertEquals("John & Jane Doe", doc.getBuiltInDocumentProperties().getAuthor()); + + field = (FieldAuthor) doc.getRange().getFields().get(0); + + // Updating dirty fields like this automatically set their "IsDirty" flag to false. + if (updateDirtyFields) { + Assert.assertEquals("John & Jane Doe", field.getResult()); + Assert.assertFalse(field.isDirty()); + } else { + Assert.assertEquals("John Doe", field.getResult()); + Assert.assertTrue(field.isDirty()); + } + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "updateDirtyFieldsDataProvider") + public static Object[][] updateDirtyFieldsDataProvider() throws Exception { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test + public void insertFieldWithFieldBuilderException() throws Exception { + Document doc = new Document(); + + Run run = DocumentHelper.insertNewRun(doc, " Hello World!", 0); + + FieldArgumentBuilder argumentBuilder = new FieldArgumentBuilder(); + argumentBuilder.addField(new FieldBuilder(FieldType.FIELD_MERGE_FIELD)); + argumentBuilder.addNode(run); + argumentBuilder.addText("Text argument builder"); + + FieldBuilder fieldBuilder = new FieldBuilder(FieldType.FIELD_INCLUDE_TEXT); + + Assert.assertThrows(IllegalArgumentException.class, () -> fieldBuilder.addArgument(argumentBuilder).addArgument("=").addArgument("BestField") + .addArgument(10).addArgument(20.0).buildAndInsert(run)); + } + + @Test + public void barCodeWord2Pdf() throws Exception { + Document doc = new Document(getMyDir() + "Field sample - BARCODE.docx"); + + doc.getFieldOptions().setBarcodeGenerator(new CustomBarcodeGenerator()); + + doc.save(getArtifactsDir() + "Field.BarCodeWord2Pdf.pdf"); + + BarCodeReader barCodeReader = barCodeReaderPdf(getArtifactsDir() + "Field.BarCodeWord2Pdf.pdf"); + + BarCodeResult qrBarCode = Arrays.stream(barCodeReader.getFoundBarCodes()).filter(b -> b.getCodeTypeName() == "QR").findFirst().get(); + Assert.assertEquals("QR", qrBarCode.getCodeTypeName()); + } + + private BarCodeReader barCodeReaderPdf(String filename) throws Exception { + // Set license for Aspose.BarCode. + com.aspose.barcode.License licenceBarCode = new com.aspose.barcode.License(); + licenceBarCode.setLicense(getLicenseDir() + "Aspose.Total.Java.lic"); + + PdfExtractor pdfExtractor = new PdfExtractor(); + pdfExtractor.bindPdf(filename); + + // Set page range for image extraction. + pdfExtractor.setStartPage(1); + pdfExtractor.setEndPage(1); + + pdfExtractor.extractImage(); + + ByteArrayOutputStream imageStream = new ByteArrayOutputStream(); + pdfExtractor.getNextImage(imageStream); + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(imageStream.toByteArray()); + + pdfExtractor.close(); + + // Recognize the barcode from the image stream above. + BarCodeReader barcodeReader = new BarCodeReader(byteArrayInputStream, DecodeType.QR); + + for (BarCodeResult result : barcodeReader.readBarCodes()) + System.out.println("Codetext found: " + result.getCodeText() + ", Symbology: " + result.getCodeTypeName()); + + return barcodeReader; + } + + @Test(enabled = false, description = "WORDSNET-13854") + public void fieldDatabase() throws Exception { + //ExStart + //ExFor:FieldDatabase + //ExFor:FieldDatabase.Connection + //ExFor:FieldDatabase.FileName + //ExFor:FieldDatabase.FirstRecord + //ExFor:FieldDatabase.FormatAttributes + //ExFor:FieldDatabase.InsertHeadings + //ExFor:FieldDatabase.InsertOnceOnMailMerge + //ExFor:FieldDatabase.LastRecord + //ExFor:FieldDatabase.Query + //ExFor:FieldDatabase.TableFormat + //ExFor:FieldDatabaseDataTable + //ExFor:IFieldDatabaseProvider + //ExFor:IFieldDatabaseProvider.GetQueryResult(String,String,String,FieldDatabase) + //ExFor:FieldOptions.FieldDatabaseProvider + //ExSummary:Shows how to extract data from a database and insert it as a field into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // This DATABASE field will run a query on a database, and display the result in a table. + FieldDatabase field = (FieldDatabase) builder.insertField(FieldType.FIELD_DATABASE, true); + field.setFileName(getDatabaseDir() + "Northwind.accdb"); + field.setConnection("DSN=MS Access Databases"); + field.setQuery("SELECT * FROM [Products]"); + + Assert.assertEquals(MessageFormat.format(" DATABASE \\d {0} \\c \"DSN=MS Access Databases\" \\s \"SELECT * FROM [Products]\"", getDatabaseDir().replace("\\", "\\\\") + "Northwind.accdb"), + field.getFieldCode()); + + // Insert another DATABASE field with a more complex query that sorts all products in descending order by gross sales. + field = (FieldDatabase) builder.insertField(FieldType.FIELD_DATABASE, true); + field.setFileName(getMyDir() + "Database\\Northwind.accdb"); + field.setConnection("DSN=MS Access Databases"); + field.setQuery("SELECT [Products].ProductName, FORMAT(SUM([Order Details].UnitPrice * (1 - [Order Details].Discount) * [Order Details].Quantity), 'Currency') AS GrossSales " + + "FROM([Products] " + + "LEFT JOIN[Order Details] ON[Products].[ProductID] = [Order Details].[ProductID]) " + + "GROUP BY[Products].ProductName " + + "ORDER BY SUM([Order Details].UnitPrice* (1 - [Order Details].Discount) * [Order Details].Quantity) DESC"); + + // These properties have the same function as LIMIT and TOP clauses. + // Configure them to display only rows 1 to 10 of the query result in the field's table. + field.setFirstRecord("1"); + field.setLastRecord("10"); + + // This property is the index of the format we want to use for our table. The list of table formats is in the "Table AutoFormat..." menu + // that shows up when we create a DATABASE field in Microsoft Word. Index #10 corresponds to the "Colorful 3" format. + field.setTableFormat("10"); + + // The FormatAttribute property is a string representation of an integer which stores multiple flags. + // We can patrially apply the format which the TableFormat property points to by setting different flags in this property. + // The number we use is the sum of a combination of values corresponding to different aspects of the table style. + // 63 represents 1 (borders) + 2 (shading) + 4 (font) + 8 (color) + 16 (autofit) + 32 (heading rows). + field.setFormatAttributes("63"); + field.setInsertHeadings(true); + field.setInsertOnceOnMailMerge(true); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.DATABASE.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.DATABASE.docx"); + + Assert.assertEquals(2, doc.getRange().getFields().getCount()); + + Table table = doc.getFirstSection().getBody().getTables().get(0); + + Assert.assertEquals(77, table.getRows().getCount()); + Assert.assertEquals(10, table.getRows().get(0).getCells().getCount()); + + field = (FieldDatabase) doc.getRange().getFields().get(0); + + Assert.assertEquals(MessageFormat.format(" DATABASE \\d {0} \\c \"DSN=MS Access Databases\" \\s \"SELECT * FROM [Products]\"", getDatabaseDir().replace("\\", "\\\\") + "Northwind.accdb"), + field.getFieldCode()); + + TestUtil.tableMatchesQueryResult(table, getDatabaseDir() + "Northwind.accdb", field.getQuery()); + + table = (Table) doc.getChild(NodeType.TABLE, 1, true); + field = (FieldDatabase) doc.getRange().getFields().get(1); + + Assert.assertEquals(11, table.getRows().getCount()); + Assert.assertEquals(2, table.getRows().get(0).getCells().getCount()); + Assert.assertEquals("ProductName\u0007", table.getRows().get(0).getCells().get(0).getText()); + Assert.assertEquals("GrossSales\u0007", table.getRows().get(0).getCells().get(1).getText()); + + Assert.assertEquals(" DATABASE \\d \"{DatabaseDir.Replace('\\', '\\\\') + 'Northwind.accdb'}\" \\c \"DSN=MS Access Databases\" " + + "\\s \"SELECT [Products].ProductName, FORMAT(SUM([Order Details].UnitPrice * (1 - [Order Details].Discount) * [Order Details].Quantity), 'Currency') AS GrossSales " + + "FROM([Products] " + + "LEFT JOIN[Order Details] ON[Products].[ProductID] = [Order Details].[ProductID]) " + + "GROUP BY[Products].ProductName " + + "ORDER BY SUM([Order Details].UnitPrice* (1 - [Order Details].Discount) * [Order Details].Quantity) DESC\" \\f 1 \\t 10 \\l 10 \\b 63 \\h \\o", + field.getFieldCode()); + + table.getRows().get(0).remove(); + + TestUtil.tableMatchesQueryResult(table, getDatabaseDir() + "Northwind.accdb", new StringBuffer(field.getQuery()).insert(7, " TOP 10 ").toString()); + } + + @Test(dataProvider = "preserveIncludePictureDataProvider") + public void preserveIncludePicture(boolean preserveIncludePictureField) throws Exception { + //ExStart + //ExFor:Field.Update(bool) + //ExFor:LoadOptions.PreserveIncludePictureField + //ExSummary:Shows how to preserve or discard INCLUDEPICTURE fields when loading a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + FieldIncludePicture includePicture = (FieldIncludePicture) builder.insertField(FieldType.FIELD_INCLUDE_PICTURE, true); + includePicture.setSourceFullName(getImageDir() + "Transparent background logo.png"); + includePicture.update(true); + + try (ByteArrayOutputStream docStream = new ByteArrayOutputStream()) { + doc.save(docStream, new OoxmlSaveOptions(SaveFormat.DOCX)); + + // We can set a flag in a LoadOptions object to decide whether to convert all INCLUDEPICTURE fields + // into image shapes when loading a document that contains them. + LoadOptions loadOptions = new LoadOptions(); + { + loadOptions.setPreserveIncludePictureField(preserveIncludePictureField); + } + + doc = new Document(new ByteArrayInputStream(docStream.toByteArray()), loadOptions); + FieldCollection fieldCollection = doc.getRange().getFields(); + + if (preserveIncludePictureField) { + Assert.assertTrue(IterableUtils.matchesAny(fieldCollection, f -> f.getType() == FieldType.FIELD_INCLUDE_PICTURE)); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.PreserveIncludePicture.docx"); + } else { + Assert.assertFalse(IterableUtils.matchesAny(fieldCollection, f -> f.getType() == FieldType.FIELD_INCLUDE_PICTURE)); + } + } + //ExEnd + } + + @DataProvider(name = "preserveIncludePictureDataProvider") + public static Object[][] preserveIncludePictureDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void fieldFormat() throws Exception { + //ExStart + //ExFor:Field.Format + //ExFor:Field.Update + //ExFor:FieldFormat + //ExFor:FieldFormat.DateTimeFormat + //ExFor:FieldFormat.NumericFormat + //ExFor:FieldFormat.GeneralFormats + //ExFor:GeneralFormat + //ExFor:GeneralFormatCollection + //ExFor:GeneralFormatCollection.Add(GeneralFormat) + //ExFor:GeneralFormatCollection.Count + //ExFor:GeneralFormatCollection.Item(Int32) + //ExFor:GeneralFormatCollection.Remove(GeneralFormat) + //ExFor:GeneralFormatCollection.RemoveAt(Int32) + //ExFor:GeneralFormatCollection.GetEnumerator + //ExSummary:Shows how to format field results. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Use a document builder to insert a field that displays a result with no format applied. + Field field = builder.insertField("= 2 + 3"); + + Assert.assertEquals("= 2 + 3", field.getFieldCode()); + Assert.assertEquals("5", field.getResult()); + + // We can apply a format to a field's result using the field's properties. + // Below are three types of formats that we can apply to a field's result. + // 1 - Numeric format: + FieldFormat format = field.getFormat(); + format.setNumericFormat("$###.00"); + field.update(); + + Assert.assertEquals("= 2 + 3 \\# $###.00", field.getFieldCode()); + Assert.assertEquals("$ 5.00", field.getResult()); + + // 2 - Date/time format: + field = builder.insertField("DATE"); + format = field.getFormat(); + format.setDateTimeFormat("dddd, MMMM dd, yyyy"); + field.update(); + + Assert.assertEquals("DATE \\@ \"dddd, MMMM dd, yyyy\"", field.getFieldCode()); + System.out.println("Today's date, in {format.DateTimeFormat} format:\n\t{field.Result}"); + + // 3 - General format: + field = builder.insertField("= 25 + 33"); + format = field.getFormat(); + format.getGeneralFormats().add(GeneralFormat.LOWERCASE_ROMAN); + format.getGeneralFormats().add(GeneralFormat.UPPER); + field.update(); + + int index = 0; + Iterator generalFormatEnumerator = format.getGeneralFormats().iterator(); + while (generalFormatEnumerator.hasNext()) { + int value = generalFormatEnumerator.next(); + System.out.println(MessageFormat.format("General format index {0}: {1}", index++, value)); + } + + + Assert.assertEquals("= 25 + 33 \\* roman \\* Upper", field.getFieldCode()); + Assert.assertEquals("LVIII", field.getResult()); + Assert.assertEquals(2, format.getGeneralFormats().getCount()); + Assert.assertEquals(GeneralFormat.LOWERCASE_ROMAN, format.getGeneralFormats().get(0)); + + // We can remove our formats to revert the field's result to its original form. + format.getGeneralFormats().remove(GeneralFormat.LOWERCASE_ROMAN); + format.getGeneralFormats().removeAt(0); + Assert.assertEquals(0, format.getGeneralFormats().getCount()); + field.update(); + + Assert.assertEquals("= 25 + 33 ", field.getFieldCode()); + Assert.assertEquals("58", field.getResult()); + Assert.assertEquals(0, format.getGeneralFormats().getCount()); + //ExEnd + } + + @Test + public void unlink() throws Exception { + //ExStart + //ExFor:Document.UnlinkFields + //ExSummary:Shows how to unlink all fields in the document. + Document doc = new Document(getMyDir() + "Linked fields.docx"); + + doc.unlinkFields(); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + String paraWithFields = DocumentHelper.getParagraphText(doc, 0); + Assert.assertEquals(paraWithFields, "Fields.Docx Элементы указателя не найдены. 1.\r"); + } + + @Test + public void unlinkAllFieldsInRange() throws Exception { + //ExStart + //ExFor:Range.UnlinkFields + //ExSummary:Shows how to unlink all fields in a range. + Document doc = new Document(getMyDir() + "Linked fields.docx"); + + Section newSection = (Section) doc.getSections().get(0).deepClone(true); + doc.getSections().add(newSection); + + doc.getSections().get(1).getRange().unlinkFields(); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + String secWithFields = DocumentHelper.getSectionText(doc, 1); + + Assert.assertTrue(secWithFields.trim().endsWith( + "Fields.Docx Элементы указателя не найдены. 3.\rОшибка! Не указана последовательность. Fields.Docx Элементы указателя не найдены. 4.")); + } + + @Test + public void unlinkSingleField() throws Exception { + //ExStart + //ExFor:Field.Unlink + //ExSummary:Shows how to unlink a field. + Document doc = new Document(getMyDir() + "Linked fields.docx"); + doc.getRange().getFields().get(1).unlink(); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + String paraWithFields = DocumentHelper.getParagraphText(doc, 0); + Assert.assertEquals(paraWithFields, "\u0013 FILENAME \\* Caps \\* MERGEFORMAT \u0014Fields.Docx\u0015 Элементы указателя не найдены. \u0013 LISTNUM LegalDefault \u0015\r"); + } + + @Test + public void updateTocPageNumbers() throws Exception { + Document doc = new Document(getMyDir() + "Field sample - TOC.docx"); + + Node startNode = DocumentHelper.getParagraph(doc, 2); + Node endNode = null; + + NodeCollection paragraphCollection = doc.getChildNodes(NodeType.PARAGRAPH, true); + + for (Paragraph para : (Iterable) paragraphCollection) { + for (Run run : para.getRuns()) { + if (run.getText().contains(ControlChar.PAGE_BREAK)) { + endNode = run; + break; + } + } + } + + if (startNode != null && endNode != null) { + removeSequence(startNode, endNode); + + startNode.remove(); + endNode.remove(); + } + + NodeCollection fStart = doc.getChildNodes(NodeType.FIELD_START, true); + + for (FieldStart field : (Iterable) fStart) { + int fType = field.getFieldType(); + if (fType == FieldType.FIELD_TOC) { + Paragraph para = (Paragraph) field.getAncestor(NodeType.PARAGRAPH); + para.getRange().updateFields(); + break; + } + } + + doc.save(getArtifactsDir() + "Field.UpdateTocPageNumbers.docx"); + } + + private static void removeSequence(Node start, Node end) { + Node curNode = start.nextPreOrder(start.getDocument()); + while (curNode != null && !curNode.equals(end)) { + Node nextNode = curNode.nextPreOrder(start.getDocument()); + + if (curNode.isComposite()) { + CompositeNode curComposite = (CompositeNode) curNode; + if (!curComposite.getChildNodes(NodeType.ANY, true).contains(end) && + !curComposite.getChildNodes(NodeType.ANY, true).contains(start)) { + nextNode = curNode.getNextSibling(); + curNode.remove(); + } + } else { + curNode.remove(); + } + + curNode = nextNode; + } + } + + //ExStart + //ExFor:FieldAsk + //ExFor:FieldAsk.BookmarkName + //ExFor:FieldAsk.DefaultResponse + //ExFor:FieldAsk.PromptOnceOnMailMerge + //ExFor:FieldAsk.PromptText + //ExFor:FieldOptions.UserPromptRespondent + //ExFor:IFieldUserPromptRespondent + //ExFor:IFieldUserPromptRespondent.Respond(String,String) + //ExSummary:Shows how to create an ASK field, and set its properties. + @Test//ExSkip + public void fieldAsk() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Place a field where the response to our ASK field will be placed. + FieldRef fieldRef = (FieldRef) builder.insertField(FieldType.FIELD_REF, true); + fieldRef.setBookmarkName("MyAskField"); + builder.writeln(); + + Assert.assertEquals(" REF MyAskField", fieldRef.getFieldCode()); + + // Insert the ASK field and edit its properties to reference our REF field by bookmark name. + FieldAsk fieldAsk = (FieldAsk) builder.insertField(FieldType.FIELD_ASK, true); + fieldAsk.setBookmarkName("MyAskField"); + fieldAsk.setPromptText("Please provide a response for this ASK field"); + fieldAsk.setDefaultResponse("Response from within the field."); + fieldAsk.setPromptOnceOnMailMerge(true); + builder.writeln(); + + Assert.assertEquals( + " ASK MyAskField \"Please provide a response for this ASK field\" \\d \"Response from within the field.\" \\o", + fieldAsk.getFieldCode()); + + // ASK fields apply the default response to their respective REF fields during a mail merge. + DataTable table = new DataTable("My Table"); + table.getColumns().add("Column 1"); + table.getRows().add("Row 1"); + table.getRows().add("Row 2"); + + FieldMergeField fieldMergeField = (FieldMergeField) builder.insertField(FieldType.FIELD_MERGE_FIELD, true); + fieldMergeField.setFieldName("Column 1"); + + // We can modify or override the default response in our ASK fields with a custom prompt responder, + // which will occur during a mail merge. + doc.getFieldOptions().setUserPromptRespondent(new MyPromptRespondent()); + doc.getMailMerge().execute(table); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.ASK.docx"); + testFieldAsk(table, doc); //ExSkip + } + + /// + /// Prepends text to the default response of an ASK field during a mail merge. + /// + private static class MyPromptRespondent implements IFieldUserPromptRespondent { + public String respond(final String promptText, final String defaultResponse) { + return "Response from MyPromptRespondent. " + defaultResponse; + } + } + //ExEnd + + private void testFieldAsk(DataTable dataTable, Document doc) throws Exception { + doc = DocumentHelper.saveOpen(doc); + + FieldRef fieldRef = (FieldRef) DocumentHelper.getField(doc.getRange().getFields(), FieldType.FIELD_REF); + TestUtil.verifyField(FieldType.FIELD_REF, + " REF MyAskField", "Response from MyPromptRespondent. Response from within the field.", fieldRef); + + FieldAsk fieldAsk = (FieldAsk) DocumentHelper.getField(doc.getRange().getFields(), FieldType.FIELD_ASK); + TestUtil.verifyField(FieldType.FIELD_ASK, + " ASK MyAskField \"Please provide a response for this ASK field\" \\d \"Response from within the field.\" \\o", + "Response from MyPromptRespondent. Response from within the field.", fieldAsk); + + Assert.assertEquals("MyAskField", fieldAsk.getBookmarkName()); + Assert.assertEquals("Please provide a response for this ASK field", fieldAsk.getPromptText()); + Assert.assertEquals("Response from within the field.", fieldAsk.getDefaultResponse()); + Assert.assertEquals(true, fieldAsk.getPromptOnceOnMailMerge()); + } + + @Test + public void fieldAdvance() throws Exception { + //ExStart + //ExFor:FieldAdvance + //ExFor:FieldAdvance.DownOffset + //ExFor:FieldAdvance.HorizontalPosition + //ExFor:FieldAdvance.LeftOffset + //ExFor:FieldAdvance.RightOffset + //ExFor:FieldAdvance.UpOffset + //ExFor:FieldAdvance.VerticalPosition + //ExSummary:Shows how to insert an ADVANCE field, and edit its properties. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("This text is in its normal place."); + + // Below are two ways of using the ADVANCE field to adjust the position of text that follows it. + // The effects of an ADVANCE field continue to be applied until the paragraph ends, + // or another ADVANCE field updates the offset/coordinate values. + // 1 - Specify a directional offset: + FieldAdvance field = (FieldAdvance) builder.insertField(FieldType.FIELD_ADVANCE, true); + Assert.assertEquals(FieldType.FIELD_ADVANCE, field.getType()); //ExSkip + Assert.assertEquals(" ADVANCE ", field.getFieldCode()); //ExSkip + field.setRightOffset("5"); + field.setUpOffset("5"); + + Assert.assertEquals(" ADVANCE \\r 5 \\u 5", field.getFieldCode()); + + builder.write("This text will be moved up and to the right."); + + field = (FieldAdvance) builder.insertField(FieldType.FIELD_ADVANCE, true); + field.setDownOffset("5"); + field.setLeftOffset("100"); + + Assert.assertEquals(" ADVANCE \\d 5 \\l 100", field.getFieldCode()); + + builder.writeln("This text is moved down and to the left, overlapping the previous text."); + + // 2 - Move text to a position specified by coordinates: + field = (FieldAdvance) builder.insertField(FieldType.FIELD_ADVANCE, true); + field.setHorizontalPosition("-100"); + field.setVerticalPosition("200"); + + Assert.assertEquals(field.getFieldCode(), " ADVANCE \\x -100 \\y 200"); + + builder.write("This text is in a custom position."); + + doc.save(getArtifactsDir() + "Field.ADVANCE.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.ADVANCE.docx"); + + field = (FieldAdvance) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_ADVANCE, " ADVANCE \\r 5 \\u 5", "", field); + Assert.assertEquals("5", field.getRightOffset()); + Assert.assertEquals("5", field.getUpOffset()); + + field = (FieldAdvance) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_ADVANCE, " ADVANCE \\d 5 \\l 100", "", field); + Assert.assertEquals("5", field.getDownOffset()); + Assert.assertEquals("100", field.getLeftOffset()); + + field = (FieldAdvance) doc.getRange().getFields().get(2); + + TestUtil.verifyField(FieldType.FIELD_ADVANCE, " ADVANCE \\x -100 \\y 200", "", field); + Assert.assertEquals("-100", field.getHorizontalPosition()); + Assert.assertEquals("200", field.getVerticalPosition()); + } + + @Test + public void fieldAddressBlock() throws Exception { + //ExStart + //ExFor:FieldAddressBlock.ExcludedCountryOrRegionName + //ExFor:FieldAddressBlock.FormatAddressOnCountryOrRegion + //ExFor:FieldAddressBlock.IncludeCountryOrRegionName + //ExFor:FieldAddressBlock.LanguageId + //ExFor:FieldAddressBlock.NameAndAddressFormat + //ExSummary:Shows how to insert an ADDRESSBLOCK field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + FieldAddressBlock field = (FieldAddressBlock) builder.insertField(FieldType.FIELD_ADDRESS_BLOCK, true); + + Assert.assertEquals(" ADDRESSBLOCK ", field.getFieldCode()); + + // Setting this to "2" will include all countries and regions, + // unless it is the one specified in the ExcludedCountryOrRegionName property. + field.setIncludeCountryOrRegionName("2"); + field.setFormatAddressOnCountryOrRegion(true); + field.setExcludedCountryOrRegionName("United States"); + field.setNameAndAddressFormat(" <Forename> <Surname> <Address Line 1> <Region> <Postcode> <Country>"); + + // By default, this property will contain the language ID of the first character of the document. + // We can set a different culture for the field to format the result with like this. + field.setLanguageId("1033"); + + Assert.assertEquals( + " ADDRESSBLOCK \\c 2 \\d \\e \"United States\" \\f \"<Title> <Forename> <Surname> <Address Line 1> <Region> <Postcode> <Country>\" \\l 1033", + field.getFieldCode()); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + field = (FieldAddressBlock) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_ADDRESS_BLOCK, + " ADDRESSBLOCK \\c 2 \\d \\e \"United States\" \\f \"<Title> <Forename> <Surname> <Address Line 1> <Region> <Postcode> <Country>\" \\l 1033", + "«AddressBlock»", field); + Assert.assertEquals("2", field.getIncludeCountryOrRegionName()); + Assert.assertEquals(true, field.getFormatAddressOnCountryOrRegion()); + Assert.assertEquals("United States", field.getExcludedCountryOrRegionName()); + Assert.assertEquals("<Title> <Forename> <Surname> <Address Line 1> <Region> <Postcode> <Country>", + field.getNameAndAddressFormat()); + Assert.assertEquals("1033", field.getLanguageId()); + } + + //ExStart + //ExFor:FieldCollection + //ExFor:FieldCollection.Count + //ExFor:FieldCollection.GetEnumerator + //ExFor:FieldStart + //ExFor:FieldStart.Accept(DocumentVisitor) + //ExFor:FieldSeparator + //ExFor:FieldSeparator.Accept(DocumentVisitor) + //ExFor:FieldEnd + //ExFor:FieldEnd.Accept(DocumentVisitor) + //ExFor:FieldEnd.HasSeparator + //ExFor:Field.End + //ExFor:Field.Separator + //ExFor:Field.Start + //ExSummary:Shows how to work with a collection of fields. + @Test //ExSkip + public void fieldCollection() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField(" DATE \\@ \"dddd, d MMMM yyyy\" "); + builder.insertField(" TIME "); + builder.insertField(" REVNUM "); + builder.insertField(" AUTHOR \"John Doe\" "); + builder.insertField(" SUBJECT \"My Subject\" "); + builder.insertField(" QUOTE \"Hello world!\" "); + doc.updateFields(); + + FieldCollection fields = doc.getRange().getFields(); + + Assert.assertEquals(6, fields.getCount()); + + // Iterate over the field collection, and print contents and type + // of every field using a custom visitor implementation. + FieldVisitor fieldVisitor = new FieldVisitor(); + + Iterator<Field> fieldEnumerator = fields.iterator(); + + while (fieldEnumerator.hasNext()) { + if (fieldEnumerator != null) { + Field currentField = fieldEnumerator.next(); + + currentField.getStart().accept(fieldVisitor); + if (currentField.getSeparator() != null) { + currentField.getSeparator().accept(fieldVisitor); + } + currentField.getEnd().accept(fieldVisitor); + } else { + System.out.println("There are no fields in the document."); + } + } + + System.out.println(fieldVisitor.getText()); + testFieldCollection(fieldVisitor.getText()); //ExSkip + } + + /// <summary> + /// Document visitor implementation that prints field info. + /// </summary> + public static class FieldVisitor extends DocumentVisitor { + public FieldVisitor() { + mBuilder = new StringBuilder(); + } + + /// <summary> + /// Gets the plain text of the document that was accumulated by the visitor. + /// </summary> + public String getText() { + return mBuilder.toString(); + } + + /// <summary> + /// Called when a FieldStart node is encountered in the document. + /// </summary> + public int visitFieldStart(final FieldStart fieldStart) { + mBuilder.append("Found field: " + fieldStart.getFieldType() + "\r\n"); + mBuilder.append("\tField code: " + fieldStart.getField().getFieldCode() + "\r\n"); + mBuilder.append("\tDisplayed as: " + fieldStart.getField().getResult() + "\r\n"); + + return VisitorAction.CONTINUE; + } + + /// <summary> + /// Called when a FieldSeparator node is encountered in the document. + /// </summary> + public int visitFieldSeparator(final FieldSeparator fieldSeparator) { + mBuilder.append("\tFound separator: " + fieldSeparator.getText() + "\r\n"); + + return VisitorAction.CONTINUE; + } + + /// <summary> + /// Called when a FieldEnd node is encountered in the document. + /// </summary> + public int visitFieldEnd(final FieldEnd fieldEnd) { + mBuilder.append("End of field: " + fieldEnd.getFieldType() + "\r\n"); + + return VisitorAction.CONTINUE; + } + + private final /*final*/ StringBuilder mBuilder; + } + //ExEnd + + private void testFieldCollection(String fieldVisitorText) { + Assert.assertTrue(fieldVisitorText.contains("Found field: 31")); + Assert.assertTrue(fieldVisitorText.contains("Found field: 32")); + Assert.assertTrue(fieldVisitorText.contains("Found field: 24")); + Assert.assertTrue(fieldVisitorText.contains("Found field: 17")); + Assert.assertTrue(fieldVisitorText.contains("Found field: 16")); + Assert.assertTrue(fieldVisitorText.contains("Found field: 35")); + } + + @Test + public void removeFields() throws Exception { + //ExStart + //ExFor:FieldCollection + //ExFor:FieldCollection.Count + //ExFor:FieldCollection.Clear + //ExFor:FieldCollection.Item(Int32) + //ExFor:FieldCollection.Remove(Field) + //ExFor:FieldCollection.RemoveAt(Int32) + //ExFor:Field.Remove + //ExSummary:Shows how to remove fields from a field collection. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField(" DATE \\@ \"dddd, d MMMM yyyy\" "); + builder.insertField(" TIME "); + builder.insertField(" REVNUM "); + builder.insertField(" AUTHOR \"John Doe\" "); + builder.insertField(" SUBJECT \"My Subject\" "); + builder.insertField(" QUOTE \"Hello world!\" "); + doc.updateFields(); + + FieldCollection fields = doc.getRange().getFields(); + + Assert.assertEquals(6, fields.getCount()); + + // Below are four ways of removing fields from a field collection. + // 1 - Get a field to remove itself: + fields.get(0).remove(); + Assert.assertEquals(5, fields.getCount()); + + // 2 - Get the collection to remove a field that we pass to its removal method: + Field lastField = fields.get(3); + fields.remove(lastField); + Assert.assertEquals(4, fields.getCount()); + + // 3 - Remove a field from a collection at an index: + fields.removeAt(2); + Assert.assertEquals(3, fields.getCount()); + + // 4 - Remove all the fields from the collection at once: + fields.clear(); + Assert.assertEquals(0, fields.getCount()); + //ExEnd + } + + @Test + public void fieldCompare() throws Exception { + //ExStart + //ExFor:FieldCompare + //ExFor:FieldCompare.ComparisonOperator + //ExFor:FieldCompare.LeftExpression + //ExFor:FieldCompare.RightExpression + //ExSummary:Shows how to compare expressions using a COMPARE field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + FieldCompare field = (FieldCompare) builder.insertField(FieldType.FIELD_COMPARE, true); + field.setLeftExpression("3"); + field.setComparisonOperator("<"); + field.setRightExpression("2"); + field.update(); + + // The COMPARE field displays a "0" or a "1", depending on its statement's truth. + // The result of this statement is false so that this field will display a "0". + Assert.assertEquals(" COMPARE 3 < 2", field.getFieldCode()); + Assert.assertEquals("0", field.getResult()); + + builder.writeln(); + + field = (FieldCompare) builder.insertField(FieldType.FIELD_COMPARE, true); + field.setLeftExpression("5"); + field.setComparisonOperator("="); + field.setRightExpression("2 + 3"); + field.update(); + + // This field displays a "1" since the statement is true. + Assert.assertEquals(" COMPARE 5 = \"2 + 3\"", field.getFieldCode()); + Assert.assertEquals("1", field.getResult()); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.COMPARE.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.COMPARE.docx"); + + field = (FieldCompare) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_COMPARE, " COMPARE 3 < 2", "0", field); + Assert.assertEquals("3", field.getLeftExpression()); + Assert.assertEquals("<", field.getComparisonOperator()); + Assert.assertEquals("2", field.getRightExpression()); + + field = (FieldCompare) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_COMPARE, " COMPARE 5 = \"2 + 3\"", "1", field); + Assert.assertEquals("5", field.getLeftExpression()); + Assert.assertEquals("=", field.getComparisonOperator()); + Assert.assertEquals("\"2 + 3\"", field.getRightExpression()); + } + + @Test + public void fieldIf() throws Exception { + //ExStart + //ExFor:FieldIf + //ExFor:FieldIf.ComparisonOperator + //ExFor:FieldIf.EvaluateCondition + //ExFor:FieldIf.FalseText + //ExFor:FieldIf.LeftExpression + //ExFor:FieldIf.RightExpression + //ExFor:FieldIf.TrueText + //ExFor:FieldIfComparisonResult + //ExSummary:Shows how to insert an IF field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Statement 1: "); + FieldIf field = (FieldIf) builder.insertField(FieldType.FIELD_IF, true); + field.setLeftExpression("0"); + field.setComparisonOperator("="); + field.setRightExpression("1"); + + // The IF field will display a string from either its "TrueText" property, + // or its "FalseText" property, depending on the truth of the statement that we have constructed. + field.setTrueText("True"); + field.setFalseText("False"); + field.update(); + + // In this case, "0 = 1" is incorrect, so the displayed result will be "False". + Assert.assertEquals(" IF 0 = 1 True False", field.getFieldCode()); + Assert.assertEquals(FieldIfComparisonResult.FALSE, field.evaluateCondition()); + Assert.assertEquals("False", field.getResult()); + + builder.write("\nStatement 2: "); + field = (FieldIf) builder.insertField(FieldType.FIELD_IF, true); + field.setLeftExpression("5"); + field.setComparisonOperator("="); + field.setRightExpression("2 + 3"); + field.setTrueText("True"); + field.setFalseText("False"); + field.update(); + + // This time the statement is correct, so the displayed result will be "True". + Assert.assertEquals(" IF 5 = \"2 + 3\" True False", field.getFieldCode()); + Assert.assertEquals(FieldIfComparisonResult.TRUE, field.evaluateCondition()); + Assert.assertEquals("True", field.getResult()); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.IF.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.IF.docx"); + field = (FieldIf) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_IF, " IF 0 = 1 True False", "False", field); + Assert.assertEquals("0", field.getLeftExpression()); + Assert.assertEquals("=", field.getComparisonOperator()); + Assert.assertEquals("1", field.getRightExpression()); + Assert.assertEquals("True", field.getTrueText()); + Assert.assertEquals("False", field.getFalseText()); + + field = (FieldIf) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_IF, " IF 5 = \"2 + 3\" True False", "True", field); + Assert.assertEquals("5", field.getLeftExpression()); + Assert.assertEquals("=", field.getComparisonOperator()); + Assert.assertEquals("\"2 + 3\"", field.getRightExpression()); + Assert.assertEquals("True", field.getTrueText()); + Assert.assertEquals("False", field.getFalseText()); + } + + @Test + public void fieldAutoNum() throws Exception { + //ExStart + //ExFor:FieldAutoNum + //ExFor:FieldAutoNum.SeparatorCharacter + //ExSummary:Shows how to number paragraphs using autonum fields. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Each AUTONUM field displays the current value of a running count of AUTONUM fields, + // allowing us to automatically number items like a numbered list. + // This field will display a number "1.". + FieldAutoNum field = (FieldAutoNum) builder.insertField(FieldType.FIELD_AUTO_NUM, true); + builder.writeln("\tParagraph 1."); + + Assert.assertEquals(" AUTONUM ", field.getFieldCode()); + + field = (FieldAutoNum) builder.insertField(FieldType.FIELD_AUTO_NUM, true); + builder.writeln("\tParagraph 2."); + + // The separator character, which appears in the field result immediately after the number,is a full stop by default. + // If we leave this property null, our second AUTONUM field will display "2." in the document. + Assert.assertNull(field.getSeparatorCharacter()); + + // We can set this property to apply the first character of its string as the new separator character. + // In this case, our AUTONUM field will now display "2:". + field.setSeparatorCharacter(":"); + + Assert.assertEquals(" AUTONUM \\s :", field.getFieldCode()); + + doc.save(getArtifactsDir() + "Field.AUTONUM.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.AUTONUM.docx"); + + TestUtil.verifyField(FieldType.FIELD_AUTO_NUM, " AUTONUM ", "", doc.getRange().getFields().get(0)); + TestUtil.verifyField(FieldType.FIELD_AUTO_NUM, " AUTONUM \\s :", "", doc.getRange().getFields().get(1)); + } + + //ExStart + //ExFor:FieldAutoNumLgl + //ExFor:FieldAutoNumLgl.RemoveTrailingPeriod + //ExFor:FieldAutoNumLgl.SeparatorCharacter + //ExSummary:Shows how to organize a document using AUTONUMLGL fields. + @Test //ExSkip + public void fieldAutoNumLgl() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + final String FILLER_TEXT = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " + + "\nUt enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. "; + + // AUTONUMLGL fields display a number that increments at each AUTONUMLGL field within its current heading level. + // These fields maintain a separate count for each heading level, + // and each field also displays the AUTONUMLGL field counts for all heading levels below its own. + // Changing the count for any heading level resets the counts for all levels above that level to 1. + // This allows us to organize our document in the form of an outline list. + // This is the first AUTONUMLGL field at a heading level of 1, displaying "1." in the document. + insertNumberedClause(builder, "\tHeading 1", FILLER_TEXT, StyleIdentifier.HEADING_1); + + // This is the second AUTONUMLGL field at a heading level of 1, so it will display "2.". + insertNumberedClause(builder, "\tHeading 2", FILLER_TEXT, StyleIdentifier.HEADING_1); + + // This is the first AUTONUMLGL field at a heading level of 2, + // and the AUTONUMLGL count for the heading level below it is "2", so it will display "2.1.". + insertNumberedClause(builder, "\tHeading 3", FILLER_TEXT, StyleIdentifier.HEADING_2); + + // This is the first AUTONUMLGL field at a heading level of 3. + // Working in the same way as the field above, it will display "2.1.1.". + insertNumberedClause(builder, "\tHeading 4", FILLER_TEXT, StyleIdentifier.HEADING_3); + + // This field is at a heading level of 2, and its respective AUTONUMLGL count is at 2, so the field will display "2.2.". + insertNumberedClause(builder, "\tHeading 5", FILLER_TEXT, StyleIdentifier.HEADING_2); + + // Incrementing the AUTONUMLGL count for a heading level below this one + // has reset the count for this level so that this field will display "2.2.1.". + insertNumberedClause(builder, "\tHeading 6", FILLER_TEXT, StyleIdentifier.HEADING_3); + + for (Field field : doc.getRange().getFields()) { + if (field.getType() == FieldType.FIELD_AUTO_NUM_LEGAL) { + // The separator character, which appears in the field result immediately after the number, + // is a full stop by default. If we leave this property null, + // our last AUTONUMLGL field will display "2.2.1." in the document. + Assert.assertNull(((FieldAutoNumLgl) field).getSeparatorCharacter()); + + // Setting a custom separator character and removing the trailing period + // will change that field's appearance from "2.2.1." to "2:2:1". + // We will apply this to all the fields that we have created. + ((FieldAutoNumLgl) field).setSeparatorCharacter(":"); + ((FieldAutoNumLgl) field).setRemoveTrailingPeriod(true); + Assert.assertEquals(field.getFieldCode(), " AUTONUMLGL \\s : \\e"); + } + } + + doc.save(getArtifactsDir() + "Field.AUTONUMLGL.docx"); + testFieldAutoNumLgl(doc); //ExSkip + } + + /// <summary> + /// Uses a document builder to insert a clause numbered by an AUTONUMLGL field. + /// </summary> + private static void insertNumberedClause(DocumentBuilder builder, String heading, String contents, /*StyleIdentifier*/int headingStyle) throws Exception { + builder.insertField(FieldType.FIELD_AUTO_NUM_LEGAL, true); + builder.getCurrentParagraph().getParagraphFormat().setStyleIdentifier(headingStyle); + builder.writeln(heading); + + // This text will belong to the auto num legal field above it. + // It will collapse when we click the arrow next to the corresponding AUTONUMLGL field in Microsoft Word. + builder.getCurrentParagraph().getParagraphFormat().setStyleIdentifier(StyleIdentifier.BODY_TEXT); + builder.writeln(contents); + } + //ExEnd + + private void testFieldAutoNumLgl(Document doc) throws Exception { + doc = DocumentHelper.saveOpen(doc); + + for (Field field : doc.getRange().getFields()) { + if (field.getType() == FieldType.FIELD_AUTO_NUM_LEGAL) { + + FieldAutoNumLgl fieldAutoNumLgl = (FieldAutoNumLgl) field; + TestUtil.verifyField(FieldType.FIELD_AUTO_NUM_LEGAL, " AUTONUMLGL \\s : \\e", "", fieldAutoNumLgl); + + Assert.assertEquals(":", fieldAutoNumLgl.getSeparatorCharacter()); + Assert.assertTrue(fieldAutoNumLgl.getRemoveTrailingPeriod()); + } + } + } + + @Test + public void fieldAutoNumOut() throws Exception { + //ExStart + //ExFor:FieldAutoNumOut + //ExSummary:Shows how to number paragraphs using AUTONUMOUT fields. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // AUTONUMOUT fields display a number that increments at each AUTONUMOUT field. + // Unlike AUTONUM fields, AUTONUMOUT fields use the outline numbering scheme, + // which we can define in Microsoft Word via Format -> Bullets & Numbering -> "Outline Numbered". + // This allows us to automatically number items like a numbered list. + // LISTNUM fields are a newer alternative to AUTONUMOUT fields. + // This field will display "1.". + builder.insertField(FieldType.FIELD_AUTO_NUM_OUTLINE, true); + builder.writeln("\tParagraph 1."); + + // This field will display "2.". + builder.insertField(FieldType.FIELD_AUTO_NUM_OUTLINE, true); + builder.writeln("\tParagraph 2."); + + for (Field field : doc.getRange().getFields()) { + if (field.getType() == FieldType.FIELD_AUTO_NUM_OUTLINE) { + Assert.assertEquals(field.getFieldCode(), " AUTONUMOUT "); + } + } + + doc.save(getArtifactsDir() + "Field.AUTONUMOUT.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.AUTONUMOUT.docx"); + + for (Field field : doc.getRange().getFields()) + TestUtil.verifyField(FieldType.FIELD_AUTO_NUM_OUTLINE, " AUTONUMOUT ", "", field); + } + + @Test + public void fieldAutoText() throws Exception { + //ExStart + //ExFor:FieldAutoText + //ExFor:FieldAutoText.EntryName + //ExFor:FieldOptions.BuiltInTemplatesPaths + //ExFor:FieldGlossary + //ExFor:FieldGlossary.EntryName + //ExSummary:Shows how to display a building block with AUTOTEXT and GLOSSARY fields. + Document doc = new Document(); + + // Create a glossary document and add an AutoText building block to it. + doc.setGlossaryDocument(new GlossaryDocument()); + BuildingBlock buildingBlock = new BuildingBlock(doc.getGlossaryDocument()); + buildingBlock.setName("MyBlock"); + buildingBlock.setGallery(BuildingBlockGallery.AUTO_TEXT); + buildingBlock.setCategory("General"); + buildingBlock.setDescription("MyBlock description"); + buildingBlock.setBehavior(BuildingBlockBehavior.PARAGRAPH); + doc.getGlossaryDocument().appendChild(buildingBlock); + + // Create a source and add it as text to our building block. + Document buildingBlockSource = new Document(); + DocumentBuilder buildingBlockSourceBuilder = new DocumentBuilder(buildingBlockSource); + buildingBlockSourceBuilder.writeln("Hello World!"); + + Node buildingBlockContent = doc.getGlossaryDocument().importNode(buildingBlockSource.getFirstSection(), true); + buildingBlock.appendChild(buildingBlockContent); + + // Set a file which contains parts that our document, or its attached template may not contain. + doc.getFieldOptions().setBuiltInTemplatesPaths(new String[]{getMyDir() + "Busniess brochure.dotx"}); + + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are two ways to use fields to display the contents of our building block. + // 1 - Using an AUTOTEXT field: + FieldAutoText fieldAutoText = (FieldAutoText) builder.insertField(FieldType.FIELD_AUTO_TEXT, true); + fieldAutoText.setEntryName("MyBlock"); + + Assert.assertEquals(" AUTOTEXT MyBlock", fieldAutoText.getFieldCode()); + + // 2 - Using a GLOSSARY field: + FieldGlossary fieldGlossary = (FieldGlossary) builder.insertField(FieldType.FIELD_GLOSSARY, true); + fieldGlossary.setEntryName("MyBlock"); + + Assert.assertEquals(fieldGlossary.getFieldCode(), " GLOSSARY MyBlock"); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.AUTOTEXT.GLOSSARY.dotx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.AUTOTEXT.GLOSSARY.dotx"); + + Assert.assertTrue(doc.getFieldOptions().getBuiltInTemplatesPaths().length == 0); + + fieldAutoText = (FieldAutoText) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_AUTO_TEXT, " AUTOTEXT MyBlock", "Hello World!\r", fieldAutoText); + Assert.assertEquals("MyBlock", fieldAutoText.getEntryName()); + + fieldGlossary = (FieldGlossary) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_GLOSSARY, " GLOSSARY MyBlock", "Hello World!\r", fieldGlossary); + Assert.assertEquals("MyBlock", fieldGlossary.getEntryName()); + } + + //ExStart + //ExFor:FieldAutoTextList + //ExFor:FieldAutoTextList.EntryName + //ExFor:FieldAutoTextList.ListStyle + //ExFor:FieldAutoTextList.ScreenTip + //ExSummary:Shows how to use an AUTOTEXTLIST field to select from a list of AutoText entries. + @Test //ExSkip + public void fieldAutoTextList() throws Exception { + Document doc = new Document(); + + // Create a glossary document and populate it with auto text entries. + doc.setGlossaryDocument(new GlossaryDocument()); + appendAutoTextEntry(doc.getGlossaryDocument(), "AutoText 1", "Contents of AutoText 1"); + appendAutoTextEntry(doc.getGlossaryDocument(), "AutoText 2", "Contents of AutoText 2"); + appendAutoTextEntry(doc.getGlossaryDocument(), "AutoText 3", "Contents of AutoText 3"); + + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create an AUTOTEXTLIST field and set the text that the field will display in Microsoft Word. + // Set the text to prompt the user to right-click this field to select an AutoText building block, + // whose contents the field will display. + FieldAutoTextList field = (FieldAutoTextList) builder.insertField(FieldType.FIELD_AUTO_TEXT_LIST, true); + field.setEntryName("Right click here to select an AutoText block"); + field.setListStyle("Heading 1"); + field.setScreenTip("Hover tip text for AutoTextList goes here"); + + Assert.assertEquals(" AUTOTEXTLIST \"Right click here to select an AutoText block\" " + + "\\s \"Heading 1\" " + + "\\t \"Hover tip text for AutoTextList goes here\"", field.getFieldCode()); + + doc.save(getArtifactsDir() + "Field.AUTOTEXTLIST.dotx"); + testFieldAutoTextList(doc); //ExSkip + } + + /// <summary> + /// Create an AutoText-type building block and add it to a glossary document. + /// </summary> + private static void appendAutoTextEntry(GlossaryDocument glossaryDoc, String name, String contents) { + BuildingBlock buildingBlock = new BuildingBlock(glossaryDoc); + buildingBlock.setName(name); + buildingBlock.setGallery(BuildingBlockGallery.AUTO_TEXT); + buildingBlock.setCategory("General"); + buildingBlock.setBehavior(BuildingBlockBehavior.PARAGRAPH); + + Section section = new Section(glossaryDoc); + section.appendChild(new Body(glossaryDoc)); + section.getBody().appendParagraph(contents); + buildingBlock.appendChild(section); + + glossaryDoc.appendChild(buildingBlock); + } + //ExEnd + + private void testFieldAutoTextList(Document doc) throws Exception { + doc = DocumentHelper.saveOpen(doc); + + Assert.assertEquals(3, doc.getGlossaryDocument().getCount()); + Assert.assertEquals("AutoText 1", doc.getGlossaryDocument().getBuildingBlocks().get(0).getName()); + Assert.assertEquals("Contents of AutoText 1", doc.getGlossaryDocument().getBuildingBlocks().get(0).getText().trim()); + Assert.assertEquals("AutoText 2", doc.getGlossaryDocument().getBuildingBlocks().get(1).getName()); + Assert.assertEquals("Contents of AutoText 2", doc.getGlossaryDocument().getBuildingBlocks().get(1).getText().trim()); + Assert.assertEquals("AutoText 3", doc.getGlossaryDocument().getBuildingBlocks().get(2).getName()); + Assert.assertEquals("Contents of AutoText 3", doc.getGlossaryDocument().getBuildingBlocks().get(2).getText().trim()); + + FieldAutoTextList field = (FieldAutoTextList) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_AUTO_TEXT_LIST, + " AUTOTEXTLIST \"Right click here to select an AutoText block\" \\s \"Heading 1\" \\t \"Hover tip text for AutoTextList goes here\"", + "", field); + Assert.assertEquals("Right click here to select an AutoText block", field.getEntryName()); + Assert.assertEquals("Heading 1", field.getListStyle()); + Assert.assertEquals("Hover tip text for AutoTextList goes here", field.getScreenTip()); + } + + @Test + public void fieldGreetingLine() throws Exception { + //ExStart + //ExFor:FieldGreetingLine + //ExFor:FieldGreetingLine.AlternateText + //ExFor:FieldGreetingLine.GetFieldNames + //ExFor:FieldGreetingLine.LanguageId + //ExFor:FieldGreetingLine.NameFormat + //ExSummary:Shows how to insert a GREETINGLINE field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a generic greeting using a GREETINGLINE field, and some text after it. + FieldGreetingLine field = (FieldGreetingLine) builder.insertField(FieldType.FIELD_GREETING_LINE, true); + builder.writeln("\n\n\tThis is your custom greeting, created programmatically using Aspose Words!"); + + // A GREETINGLINE field accepts values from a data source during a mail merge, like a MERGEFIELD. + // It can also format how the source's data is written in its place once the mail merge is complete. + // The field names collection corresponds to the columns from the data source + // that the field will take values from. + Assert.assertEquals(0, field.getFieldNames().length); + + // To populate that array, we need to specify a format for our greeting line. + field.setNameFormat("<< _BEFORE_ Dear >><< _TITLE0_ >><< _LAST0_ >><< _AFTER_ ,>> "); + + // Now, our field will accept values from these two columns in the data source. + Assert.assertEquals("Courtesy Title", field.getFieldNames()[0]); + Assert.assertEquals("Last Name", field.getFieldNames()[1]); + Assert.assertEquals(2, field.getFieldNames().length); + + // This string will cover any cases where the data table data is invalid + // by substituting the malformed name with a string. + field.setAlternateText("Sir or Madam"); + + // Set a locale to format the result. + field.setLanguageId("1033"); + + Assert.assertEquals(" GREETINGLINE \\f \"<< _BEFORE_ Dear >><< _TITLE0_ >><< _LAST0_ >><< _AFTER_ ,>> \" \\e \"Sir or Madam\" \\l 1033", + field.getFieldCode()); + + // Create a data table with columns whose names match elements + // from the field's field names collection, and then carry out the mail merge. + DataTable table = new DataTable("Employees"); + table.getColumns().add("Courtesy Title"); + table.getColumns().add("First Name"); + table.getColumns().add("Last Name"); + table.getRows().add("Mr.", "John", "Doe"); + table.getRows().add("Mrs.", "Jane", "Cardholder"); + + // This row has an invalid value in the Courtesy Title column, so our greeting will default to the alternate text. + table.getRows().add("", "No", "Name"); + + doc.getMailMerge().execute(table); + + Assert.assertTrue(doc.getRange().getFields().getCount() == 0); + Assert.assertEquals("Dear Mr. Doe,\r\r\tThis is your custom greeting, created programmatically using Aspose Words!\r" + + "\fDear Mrs. Cardholder,\r\r\tThis is your custom greeting, created programmatically using Aspose Words!\r" + + "\fDear Sir or Madam,\r\r\tThis is your custom greeting, created programmatically using Aspose Words!", + doc.getText().trim()); + //ExEnd + } + + @Test + public void fieldListNum() throws Exception { + //ExStart + //ExFor:FieldListNum + //ExFor:FieldListNum.HasListName + //ExFor:FieldListNum.ListLevel + //ExFor:FieldListNum.ListName + //ExFor:FieldListNum.StartingNumber + //ExSummary:Shows how to number paragraphs with LISTNUM fields. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // LISTNUM fields display a number that increments at each LISTNUM field. + // These fields also have a variety of options that allow us to use them to emulate numbered lists. + FieldListNum field = (FieldListNum) builder.insertField(FieldType.FIELD_LIST_NUM, true); + + // Lists start counting at 1 by default, but we can set this number to a different value, such as 0. + // This field will display "0)". + field.setStartingNumber("0"); + builder.writeln("Paragraph 1"); + + Assert.assertEquals(" LISTNUM \\s 0", field.getFieldCode()); + + // LISTNUM fields maintain separate counts for each list level. + // Inserting a LISTNUM field in the same paragraph as another LISTNUM field + // increases the list level instead of the count. + // The next field will continue the count we started above and display a value of "1" at list level 1. + builder.insertField(FieldType.FIELD_LIST_NUM, true); + + // This field will start a count at list level 2. It will display a value of "1". + builder.insertField(FieldType.FIELD_LIST_NUM, true); + + // This field will start a count at list level 3. It will display a value of "1". + // Different list levels have different formatting, + // so these fields combined will display a value of "1)a)i)". + builder.insertField(FieldType.FIELD_LIST_NUM, true); + builder.writeln("Paragraph 2"); + + // The next LISTNUM field that we insert will continue the count at the list level + // that the previous LISTNUM field was on. + // We can use the "ListLevel" property to jump to a different list level. + // If this LISTNUM field stayed on list level 3, it would display "ii)", + // but, since we have moved it to list level 2, it carries on the count at that level and displays "b)". + field = (FieldListNum) builder.insertField(FieldType.FIELD_LIST_NUM, true); + field.setListLevel("2"); + builder.writeln("Paragraph 3"); + + Assert.assertEquals(" LISTNUM \\l 2", field.getFieldCode()); + + // We can set the ListName property to get the field to emulate a different AUTONUM field type. + // "NumberDefault" emulates AUTONUM, "OutlineDefault" emulates AUTONUMOUT, + // and "LegalDefault" emulates AUTONUMLGL fields. + // The "OutlineDefault" list name with 1 as the starting number will result in displaying "I.". + field = (FieldListNum) builder.insertField(FieldType.FIELD_LIST_NUM, true); + field.setStartingNumber("1"); + field.setListName("OutlineDefault"); + builder.writeln("Paragraph 4"); + + Assert.assertTrue(field.hasListName()); + Assert.assertEquals(" LISTNUM OutlineDefault \\s 1", field.getFieldCode()); + + // The ListName does not carry over from the previous field, so we will need to set it for each new field. + // This field continues the count with the different list name, and displays "II.". + field = (FieldListNum) builder.insertField(FieldType.FIELD_LIST_NUM, true); + field.setListName("OutlineDefault"); + builder.writeln("Paragraph 5"); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.LISTNUM.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.LISTNUM.docx"); + + Assert.assertEquals(7, doc.getRange().getFields().getCount()); + + field = (FieldListNum) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_LIST_NUM, " LISTNUM \\s 0", "", field); + Assert.assertEquals("0", field.getStartingNumber()); + Assert.assertNull(field.getListLevel()); + Assert.assertFalse(field.hasListName()); + Assert.assertNull(field.getListName()); + + for (int i = 1; i < 4; i++) { + field = (FieldListNum) doc.getRange().getFields().get(i); + + TestUtil.verifyField(FieldType.FIELD_LIST_NUM, " LISTNUM ", "", field); + Assert.assertNull(field.getStartingNumber()); + Assert.assertNull(field.getListLevel()); + Assert.assertFalse(field.hasListName()); + Assert.assertNull(field.getListName()); + } + + field = (FieldListNum) doc.getRange().getFields().get(4); + + TestUtil.verifyField(FieldType.FIELD_LIST_NUM, " LISTNUM \\l 2", "", field); + Assert.assertNull(field.getStartingNumber()); + Assert.assertEquals("2", field.getListLevel()); + Assert.assertFalse(field.hasListName()); + Assert.assertNull(field.getListName()); + + field = (FieldListNum) doc.getRange().getFields().get(5); + + TestUtil.verifyField(FieldType.FIELD_LIST_NUM, " LISTNUM OutlineDefault \\s 1", "", field); + Assert.assertEquals("1", field.getStartingNumber()); + Assert.assertNull(field.getListLevel()); + Assert.assertTrue(field.hasListName()); + Assert.assertEquals("OutlineDefault", field.getListName()); + } + + @Test + public void mergeField() throws Exception { + //ExStart + //ExFor:FieldMergeField + //ExFor:FieldMergeField.FieldName + //ExFor:FieldMergeField.FieldNameNoPrefix + //ExFor:FieldMergeField.IsMapped + //ExFor:FieldMergeField.IsVerticalFormatting + //ExFor:FieldMergeField.TextAfter + //ExFor:FieldMergeField.TextBefore + //ExFor:FieldMergeField.Type + //ExSummary:Shows how to use MERGEFIELD fields to perform a mail merge. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a data table to be used as a mail merge data source. + DataTable table = new DataTable("Employees"); + table.getColumns().add("Courtesy Title"); + table.getColumns().add("First Name"); + table.getColumns().add("Last Name"); + table.getRows().add("Mr.", "John", "Doe"); + table.getRows().add("Mrs.", "Jane", "Cardholder"); + + // Insert a MERGEFIELD with a FieldName property set to the name of a column in the data source. + FieldMergeField fieldMergeField = (FieldMergeField) builder.insertField(FieldType.FIELD_MERGE_FIELD, true); + fieldMergeField.setFieldName("Courtesy Title"); + fieldMergeField.isMapped(true); + fieldMergeField.isVerticalFormatting(false); + + // We can apply text before and after the value that this field accepts when the merge takes place. + fieldMergeField.setTextBefore("Dear "); + fieldMergeField.setTextAfter(" "); + + Assert.assertEquals(" MERGEFIELD \"Courtesy Title\" \\m \\b \"Dear \" \\f \" \"", fieldMergeField.getFieldCode()); + Assert.assertEquals(FieldType.FIELD_MERGE_FIELD, fieldMergeField.getType()); + + // Insert another MERGEFIELD for a different column in the data source. + fieldMergeField = (FieldMergeField) builder.insertField(FieldType.FIELD_MERGE_FIELD, true); + fieldMergeField.setFieldName("Last Name"); + fieldMergeField.setTextAfter(":"); + + doc.updateFields(); + doc.getMailMerge().execute(table); + + Assert.assertEquals("Dear Mr. Doe:\fDear Mrs. Cardholder:", doc.getText().trim()); + //ExEnd + + Assert.assertTrue(doc.getRange().getFields().getCount() == 0); + } + + //ExStart + //ExFor:FieldToc + //ExFor:FieldToc.BookmarkName + //ExFor:FieldToc.CustomStyles + //ExFor:FieldToc.EntrySeparator + //ExFor:FieldToc.HeadingLevelRange + //ExFor:FieldToc.HideInWebLayout + //ExFor:FieldToc.InsertHyperlinks + //ExFor:FieldToc.PageNumberOmittingLevelRange + //ExFor:FieldToc.PreserveLineBreaks + //ExFor:FieldToc.PreserveTabs + //ExFor:FieldToc.UpdatePageNumbers + //ExFor:FieldToc.UseParagraphOutlineLevel + //ExFor:FieldOptions.CustomTocStyleSeparator + //ExSummary:Shows how to insert a TOC, and populate it with entries based on heading styles. + @Test //ExSkip + public void fieldToc() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startBookmark("MyBookmark"); + + // Insert a TOC field, which will compile all headings into a table of contents. + // For each heading, this field will create a line with the text in that heading style to the left, + // and the page the heading appears on to the right. + FieldToc field = (FieldToc) builder.insertField(FieldType.FIELD_TOC, true); + + // Use the BookmarkName property to only list headings + // that appear within the bounds of a bookmark with the "MyBookmark" name. + field.setBookmarkName("MyBookmark"); + + // Text with a built-in heading style, such as "Heading 1", applied to it will count as a heading. + // We can name additional styles to be picked up as headings by the TOC in this property and their TOC levels. + field.setCustomStyles("Quote; 6; Intense Quote; 7"); + + // By default, Styles/TOC levels are separated in the CustomStyles property by a comma, + // but we can set a custom delimiter in this property. + doc.getFieldOptions().setCustomTocStyleSeparator(";"); + + // Configure the field to exclude any headings that have TOC levels outside of this range. + field.setHeadingLevelRange("1-3"); + + // The TOC will not display the page numbers of headings whose TOC levels are within this range. + field.setPageNumberOmittingLevelRange("2-5"); + + // Set a custom string that will separate every heading from its page number. + field.setEntrySeparator("-"); + field.setInsertHyperlinks(true); + field.setHideInWebLayout(false); + field.setPreserveLineBreaks(true); + field.setPreserveTabs(true); + field.setUseParagraphOutlineLevel(false); + + insertNewPageWithHeading(builder, "First entry", "Heading 1"); + builder.writeln("Paragraph text."); + insertNewPageWithHeading(builder, "Second entry", "Heading 1"); + insertNewPageWithHeading(builder, "Third entry", "Quote"); + insertNewPageWithHeading(builder, "Fourth entry", "Intense Quote"); + + // These two headings will have the page numbers omitted because they are within the "2-5" range. + insertNewPageWithHeading(builder, "Fifth entry", "Heading 2"); + insertNewPageWithHeading(builder, "Sixth entry", "Heading 3"); + + // This entry does not appear because "Heading 4" is outside of the "1-3" range that we have set earlier. + insertNewPageWithHeading(builder, "Seventh entry", "Heading 4"); + + builder.endBookmark("MyBookmark"); + builder.writeln("Paragraph text."); + + // This entry does not appear because it is outside the bookmark specified by the TOC. + insertNewPageWithHeading(builder, "Eighth entry", "Heading 1"); + + Assert.assertEquals(" TOC \\b MyBookmark \\t \"Quote; 6; Intense Quote; 7\" \\o 1-3 \\n 2-5 \\p - \\h \\x \\w", field.getFieldCode()); + + field.updatePageNumbers(); + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.TOC.docx"); + testFieldToc(doc); //ExSkip + } + + /// <summary> + /// Start a new page and insert a paragraph of a specified style. + /// </summary> + @Test(enabled = false) //ExSkip + public void insertNewPageWithHeading(final DocumentBuilder builder, final String captionText, final String styleName) { + builder.insertBreak(BreakType.PAGE_BREAK); + String originalStyle = builder.getParagraphFormat().getStyleName(); + builder.getParagraphFormat().setStyle(builder.getDocument().getStyles().get(styleName)); + builder.writeln(captionText); + builder.getParagraphFormat().setStyle(builder.getDocument().getStyles().get(originalStyle)); + } + //ExEnd + + private void testFieldToc(Document doc) throws Exception { + doc = DocumentHelper.saveOpen(doc); + FieldToc field = (FieldToc) doc.getRange().getFields().get(0); + + Assert.assertEquals("MyBookmark", field.getBookmarkName()); + Assert.assertEquals("Quote; 6; Intense Quote; 7", field.getCustomStyles()); + Assert.assertEquals("-", field.getEntrySeparator()); + Assert.assertEquals("1-3", field.getHeadingLevelRange()); + Assert.assertEquals("2-5", field.getPageNumberOmittingLevelRange()); + Assert.assertFalse(field.getHideInWebLayout()); + Assert.assertTrue(field.getInsertHyperlinks()); + Assert.assertTrue(field.getPreserveLineBreaks()); + Assert.assertTrue(field.getPreserveTabs()); + Assert.assertTrue(field.updatePageNumbers()); + Assert.assertFalse(field.getUseParagraphOutlineLevel()); + Assert.assertEquals(" TOC \\b MyBookmark \\t \"Quote; 6; Intense Quote; 7\" \\o 1-3 \\n 2-5 \\p - \\h \\x \\w", field.getFieldCode()); + Assert.assertEquals("\u0013 HYPERLINK \\l \"_Toc256000001\" \u0014First entry-\u0013 PAGEREF _Toc256000001 \\h \u00142\u0015\u0015\r" + + "\u0013 HYPERLINK \\l \"_Toc256000002\" \u0014Second entry-\u0013 PAGEREF _Toc256000002 \\h \u00143\u0015\u0015\r" + + "\u0013 HYPERLINK \\l \"_Toc256000003\" \u0014Third entry-\u0013 PAGEREF _Toc256000003 \\h \u00144\u0015\u0015\r" + + "\u0013 HYPERLINK \\l \"_Toc256000004\" \u0014Fourth entry-\u0013 PAGEREF _Toc256000004 \\h \u00145\u0015\u0015\r" + + "\u0013 HYPERLINK \\l \"_Toc256000005\" \u0014Fifth entry\u0015\r" + + "\u0013 HYPERLINK \\l \"_Toc256000006\" \u0014Sixth entry\u0015\r", field.getResult()); + } + + //ExStart + //ExFor:FieldToc.EntryIdentifier + //ExFor:FieldToc.EntryLevelRange + //ExFor:FieldTC + //ExFor:FieldTC.OmitPageNumber + //ExFor:FieldTC.Text + //ExFor:FieldTC.TypeIdentifier + //ExFor:FieldTC.EntryLevel + //ExSummary:Shows how to insert a TOC field, and filter which TC fields end up as entries. + @Test //ExSkip + public void fieldTocEntryIdentifier() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a TOC field, which will compile all TC fields into a table of contents. + FieldToc fieldToc = (FieldToc) builder.insertField(FieldType.FIELD_TOC, true); + + // Configure the field only to pick up TC entries of the "A" type, and an entry-level between 1 and 3. + fieldToc.setEntryIdentifier("A"); + fieldToc.setEntryLevelRange("1-3"); + + Assert.assertEquals(" TOC \\f A \\l 1-3", fieldToc.getFieldCode()); + + // These two entries will appear in the table. + builder.insertBreak(BreakType.PAGE_BREAK); + insertTocEntry(builder, "TC field 1", "A", "1"); + insertTocEntry(builder, "TC field 2", "A", "2"); + + Assert.assertEquals(" TC \"TC field 1\" \\n \\f A \\l 1", doc.getRange().getFields().get(1).getFieldCode()); + + // This entry will be omitted from the table because it has a different type from "A". + insertTocEntry(builder, "TC field 3", "B", "1"); + + // This entry will be omitted from the table because it has an entry-level outside of the 1-3 range. + insertTocEntry(builder, "TC field 4", "A", "5"); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.TC.docx"); + testFieldTocEntryIdentifier(doc); //ExSkip + } + + /// <summary> + /// Use a document builder to insert a TC field. + /// </summary> + @Test(enabled = false) //ExSkip + public void insertTocEntry(final DocumentBuilder builder, final String text, final String typeIdentifier, final String entryLevel) throws Exception { + FieldTC fieldTc = (FieldTC) builder.insertField(FieldType.FIELD_TOC_ENTRY, true); + fieldTc.setOmitPageNumber(true); + fieldTc.setText(text); + fieldTc.setTypeIdentifier(typeIdentifier); + fieldTc.setEntryLevel(entryLevel); + } + //ExEnd + + private void testFieldTocEntryIdentifier(Document doc) throws Exception { + doc = DocumentHelper.saveOpen(doc); + FieldToc fieldToc = (FieldToc) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_TOC, " TOC \\f A \\l 1-3", "TC field 1\rTC field 2\r", fieldToc); + Assert.assertEquals("A", fieldToc.getEntryIdentifier()); + Assert.assertEquals("1-3", fieldToc.getEntryLevelRange()); + + FieldTC fieldTc = (FieldTC) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_TOC_ENTRY, " TC \"TC field 1\" \\n \\f A \\l 1", "", fieldTc); + Assert.assertTrue(fieldTc.getOmitPageNumber()); + Assert.assertEquals("TC field 1", fieldTc.getText()); + Assert.assertEquals("A", fieldTc.getTypeIdentifier()); + Assert.assertEquals("1", fieldTc.getEntryLevel()); + + fieldTc = (FieldTC) doc.getRange().getFields().get(2); + + TestUtil.verifyField(FieldType.FIELD_TOC_ENTRY, " TC \"TC field 2\" \\n \\f A \\l 2", "", fieldTc); + Assert.assertTrue(fieldTc.getOmitPageNumber()); + Assert.assertEquals("TC field 2", fieldTc.getText()); + Assert.assertEquals("A", fieldTc.getTypeIdentifier()); + Assert.assertEquals("2", fieldTc.getEntryLevel()); + + fieldTc = (FieldTC) doc.getRange().getFields().get(3); + + TestUtil.verifyField(FieldType.FIELD_TOC_ENTRY, " TC \"TC field 3\" \\n \\f B \\l 1", "", fieldTc); + Assert.assertTrue(fieldTc.getOmitPageNumber()); + Assert.assertEquals("TC field 3", fieldTc.getText()); + Assert.assertEquals("B", fieldTc.getTypeIdentifier()); + Assert.assertEquals("1", fieldTc.getEntryLevel()); + + fieldTc = (FieldTC) doc.getRange().getFields().get(4); + + TestUtil.verifyField(FieldType.FIELD_TOC_ENTRY, " TC \"TC field 4\" \\n \\f A \\l 5", "", fieldTc); + Assert.assertTrue(fieldTc.getOmitPageNumber()); + Assert.assertEquals("TC field 4", fieldTc.getText()); + Assert.assertEquals("A", fieldTc.getTypeIdentifier()); + Assert.assertEquals("5", fieldTc.getEntryLevel()); + } + + @Test + public void tocSeqPrefix() throws Exception { + //ExStart + //ExFor:FieldToc + //ExFor:FieldToc.TableOfFiguresLabel + //ExFor:FieldToc.PrefixedSequenceIdentifier + //ExFor:FieldToc.SequenceSeparator + //ExFor:FieldSeq + //ExFor:FieldSeq.SequenceIdentifier + //ExSummary:Shows how to populate a TOC field with entries using SEQ fields. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // A TOC field can create an entry in its table of contents for each SEQ field found in the document. + // Each entry contains the paragraph that includes the SEQ field and the page's number that the field appears on. + FieldToc fieldToc = (FieldToc) builder.insertField(FieldType.FIELD_TOC, true); + + // SEQ fields display a count that increments at each SEQ field. + // These fields also maintain separate counts for each unique named sequence + // identified by the SEQ field's "SequenceIdentifier" property. + // Use the "TableOfFiguresLabel" property to name a main sequence for the TOC. + // Now, this TOC will only create entries out of SEQ fields with their "SequenceIdentifier" set to "MySequence". + fieldToc.setTableOfFiguresLabel("MySequence"); + + // We can name another SEQ field sequence in the "PrefixedSequenceIdentifier" property. + // SEQ fields from this prefix sequence will not create TOC entries. + // Every TOC entry created from a main sequence SEQ field will now also display the count that + // the prefix sequence is currently on at the primary sequence SEQ field that made the entry. + fieldToc.setPrefixedSequenceIdentifier("PrefixSequence"); + + // Each TOC entry will display the prefix sequence count immediately to the left + // of the page number that the main sequence SEQ field appears on. + // We can specify a custom separator that will appear between these two numbers. + fieldToc.setSequenceSeparator(">"); + + Assert.assertEquals(" TOC \\c MySequence \\s PrefixSequence \\d >", fieldToc.getFieldCode()); + + builder.insertBreak(BreakType.PAGE_BREAK); + + // There are two ways of using SEQ fields to populate this TOC. + // 1 - Inserting a SEQ field that belongs to the TOC's prefix sequence: + // This field will increment the SEQ sequence count for the "PrefixSequence" by 1. + // Since this field does not belong to the main sequence identified + // by the "TableOfFiguresLabel" property of the TOC, it will not appear as an entry. + FieldSeq fieldSeq = (FieldSeq) builder.insertField(FieldType.FIELD_SEQUENCE, true); + fieldSeq.setSequenceIdentifier("PrefixSequence"); + builder.insertParagraph(); + + Assert.assertEquals(" SEQ PrefixSequence", fieldSeq.getFieldCode()); + + // 2 - Inserting a SEQ field that belongs to the TOC's main sequence: + // This SEQ field will create an entry in the TOC. + // The TOC entry will contain the paragraph that the SEQ field is in and the number of the page that it appears on. + // This entry will also display the count that the prefix sequence is currently at, + // separated from the page number by the value in the TOC's SeqenceSeparator property. + // The "PrefixSequence" count is at 1, this main sequence SEQ field is on page 2, + // and the separator is ">", so entry will display "1>2". + builder.write("First TOC entry, MySequence #"); + fieldSeq = (FieldSeq) builder.insertField(FieldType.FIELD_SEQUENCE, true); + fieldSeq.setSequenceIdentifier("MySequence"); + + Assert.assertEquals(" SEQ MySequence", fieldSeq.getFieldCode()); + + // Insert a page, advance the prefix sequence by 2, and insert a SEQ field to create a TOC entry afterwards. + // The prefix sequence is now at 2, and the main sequence SEQ field is on page 3, + // so the TOC entry will display "2>3" at its page count. + builder.insertBreak(BreakType.PAGE_BREAK); + fieldSeq = (FieldSeq) builder.insertField(FieldType.FIELD_SEQUENCE, true); + fieldSeq.setSequenceIdentifier("PrefixSequence"); + builder.insertParagraph(); + fieldSeq = (FieldSeq) builder.insertField(FieldType.FIELD_SEQUENCE, true); + builder.write("Second TOC entry, MySequence #"); + fieldSeq.setSequenceIdentifier("MySequence"); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.TOC.SEQ.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.TOC.SEQ.docx"); + + Assert.assertEquals(9, doc.getRange().getFields().getCount()); + + fieldToc = (FieldToc) doc.getRange().getFields().get(0); + System.out.println(fieldToc.getDisplayResult()); + TestUtil.verifyField(FieldType.FIELD_TOC, " TOC \\c MySequence \\s PrefixSequence \\d >", + "First TOC entry, MySequence #12\t\u0013 SEQ PrefixSequence _Toc256000000 \\* ARABIC \u00141\u0015>\u0013 PAGEREF _Toc256000000 \\h \u00142\u0015\r2" + + "Second TOC entry, MySequence #\t\u0013 SEQ PrefixSequence _Toc256000001 \\* ARABIC \u00142\u0015>\u0013 PAGEREF _Toc256000001 \\h \u00143\u0015\r", + fieldToc); + Assert.assertEquals("MySequence", fieldToc.getTableOfFiguresLabel()); + Assert.assertEquals("PrefixSequence", fieldToc.getPrefixedSequenceIdentifier()); + Assert.assertEquals(">", fieldToc.getSequenceSeparator()); + + fieldSeq = (FieldSeq) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_SEQUENCE, " SEQ PrefixSequence _Toc256000000 \\* ARABIC ", "1", fieldSeq); + Assert.assertEquals("PrefixSequence", fieldSeq.getSequenceIdentifier()); + + // Byproduct field created by Aspose.Words + FieldPageRef fieldPageRef = (FieldPageRef) doc.getRange().getFields().get(2); + + TestUtil.verifyField(FieldType.FIELD_PAGE_REF, " PAGEREF _Toc256000000 \\h ", "2", fieldPageRef); + Assert.assertEquals("PrefixSequence", fieldSeq.getSequenceIdentifier()); + Assert.assertEquals("_Toc256000000", fieldPageRef.getBookmarkName()); + + fieldSeq = (FieldSeq) doc.getRange().getFields().get(3); + + TestUtil.verifyField(FieldType.FIELD_SEQUENCE, " SEQ PrefixSequence _Toc256000001 \\* ARABIC ", "2", fieldSeq); + Assert.assertEquals("PrefixSequence", fieldSeq.getSequenceIdentifier()); + + fieldPageRef = (FieldPageRef) doc.getRange().getFields().get(4); + + TestUtil.verifyField(FieldType.FIELD_PAGE_REF, " PAGEREF _Toc256000001 \\h ", "3", fieldPageRef); + Assert.assertEquals("PrefixSequence", fieldSeq.getSequenceIdentifier()); + Assert.assertEquals("_Toc256000001", fieldPageRef.getBookmarkName()); + + fieldSeq = (FieldSeq) doc.getRange().getFields().get(5); + + TestUtil.verifyField(FieldType.FIELD_SEQUENCE, " SEQ PrefixSequence", "1", fieldSeq); + Assert.assertEquals("PrefixSequence", fieldSeq.getSequenceIdentifier()); + + fieldSeq = (FieldSeq) doc.getRange().getFields().get(6); + + TestUtil.verifyField(FieldType.FIELD_SEQUENCE, " SEQ MySequence", "1", fieldSeq); + Assert.assertEquals("MySequence", fieldSeq.getSequenceIdentifier()); + + fieldSeq = (FieldSeq) doc.getRange().getFields().get(7); + + TestUtil.verifyField(FieldType.FIELD_SEQUENCE, " SEQ PrefixSequence", "2", fieldSeq); + Assert.assertEquals("PrefixSequence", fieldSeq.getSequenceIdentifier()); + + fieldSeq = (FieldSeq) doc.getRange().getFields().get(8); + + TestUtil.verifyField(FieldType.FIELD_SEQUENCE, " SEQ MySequence", "2", fieldSeq); + Assert.assertEquals("MySequence", fieldSeq.getSequenceIdentifier()); + } + + @Test + public void tocSeqNumbering() throws Exception { + //ExStart + //ExFor:FieldSeq + //ExFor:FieldSeq.InsertNextNumber + //ExFor:FieldSeq.ResetHeadingLevel + //ExFor:FieldSeq.ResetNumber + //ExFor:FieldSeq.SequenceIdentifier + //ExSummary:Shows create numbering using SEQ fields. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // SEQ fields display a count that increments at each SEQ field. + // These fields also maintain separate counts for each unique named sequence + // identified by the SEQ field's "SequenceIdentifier" property. + // Insert a SEQ field that will display the current count value of "MySequence", + // after using the "ResetNumber" property to set it to 100. + builder.write("#"); + FieldSeq fieldSeq = (FieldSeq) builder.insertField(FieldType.FIELD_SEQUENCE, true); + fieldSeq.setSequenceIdentifier("MySequence"); + fieldSeq.setResetNumber("100"); + fieldSeq.update(); + + Assert.assertEquals(" SEQ MySequence \\r 100", fieldSeq.getFieldCode()); + Assert.assertEquals("100", fieldSeq.getResult()); + + // Display the next number in this sequence with another SEQ field. + builder.write(", #"); + fieldSeq = (FieldSeq) builder.insertField(FieldType.FIELD_SEQUENCE, true); + fieldSeq.setSequenceIdentifier("MySequence"); + fieldSeq.update(); + + Assert.assertEquals("101", fieldSeq.getResult()); + + // Insert a level 1 heading. + builder.insertBreak(BreakType.PARAGRAPH_BREAK); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 1")); + builder.writeln("This level 1 heading will reset MySequence to 1"); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Normal")); + + // Insert another SEQ field from the same sequence and configure it to reset the count at every heading with 1. + builder.write("\n#"); + fieldSeq = (FieldSeq) builder.insertField(FieldType.FIELD_SEQUENCE, true); + fieldSeq.setSequenceIdentifier("MySequence"); + fieldSeq.setResetHeadingLevel("1"); + fieldSeq.update(); + + // The above heading is a level 1 heading, so the count for this sequence is reset to 1. + Assert.assertEquals(" SEQ MySequence \\s 1", fieldSeq.getFieldCode()); + Assert.assertEquals("1", fieldSeq.getResult()); + + // Move to the next number of this sequence. + builder.write(", #"); + fieldSeq = (FieldSeq) builder.insertField(FieldType.FIELD_SEQUENCE, true); + fieldSeq.setSequenceIdentifier("MySequence"); + fieldSeq.setInsertNextNumber(true); + fieldSeq.update(); + + Assert.assertEquals(" SEQ MySequence \\n", fieldSeq.getFieldCode()); + Assert.assertEquals("2", fieldSeq.getResult()); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.SEQ.ResetNumbering.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.SEQ.ResetNumbering.docx"); + + Assert.assertEquals(4, doc.getRange().getFields().getCount()); + + fieldSeq = (FieldSeq) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_SEQUENCE, " SEQ MySequence \\r 100", "100", fieldSeq); + Assert.assertEquals("MySequence", fieldSeq.getSequenceIdentifier()); + + fieldSeq = (FieldSeq) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_SEQUENCE, " SEQ MySequence", "101", fieldSeq); + Assert.assertEquals("MySequence", fieldSeq.getSequenceIdentifier()); + + fieldSeq = (FieldSeq) doc.getRange().getFields().get(2); + + TestUtil.verifyField(FieldType.FIELD_SEQUENCE, " SEQ MySequence \\s 1", "1", fieldSeq); + Assert.assertEquals("MySequence", fieldSeq.getSequenceIdentifier()); + + fieldSeq = (FieldSeq) doc.getRange().getFields().get(3); + + TestUtil.verifyField(FieldType.FIELD_SEQUENCE, " SEQ MySequence \\n", "2", fieldSeq); + Assert.assertEquals("MySequence", fieldSeq.getSequenceIdentifier()); + } + + @Test + public void tocSeqBookmark() throws Exception { + //ExStart + //ExFor:FieldSeq + //ExFor:FieldSeq.BookmarkName + //ExSummary:Shows how to combine table of contents and sequence fields. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // A TOC field can create an entry in its table of contents for each SEQ field found in the document. + // Each entry contains the paragraph that contains the SEQ field, + // and the number of the page that the field appears on. + FieldToc fieldToc = (FieldToc) builder.insertField(FieldType.FIELD_TOC, true); + + // Configure this TOC field to have a SequenceIdentifier property with a value of "MySequence". + fieldToc.setTableOfFiguresLabel("MySequence"); + + // Configure this TOC field to only pick up SEQ fields that are within the bounds of a bookmark + // named "TOCBookmark". + fieldToc.setBookmarkName("TOCBookmark"); + builder.insertBreak(BreakType.PAGE_BREAK); + + Assert.assertEquals(" TOC \\c MySequence \\b TOCBookmark", fieldToc.getFieldCode()); + + // SEQ fields display a count that increments at each SEQ field. + // These fields also maintain separate counts for each unique named sequence + // identified by the SEQ field's "SequenceIdentifier" property. + // Insert a SEQ field that has a sequence identifier that matches the TOC's + // TableOfFiguresLabel property. This field will not create an entry in the TOC since it is outside + // the bookmark's bounds designated by "BookmarkName". + builder.write("MySequence #"); + FieldSeq fieldSeq = (FieldSeq) builder.insertField(FieldType.FIELD_SEQUENCE, true); + fieldSeq.setSequenceIdentifier("MySequence"); + builder.writeln(", will not show up in the TOC because it is outside of the bookmark."); + + builder.startBookmark("TOCBookmark"); + + // This SEQ field's sequence matches the TOC's "TableOfFiguresLabel" property and is within the bookmark's bounds. + // The paragraph that contains this field will show up in the TOC as an entry. + builder.write("MySequence #"); + fieldSeq = (FieldSeq) builder.insertField(FieldType.FIELD_SEQUENCE, true); + fieldSeq.setSequenceIdentifier("MySequence"); + builder.writeln(", will show up in the TOC next to the entry for the above caption."); + + // This SEQ field's sequence does not match the TOC's "TableOfFiguresLabel" property, + // and is within the bounds of the bookmark. Its paragraph will not show up in the TOC as an entry. + builder.write("MySequence #"); + fieldSeq = (FieldSeq) builder.insertField(FieldType.FIELD_SEQUENCE, true); + fieldSeq.setSequenceIdentifier("OtherSequence"); + builder.writeln(", will not show up in the TOC because it's from a different sequence identifier."); + + // This SEQ field's sequence matches the TOC's "TableOfFiguresLabel" property and is within the bounds of the bookmark. + // This field also references another bookmark. The contents of that bookmark will appear in the TOC entry for this SEQ field. + // The SEQ field itself will not display the contents of that bookmark. + fieldSeq = (FieldSeq) builder.insertField(FieldType.FIELD_SEQUENCE, true); + fieldSeq.setSequenceIdentifier("MySequence"); + fieldSeq.setBookmarkName("SEQBookmark"); + Assert.assertEquals(" SEQ MySequence SEQBookmark", fieldSeq.getFieldCode()); + + // Create a bookmark with contents that will show up in the TOC entry due to the above SEQ field referencing it. + builder.insertBreak(BreakType.PAGE_BREAK); + builder.startBookmark("SEQBookmark"); + builder.write("MySequence #"); + fieldSeq = (FieldSeq) builder.insertField(FieldType.FIELD_SEQUENCE, true); + fieldSeq.setSequenceIdentifier("MySequence"); + builder.writeln(", text from inside SEQBookmark."); + builder.endBookmark("SEQBookmark"); + + builder.endBookmark("TOCBookmark"); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.SEQ.Bookmark.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.SEQ.Bookmark.docx"); + + Assert.assertEquals(8, doc.getRange().getFields().getCount()); + + fieldToc = (FieldToc) doc.getRange().getFields().get(0); + String[] pageRefIds = Arrays.stream(fieldToc.getResult().split(" ")).filter(s -> s.startsWith("_Toc")).toArray(String[]::new); + + Assert.assertEquals(FieldType.FIELD_TOC, fieldToc.getType()); + Assert.assertEquals("MySequence", fieldToc.getTableOfFiguresLabel()); + TestUtil.verifyField(FieldType.FIELD_TOC, " TOC \\c MySequence \\b TOCBookmark", + MessageFormat.format("MySequence #2, will show up in the TOC next to the entry for the above caption.\t\u0013 PAGEREF {0} \\h \u00142\u0015\r", pageRefIds[0]) + + MessageFormat.format("3MySequence #3, text from inside SEQBookmark.\t\u0013 PAGEREF {0} \\h \u00142\u0015\r", pageRefIds[1]), fieldToc); + + FieldPageRef fieldPageRef = (FieldPageRef) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_PAGE_REF, MessageFormat.format(" PAGEREF {0} \\h ", pageRefIds[0]), "2", fieldPageRef); + Assert.assertEquals(pageRefIds[0], fieldPageRef.getBookmarkName()); + + fieldPageRef = (FieldPageRef) doc.getRange().getFields().get(2); + + TestUtil.verifyField(FieldType.FIELD_PAGE_REF, MessageFormat.format(" PAGEREF {0} \\h ", pageRefIds[1]), "2", fieldPageRef); + Assert.assertEquals(pageRefIds[1], fieldPageRef.getBookmarkName()); + + fieldSeq = (FieldSeq) doc.getRange().getFields().get(3); + + TestUtil.verifyField(FieldType.FIELD_SEQUENCE, " SEQ MySequence", "1", fieldSeq); + Assert.assertEquals("MySequence", fieldSeq.getSequenceIdentifier()); + + fieldSeq = (FieldSeq) doc.getRange().getFields().get(4); + + TestUtil.verifyField(FieldType.FIELD_SEQUENCE, " SEQ MySequence", "2", fieldSeq); + Assert.assertEquals("MySequence", fieldSeq.getSequenceIdentifier()); + + fieldSeq = (FieldSeq) doc.getRange().getFields().get(5); + + TestUtil.verifyField(FieldType.FIELD_SEQUENCE, " SEQ OtherSequence", "1", fieldSeq); + Assert.assertEquals("OtherSequence", fieldSeq.getSequenceIdentifier()); + + fieldSeq = (FieldSeq) doc.getRange().getFields().get(6); + + TestUtil.verifyField(FieldType.FIELD_SEQUENCE, " SEQ MySequence SEQBookmark", "3", fieldSeq); + Assert.assertEquals("MySequence", fieldSeq.getSequenceIdentifier()); + Assert.assertEquals("SEQBookmark", fieldSeq.getBookmarkName()); + + fieldSeq = (FieldSeq) doc.getRange().getFields().get(7); + + TestUtil.verifyField(FieldType.FIELD_SEQUENCE, " SEQ MySequence", "3", fieldSeq); + Assert.assertEquals("MySequence", fieldSeq.getSequenceIdentifier()); + } + + @Test(enabled = false, description = "WORDSNET-13854") + public void fieldCitation() throws Exception { + //ExStart + //ExFor:FieldCitation + //ExFor:FieldCitation.AnotherSourceTag + //ExFor:FieldCitation.FormatLanguageId + //ExFor:FieldCitation.PageNumber + //ExFor:FieldCitation.Prefix + //ExFor:FieldCitation.SourceTag + //ExFor:FieldCitation.Suffix + //ExFor:FieldCitation.SuppressAuthor + //ExFor:FieldCitation.SuppressTitle + //ExFor:FieldCitation.SuppressYear + //ExFor:FieldCitation.VolumeNumber + //ExFor:FieldBibliography + //ExFor:FieldBibliography.FormatLanguageId + //ExFor:FieldBibliography.FilterLanguageId + //ExFor:FieldBibliography.SourceTag + //ExSummary:Shows how to work with CITATION and BIBLIOGRAPHY fields. + // Open a document containing bibliographical sources that we can find in + // Microsoft Word via References -> Citations & Bibliography -> Manage Sources. + Document doc = new Document(getMyDir() + "Bibliography.docx"); + Assert.assertEquals(2, doc.getRange().getFields().getCount()); //ExSkip + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.write("Text to be cited with one source."); + + // Create a citation with just the page number and the author of the referenced book. + FieldCitation fieldCitation = (FieldCitation) builder.insertField(FieldType.FIELD_CITATION, true); + + // We refer to sources using their tag names. + fieldCitation.setSourceTag("Book1"); + fieldCitation.setPageNumber("85"); + fieldCitation.setSuppressAuthor(false); + fieldCitation.setSuppressTitle(true); + fieldCitation.setSuppressYear(true); + + Assert.assertEquals(" CITATION Book1 \\p 85 \\t \\y", fieldCitation.getFieldCode()); + + // Create a more detailed citation which cites two sources. + builder.insertParagraph(); + builder.write("Text to be cited with two sources."); + fieldCitation = (FieldCitation) builder.insertField(FieldType.FIELD_CITATION, true); + fieldCitation.setSourceTag("Book1"); + fieldCitation.setAnotherSourceTag("Book2"); + fieldCitation.setFormatLanguageId("en-US"); + fieldCitation.setPageNumber("19"); + fieldCitation.setPrefix("Prefix "); + fieldCitation.setSuffix(" Suffix"); + fieldCitation.setSuppressAuthor(false); + fieldCitation.setSuppressTitle(false); + fieldCitation.setSuppressYear(false); + fieldCitation.setVolumeNumber("VII"); + + Assert.assertEquals(" CITATION Book1 \\m Book2 \\l en-US \\p 19 \\f \"Prefix \" \\s \" Suffix\" \\v VII", fieldCitation.getFieldCode()); + + // We can use a BIBLIOGRAPHY field to display all the sources within the document. + builder.insertBreak(BreakType.PAGE_BREAK); + FieldBibliography fieldBibliography = (FieldBibliography)builder.insertField(FieldType.FIELD_BIBLIOGRAPHY, true); + fieldBibliography.setFormatLanguageId("5129"); + fieldBibliography.setFilterLanguageId("5129"); + fieldBibliography.setSourceTag("Book2"); + + Assert.assertEquals(" BIBLIOGRAPHY \\l 5129 \\f 5129 \\m Book2", fieldBibliography.getFieldCode()); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.CITATION.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.CITATION.docx"); + + Assert.assertEquals(5, doc.getRange().getFields().getCount()); + + fieldCitation = (FieldCitation) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_CITATION, " CITATION Book1 \\p 85 \\t \\y", " (Doe, p. 85)", fieldCitation); + Assert.assertEquals("Book1", fieldCitation.getSourceTag()); + Assert.assertEquals("85", fieldCitation.getPageNumber()); + Assert.assertFalse(fieldCitation.getSuppressAuthor()); + Assert.assertTrue(fieldCitation.getSuppressTitle()); + Assert.assertTrue(fieldCitation.getSuppressYear()); + + fieldCitation = (FieldCitation) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_CITATION, + " CITATION Book1 \\m Book2 \\l en-US \\p 19 \\f \"Prefix \" \\s \" Suffix\" \\v VII", + " (Doe, 2018; Prefix Cardholder, 2018, VII:19 Suffix)", fieldCitation); + Assert.assertEquals("Book1", fieldCitation.getSourceTag()); + Assert.assertEquals("Book2", fieldCitation.getAnotherSourceTag()); + Assert.assertEquals("en-US", fieldCitation.getFormatLanguageId()); + Assert.assertEquals("Prefix ", fieldCitation.getPrefix()); + Assert.assertEquals(" Suffix", fieldCitation.getSuffix()); + Assert.assertEquals("19", fieldCitation.getPageNumber()); + Assert.assertFalse(fieldCitation.getSuppressAuthor()); + Assert.assertFalse(fieldCitation.getSuppressTitle()); + Assert.assertFalse(fieldCitation.getSuppressYear()); + Assert.assertEquals("VII", fieldCitation.getVolumeNumber()); + + fieldBibliography = (FieldBibliography) doc.getRange().getFields().get(2); + + TestUtil.verifyField(FieldType.FIELD_BIBLIOGRAPHY, " BIBLIOGRAPHY \\l 5129 \\f 5129 \\m Book2", + "Cardholder, A. (2018). My Book, Vol. II. New York: Doe Co. Ltd.\r", fieldBibliography); + Assert.assertEquals("5129", fieldBibliography.getFormatLanguageId()); + Assert.assertEquals("5129", fieldBibliography.getFilterLanguageId()); + + fieldCitation = (FieldCitation) doc.getRange().getFields().get(3); + + TestUtil.verifyField(FieldType.FIELD_CITATION, " CITATION Book1 \\l 1033 ", "(Doe, 2018)", fieldCitation); + Assert.assertEquals("Book1", fieldCitation.getSourceTag()); + Assert.assertEquals("1033", fieldCitation.getFormatLanguageId()); + + fieldBibliography = (FieldBibliography) doc.getRange().getFields().get(4); + + TestUtil.verifyField(FieldType.FIELD_BIBLIOGRAPHY, " BIBLIOGRAPHY ", + "Cardholder, A. (2018). My Book, Vol. II. New York: Doe Co. Ltd.\rDoe, J. (2018). My Book, Vol I. London: Doe Co. Ltd.\r", fieldBibliography); + } + + //ExStart + //ExFor:Bibliography.BibliographyStyle + //ExFor:IBibliographyStylesProvider + //ExFor:IBibliographyStylesProvider.GetStyle(String) + //ExFor:FieldOptions.BibliographyStylesProvider + //ExSummary:Shows how to override built-in styles or provide custom one. + @Test //ExSkip + public void changeBibliographyStyles() throws Exception + { + Document doc = new Document(getMyDir() + "Bibliography.docx"); + + // If the document already has a style you can change it with the following code: + // doc.Bibliography.BibliographyStyle = "Bibliography custom style.xsl"; + + doc.getFieldOptions().setBibliographyStylesProvider(new BibliographyStylesProvider()); + doc.updateFields(); + + doc.save(getArtifactsDir() + "Field.ChangeBibliographyStyles.docx"); + } + + public static class BibliographyStylesProvider implements IBibliographyStylesProvider + { + public FileInputStream getStyle(String styleFileName) throws Exception + { + return new FileInputStream(getMyDir() + "Bibliography custom style.xsl"); + } + } + //ExEnd + + @Test + public void fieldData() throws Exception { + //ExStart + //ExFor:FieldData + //ExSummary:Shows how to insert a DATA field into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + FieldData field = (FieldData) builder.insertField(FieldType.FIELD_DATA, true); + Assert.assertEquals(" DATA ", field.getFieldCode()); + //ExEnd + + TestUtil.verifyField(FieldType.FIELD_DATA, " DATA ", "", DocumentHelper.saveOpen(doc).getRange().getFields().get(0)); + } + + @Test + public void fieldInclude() throws Exception { + //ExStart + //ExFor:FieldInclude + //ExFor:FieldInclude.BookmarkName + //ExFor:FieldInclude.LockFields + //ExFor:FieldInclude.SourceFullName + //ExFor:FieldInclude.TextConverter + //ExSummary:Shows how to create an INCLUDE field, and set its properties. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // We can use an INCLUDE field to import a portion of another document in the local file system. + // The bookmark from the other document that we reference with this field contains this imported portion. + FieldInclude field = (FieldInclude) builder.insertField(FieldType.FIELD_INCLUDE, true); + field.setSourceFullName(getMyDir() + "Bookmarks.docx"); + field.setBookmarkName("MyBookmark1"); + field.setLockFields(false); + field.setTextConverter("Microsoft Word"); + + Assert.assertTrue(field.getFieldCode().matches(" INCLUDE .* MyBookmark1 \\\\c \"Microsoft Word\"")); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.INCLUDE.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.INCLUDE.docx"); + field = (FieldInclude) doc.getRange().getFields().get(0); + + Assert.assertEquals(FieldType.FIELD_INCLUDE, field.getType()); + Assert.assertEquals("First bookmark.", field.getResult()); + Assert.assertTrue(field.getFieldCode().matches(" INCLUDE .* MyBookmark1 \\\\c \"Microsoft Word\"")); + + Assert.assertEquals(getMyDir() + "Bookmarks.docx", field.getSourceFullName()); + Assert.assertEquals("MyBookmark1", field.getBookmarkName()); + Assert.assertFalse(field.getLockFields()); + Assert.assertEquals("Microsoft Word", field.getTextConverter()); + } + + @Test + public void fieldIncludePicture() throws Exception { + //ExStart + //ExFor:FieldIncludePicture + //ExFor:FieldIncludePicture.GraphicFilter + //ExFor:FieldIncludePicture.IsLinked + //ExFor:FieldIncludePicture.ResizeHorizontally + //ExFor:FieldIncludePicture.ResizeVertically + //ExFor:FieldIncludePicture.SourceFullName + //ExFor:FieldImport + //ExFor:FieldImport.GraphicFilter + //ExFor:FieldImport.IsLinked + //ExFor:FieldImport.SourceFullName + //ExSummary:Shows how to insert images using IMPORT and INCLUDEPICTURE fields. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are two similar field types that we can use to display images linked from the local file system. + // 1 - The INCLUDEPICTURE field: + FieldIncludePicture fieldIncludePicture = (FieldIncludePicture) builder.insertField(FieldType.FIELD_INCLUDE_PICTURE, true); + fieldIncludePicture.setSourceFullName(getImageDir() + "Transparent background logo.png"); + + Assert.assertTrue(fieldIncludePicture.getFieldCode().matches(" INCLUDEPICTURE .*")); + + // Apply the PNG32.FLT filter. + fieldIncludePicture.setGraphicFilter("PNG32"); + fieldIncludePicture.isLinked(true); + fieldIncludePicture.setResizeHorizontally(true); + fieldIncludePicture.setResizeVertically(true); + + // 2 - The IMPORT field: + FieldImport fieldImport = (FieldImport) builder.insertField(FieldType.FIELD_IMPORT, true); + fieldImport.setSourceFullName(getImageDir() + "Transparent background logo.png"); + fieldImport.setGraphicFilter("PNG32"); + fieldImport.isLinked(true); + + Assert.assertTrue(fieldImport.getFieldCode().matches(" IMPORT .* \\\\c PNG32 \\\\d")); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.IMPORT.INCLUDEPICTURE.docx"); + //ExEnd + + Assert.assertEquals(getImageDir() + "Transparent background logo.png", fieldIncludePicture.getSourceFullName()); + Assert.assertEquals("PNG32", fieldIncludePicture.getGraphicFilter()); + Assert.assertTrue(fieldIncludePicture.isLinked()); + Assert.assertTrue(fieldIncludePicture.getResizeHorizontally()); + Assert.assertTrue(fieldIncludePicture.getResizeVertically()); + + Assert.assertEquals(getImageDir() + "Transparent background logo.png", fieldImport.getSourceFullName()); + Assert.assertEquals("PNG32", fieldImport.getGraphicFilter()); + Assert.assertTrue(fieldImport.isLinked()); + + doc = new Document(getArtifactsDir() + "Field.IMPORT.INCLUDEPICTURE.docx"); + + // The INCLUDEPICTURE fields have been converted into shapes with linked images during loading. + Assert.assertEquals(0, doc.getRange().getFields().getCount()); + Assert.assertEquals(2, doc.getChildNodes(NodeType.SHAPE, true).getCount()); + + Shape image = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertTrue(image.isImage()); + Assert.assertNull(image.getImageData().getImageBytes()); + Assert.assertEquals(getImageDir() + "Transparent background logo.png", image.getImageData().getSourceFullName()); + + image = (Shape) doc.getChild(NodeType.SHAPE, 1, true); + + Assert.assertTrue(image.isImage()); + Assert.assertNull(image.getImageData().getImageBytes()); + Assert.assertEquals(getImageDir() + "Transparent background logo.png", image.getImageData().getSourceFullName()); + } + + //ExStart + //ExFor:FieldIncludeText + //ExFor:FieldIncludeText.BookmarkName + //ExFor:FieldIncludeText.Encoding + //ExFor:FieldIncludeText.LockFields + //ExFor:FieldIncludeText.MimeType + //ExFor:FieldIncludeText.NamespaceMappings + //ExFor:FieldIncludeText.SourceFullName + //ExFor:FieldIncludeText.TextConverter + //ExFor:FieldIncludeText.XPath + //ExFor:FieldIncludeText.XslTransformation + //ExSummary:Shows how to create an INCLUDETEXT field, and set its properties. + @Test//ExSkip + public void fieldIncludeText() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are two ways to use INCLUDETEXT fields to display the contents of an XML file in the local file system. + // 1 - Perform an XSL transformation on an XML document: + FieldIncludeText fieldIncludeText = createFieldIncludeText(builder, getMyDir() + "CD collection data.xml", false, "text/xml", "XML", "ISO-8859-1"); + fieldIncludeText.setXslTransformation(getMyDir() + "CD collection XSL transformation.xsl"); + + builder.writeln(); + + // 2 - Use an XPath to take specific elements from an XML document: + fieldIncludeText = createFieldIncludeText(builder, getMyDir() + "CD collection data.xml", false, "text/xml", "XML", "ISO-8859-1"); + fieldIncludeText.setNamespaceMappings("xmlns:n='myNamespace'"); + fieldIncludeText.setXPath("/catalog/cd/title"); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.INCLUDETEXT.docx"); + } + + /// <summary> + /// Use a document builder to insert an INCLUDETEXT field with custom properties. + /// </summary> + @Test(enabled = false)//ExSkip + public FieldIncludeText createFieldIncludeText(DocumentBuilder builder, String sourceFullName, boolean lockFields, String mimeType, String textConverter, String encoding) throws Exception { + FieldIncludeText fieldIncludeText = (FieldIncludeText) builder.insertField(FieldType.FIELD_INCLUDE_TEXT, true); + fieldIncludeText.setSourceFullName(sourceFullName); + fieldIncludeText.setLockFields(lockFields); + fieldIncludeText.setMimeType(mimeType); + fieldIncludeText.setTextConverter(textConverter); + fieldIncludeText.setEncoding(encoding); + + return fieldIncludeText; + } + //ExEnd + + @Test(enabled = false, description = "WORDSNET-17545") + public void fieldHyperlink() throws Exception { + //ExStart + //ExFor:FieldHyperlink + //ExFor:FieldHyperlink.Address + //ExFor:FieldHyperlink.IsImageMap + //ExFor:FieldHyperlink.OpenInNewWindow + //ExFor:FieldHyperlink.ScreenTip + //ExFor:FieldHyperlink.SubAddress + //ExFor:FieldHyperlink.Target + //ExSummary:Shows how to use HYPERLINK fields to link to documents in the local file system. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + FieldHyperlink field = (FieldHyperlink) builder.insertField(FieldType.FIELD_HYPERLINK, true); + + // When we click this HYPERLINK field in Microsoft Word, + // it will open the linked document and then place the cursor at the specified bookmark. + field.setAddress(getMyDir() + "Bookmarks.docx"); + field.setSubAddress("MyBookmark3"); + field.setScreenTip("Open " + field.getAddress() + " on bookmark " + field.getSubAddress() + " in a new window"); + + builder.writeln(); + + // When we click this HYPERLINK field in Microsoft Word, + // it will open the linked document, and automatically scroll down to the specified iframe. + field = (FieldHyperlink) builder.insertField(FieldType.FIELD_HYPERLINK, true); + field.setAddress(getMyDir() + "Iframes.html"); + field.setScreenTip("Open " + field.getAddress()); + field.setTarget("iframe_3"); + field.setOpenInNewWindow(true); + field.isImageMap(false); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.HYPERLINK.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.HYPERLINK.docx"); + field = (FieldHyperlink) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_HYPERLINK, + " HYPERLINK \"" + getMyDir().replace("\\", "\\\\") + "Bookmarks.docx\" \\l \"MyBookmark3\" \\o \"Open " + getMyDir() + "Bookmarks.docx on bookmark MyBookmark3 in a new window\" ", + getMyDir() + "Bookmarks.docx - MyBookmark3", field); + Assert.assertEquals(getMyDir() + "Bookmarks.docx", field.getAddress()); + Assert.assertEquals("MyBookmark3", field.getSubAddress()); + Assert.assertEquals("Open " + field.getAddress().replace("\\", "") + " on bookmark " + field.getSubAddress() + " in a new window", field.getScreenTip()); + + field = (FieldHyperlink) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_HYPERLINK, " HYPERLINK \"file:///" + getMyDir().replace("\\", "\\\\").replace(" ", "%20") + "Iframes.html\" \\t \"iframe_3\" \\o \"Open " + getMyDir().replace("\\", "\\\\") + "Iframes.html\" ", + getMyDir() + "Iframes.html", field); + Assert.assertEquals("file:///" + getMyDir().replace(" ", "%20") + "Iframes.html", field.getAddress()); + Assert.assertEquals("Open " + getMyDir() + "Iframes.html", field.getScreenTip()); + Assert.assertEquals("iframe_3", field.getTarget()); + Assert.assertFalse(field.getOpenInNewWindow()); + Assert.assertFalse(field.isImageMap()); + } + + //ExStart + //ExFor:MergeFieldImageDimension + //ExFor:MergeFieldImageDimension.#ctor(Double) + //ExFor:MergeFieldImageDimension.#ctor(Double,MergeFieldImageDimensionUnit) + //ExFor:MergeFieldImageDimension.Unit + //ExFor:MergeFieldImageDimension.Value + //ExFor:MergeFieldImageDimensionUnit + //ExFor:ImageFieldMergingArgs + //ExFor:ImageFieldMergingArgs.ImageFileName + //ExFor:ImageFieldMergingArgs.ImageWidth + //ExFor:ImageFieldMergingArgs.ImageHeight + //ExFor:ImageFieldMergingArgs.Shape + //ExSummary:Shows how to set the dimensions of images as MERGEFIELDS accepts them during a mail merge. + @Test //ExSkip + public void mergeFieldImageDimension() throws Exception { + Document doc = new Document(); + + // Insert a MERGEFIELD that will accept images from a source during a mail merge. Use the field code to reference + // a column in the data source containing local system filenames of images we wish to use in the mail merge. + DocumentBuilder builder = new DocumentBuilder(doc); + FieldMergeField field = (FieldMergeField) builder.insertField("MERGEFIELD Image:ImageColumn"); + + // The data source should have such a column named "ImageColumn". + Assert.assertEquals("Image:ImageColumn", field.getFieldName()); + + // Create a suitable data source. + DataTable dataTable = new DataTable("Images"); + dataTable.getColumns().add(new DataColumn("ImageColumn")); + dataTable.getRows().add(getImageDir() + "Logo.jpg"); + dataTable.getRows().add(getImageDir() + "Transparent background logo.png"); + dataTable.getRows().add(getImageDir() + "Enhanced Windows MetaFile.emf"); + + // Configure a callback to modify the sizes of images at merge time, then execute the mail merge. + doc.getMailMerge().setFieldMergingCallback(new MergedImageResizer(200.0, 200.0, MergeFieldImageDimensionUnit.POINT)); + doc.getMailMerge().execute(dataTable); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.MERGEFIELD.ImageDimension.docx"); + testMergeFieldImageDimension(doc); //ExSkip + } + + /// <summary> + /// Sets the size of all mail merged images to one defined width and height. + /// </summary> + private static class MergedImageResizer implements IFieldMergingCallback { + public MergedImageResizer(final double imageWidth, final double imageHeight, final int unit) { + mImageWidth = imageWidth; + mImageHeight = imageHeight; + mUnit = unit; + } + + public void fieldMerging(final FieldMergingArgs args) { + throw new UnsupportedOperationException(); + } + + public void imageFieldMerging(final ImageFieldMergingArgs args) { + args.setImageFileName(args.getFieldValue().toString()); + args.setImageWidth(new MergeFieldImageDimension(mImageWidth, mUnit)); + args.setImageHeight(new MergeFieldImageDimension(mImageHeight, mUnit)); + + Assert.assertEquals(mImageWidth, args.getImageWidth().getValue()); + Assert.assertEquals(mUnit, args.getImageWidth().getUnit()); + Assert.assertEquals(mImageHeight, args.getImageHeight().getValue()); + Assert.assertEquals(mUnit, args.getImageHeight().getUnit()); + Assert.assertNull(args.getShape()); + } + + private final double mImageWidth; + private final double mImageHeight; + private final int mUnit; + } + //ExEnd + + private void testMergeFieldImageDimension(Document doc) throws Exception { + doc = DocumentHelper.saveOpen(doc); + + Assert.assertEquals(0, doc.getRange().getFields().getCount()); + Assert.assertEquals(3, doc.getChildNodes(NodeType.SHAPE, true).getCount()); + + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, shape); + Assert.assertEquals(200.0d, shape.getWidth()); + Assert.assertEquals(200.0d, shape.getHeight()); + + shape = (Shape) doc.getChild(NodeType.SHAPE, 1, true); + + TestUtil.verifyImageInShape(400, 400, ImageType.PNG, shape); + Assert.assertEquals(200.0d, shape.getWidth()); + Assert.assertEquals(200.0d, shape.getHeight()); + + shape = (Shape) doc.getChild(NodeType.SHAPE, 2, true); + + TestUtil.verifyImageInShape(534, 534, ImageType.EMF, shape); + Assert.assertEquals(200.0d, shape.getWidth()); + Assert.assertEquals(200.0d, shape.getHeight()); + } + + //ExStart + //ExFor:ImageFieldMergingArgs.Image + //ExSummary:Shows how to use a callback to customize image merging logic. + @Test //ExSkip + public void mergeFieldImages() throws Exception { + Document doc = new Document(); + + // Insert a MERGEFIELD that will accept images from a source during a mail merge. Use the field code to reference + // a column in the data source which contains local system filenames of images we wish to use in the mail merge. + DocumentBuilder builder = new DocumentBuilder(doc); + FieldMergeField field = (FieldMergeField) builder.insertField("MERGEFIELD Image:ImageColumn"); + + // In this case, the field expects the data source to have such a column named "ImageColumn". + Assert.assertEquals("Image:ImageColumn", field.getFieldName()); + + // Filenames can be lengthy, and if we can find a way to avoid storing them in the data source, + // we may considerably reduce its size. + // Create a data source that refers to images using short names. + DataTable dataTable = new DataTable("Images"); + dataTable.getColumns().add(new DataColumn("ImageColumn")); + dataTable.getRows().add("Dark logo"); + dataTable.getRows().add("Transparent logo"); + + // Assign a merging callback that contains all logic that processes those names, + // and then execute the mail merge. + doc.getMailMerge().setFieldMergingCallback(new ImageFilenameCallback()); + doc.getMailMerge().execute(dataTable); + + doc.save(getArtifactsDir() + "Field.MERGEFIELD.Images.docx"); + testMergeFieldImages(new Document(getArtifactsDir() + "Field.MERGEFIELD.Images.docx")); //ExSkip + } + + /// <summary> + /// Contains a dictionary that maps names of images to local system filenames that contain these images. + /// If a mail merge data source uses one of the dictionary's names to refer to an image, + /// this callback will pass the respective filename to the merge destination. + /// </summary> + private static class ImageFilenameCallback implements IFieldMergingCallback { + public ImageFilenameCallback() { + mImageFilenames.put("Dark logo", getImageDir() + "Logo.jpg"); + mImageFilenames.put("Transparent logo", getImageDir() + "Transparent background logo.png"); + } + + public void fieldMerging(FieldMergingArgs args) { + throw new UnsupportedOperationException(); + } + + public void imageFieldMerging(ImageFieldMergingArgs args) throws IOException { + if (mImageFilenames.containsKey(args.getFieldValue().toString())) { + args.setImage(ImageIO.read(new File(mImageFilenames.get(args.getFieldValue().toString())))); + } + + Assert.assertNotNull(args.getImage()); + } + + private final HashMap<String, String> mImageFilenames = new HashMap<>(); + } + //ExEnd + + private void testMergeFieldImages(Document doc) throws Exception { + doc = DocumentHelper.saveOpen(doc); + + Assert.assertEquals(0, doc.getRange().getFields().getCount()); + Assert.assertEquals(2, doc.getChildNodes(NodeType.SHAPE, true).getCount()); + + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(400, 400, ImageType.PNG, shape); + Assert.assertEquals(300.0d, shape.getWidth(), 1); + Assert.assertEquals(300.0d, shape.getHeight(), 1); + + shape = (Shape) doc.getChild(NodeType.SHAPE, 1, true); + + TestUtil.verifyImageInShape(400, 400, ImageType.PNG, shape); + Assert.assertEquals(300.0d, shape.getWidth(), 1); + Assert.assertEquals(300.0d, shape.getHeight(), 1); + } + + @Test + public void fieldIndexFilter() throws Exception { + //ExStart + //ExFor:FieldIndex + //ExFor:FieldIndex.BookmarkName + //ExFor:FieldIndex.EntryType + //ExFor:FieldXE + //ExFor:FieldXE.EntryType + //ExFor:FieldXE.Text + //ExSummary:Shows how to create an INDEX field, and then use XE fields to populate it with entries. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create an INDEX field which will display an entry for each XE field found in the document. + // Each entry will display the XE field's Text property value on the left side + // and the page containing the XE field on the right. + // If the XE fields have the same value in their "Text" property, + // the INDEX field will group them into one entry. + FieldIndex index = (FieldIndex) builder.insertField(FieldType.FIELD_INDEX, true); + + // Configure the INDEX field only to display XE fields that are within the bounds + // of a bookmark named "MainBookmark", and whose "EntryType" properties have a value of "A". + // For both INDEX and XE fields, the "EntryType" property only uses the first character of its string value. + index.setBookmarkName("MainBookmark"); + index.setEntryType("A"); + + Assert.assertEquals(" INDEX \\b MainBookmark \\f A", index.getFieldCode()); + + // On a new page, start the bookmark with a name that matches the value + // of the INDEX field's "BookmarkName" property. + builder.insertBreak(BreakType.PAGE_BREAK); + builder.startBookmark("MainBookmark"); + + // The INDEX field will pick up this entry because it is inside the bookmark, + // and its entry type also matches the INDEX field's entry type. + FieldXE indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("Index entry 1"); + indexEntry.setEntryType("A"); + + Assert.assertEquals(" XE \"Index entry 1\" \\f A", indexEntry.getFieldCode()); + + // Insert an XE field that will not appear in the INDEX because the entry types do not match. + builder.insertBreak(BreakType.PAGE_BREAK); + indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("Index entry 2"); + indexEntry.setEntryType("B"); + + // End the bookmark and insert an XE field afterwards. + // It is of the same type as the INDEX field, but will not appear + // since it is outside the bookmark's boundaries. + builder.endBookmark("MainBookmark"); + builder.insertBreak(BreakType.PAGE_BREAK); + indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("Index entry 3"); + indexEntry.setEntryType("A"); + + doc.updatePageLayout(); + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.INDEX.XE.Filtering.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.INDEX.XE.Filtering.docx"); + index = (FieldIndex) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_INDEX, " INDEX \\b MainBookmark \\f A", "Index entry 1, 2\r", index); + Assert.assertEquals("MainBookmark", index.getBookmarkName()); + Assert.assertEquals("A", index.getEntryType()); + + indexEntry = (FieldXE) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_INDEX_ENTRY, " XE \"Index entry 1\" \\f A", "", indexEntry); + Assert.assertEquals("Index entry 1", indexEntry.getText()); + Assert.assertEquals("A", indexEntry.getEntryType()); + + indexEntry = (FieldXE) doc.getRange().getFields().get(2); + + TestUtil.verifyField(FieldType.FIELD_INDEX_ENTRY, " XE \"Index entry 2\" \\f B", "", indexEntry); + Assert.assertEquals("Index entry 2", indexEntry.getText()); + Assert.assertEquals("B", indexEntry.getEntryType()); + + indexEntry = (FieldXE) doc.getRange().getFields().get(3); + + TestUtil.verifyField(FieldType.FIELD_INDEX_ENTRY, " XE \"Index entry 3\" \\f A", "", indexEntry); + Assert.assertEquals("Index entry 3", indexEntry.getText()); + Assert.assertEquals("A", indexEntry.getEntryType()); + } + + @Test + public void fieldIndexFormatting() throws Exception { + //ExStart + //ExFor:FieldIndex + //ExFor:FieldIndex.Heading + //ExFor:FieldIndex.NumberOfColumns + //ExFor:FieldIndex.LanguageId + //ExFor:FieldIndex.LetterRange + //ExFor:FieldXE + //ExFor:FieldXE.IsBold + //ExFor:FieldXE.IsItalic + //ExFor:FieldXE.Text + //ExSummary:Shows how to populate an INDEX field with entries using XE fields, and also modify its appearance. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create an INDEX field which will display an entry for each XE field found in the document. + // Each entry will display the XE field's Text property value on the left side, + // and the number of the page that contains the XE field on the right. + // If the XE fields have the same value in their "Text" property, + // the INDEX field will group them into one entry. + FieldIndex index = (FieldIndex) builder.insertField(FieldType.FIELD_INDEX, true); + index.setLanguageId("1033"); + + // Setting this property's value to "A" will group all the entries by their first letter, + // and place that letter in uppercase above each group. + index.setHeading("A"); + + // Set the table created by the INDEX field to span over 2 columns. + index.setNumberOfColumns("2"); + + // Set any entries with starting letters outside the "a-c" character range to be omitted. + index.setLetterRange("a-c"); + + Assert.assertEquals(" INDEX \\z 1033 \\h A \\c 2 \\p a-c", index.getFieldCode()); + + // These next two XE fields will show up under the "A" heading, + // with their respective text stylings also applied to their page numbers. + builder.insertBreak(BreakType.PAGE_BREAK); + FieldXE indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("Apple"); + indexEntry.isItalic(true); + + Assert.assertEquals(" XE Apple \\i", indexEntry.getFieldCode()); + + builder.insertBreak(BreakType.PAGE_BREAK); + indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("Apricot"); + indexEntry.isBold(true); + + Assert.assertEquals(" XE Apricot \\b", indexEntry.getFieldCode()); + + // Both the next two XE fields will be under a "B" and "C" heading in the INDEX fields table of contents. + builder.insertBreak(BreakType.PAGE_BREAK); + indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("Banana"); + + builder.insertBreak(BreakType.PAGE_BREAK); + indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("Cherry"); + + // INDEX fields sort all entries alphabetically, so this entry will show up under "A" with the other two. + builder.insertBreak(BreakType.PAGE_BREAK); + indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("Avocado"); + + // This entry will not appear because it starts with the letter "D", + // which is outside the "a-c" character range that the INDEX field's LetterRange property defines. + builder.insertBreak(BreakType.PAGE_BREAK); + indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("Durian"); + + doc.updatePageLayout(); + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.INDEX.XE.Formatting.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.INDEX.XE.Formatting.docx"); + index = (FieldIndex) doc.getRange().getFields().get(0); + + Assert.assertEquals("1033", index.getLanguageId()); + Assert.assertEquals("A", index.getHeading()); + Assert.assertEquals("2", index.getNumberOfColumns()); + Assert.assertEquals("a-c", index.getLetterRange()); + Assert.assertEquals(" INDEX \\z 1033 \\h A \\c 2 \\p a-c", index.getFieldCode()); + Assert.assertEquals("\fA\r" + + "Apple, 2\r" + + "Apricot, 3\r" + + "Avocado, 6\r" + + "B\r" + + "Banana, 4\r" + + "C\r" + + "Cherry, 5\r\f", index.getResult()); + + indexEntry = (FieldXE) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_INDEX_ENTRY, " XE Apple \\i", "", indexEntry); + Assert.assertEquals("Apple", indexEntry.getText()); + Assert.assertFalse(indexEntry.isBold()); + Assert.assertTrue(indexEntry.isItalic()); + + indexEntry = (FieldXE) doc.getRange().getFields().get(2); + + TestUtil.verifyField(FieldType.FIELD_INDEX_ENTRY, " XE Apricot \\b", "", indexEntry); + Assert.assertEquals("Apricot", indexEntry.getText()); + Assert.assertTrue(indexEntry.isBold()); + Assert.assertFalse(indexEntry.isItalic()); + + indexEntry = (FieldXE) doc.getRange().getFields().get(3); + + TestUtil.verifyField(FieldType.FIELD_INDEX_ENTRY, " XE Banana", "", indexEntry); + Assert.assertEquals("Banana", indexEntry.getText()); + Assert.assertFalse(indexEntry.isBold()); + Assert.assertFalse(indexEntry.isItalic()); + + indexEntry = (FieldXE) doc.getRange().getFields().get(4); + + TestUtil.verifyField(FieldType.FIELD_INDEX_ENTRY, " XE Cherry", "", indexEntry); + Assert.assertEquals("Cherry", indexEntry.getText()); + Assert.assertFalse(indexEntry.isBold()); + Assert.assertFalse(indexEntry.isItalic()); + + indexEntry = (FieldXE) doc.getRange().getFields().get(5); + + TestUtil.verifyField(FieldType.FIELD_INDEX_ENTRY, " XE Avocado", "", indexEntry); + Assert.assertEquals("Avocado", indexEntry.getText()); + Assert.assertFalse(indexEntry.isBold()); + Assert.assertFalse(indexEntry.isItalic()); + + indexEntry = (FieldXE) doc.getRange().getFields().get(6); + + TestUtil.verifyField(FieldType.FIELD_INDEX_ENTRY, " XE Durian", "", indexEntry); + Assert.assertEquals("Durian", indexEntry.getText()); + Assert.assertFalse(indexEntry.isBold()); + Assert.assertFalse(indexEntry.isItalic()); + } + + @Test + public void fieldIndexSequence() throws Exception { + //ExStart + //ExFor:FieldIndex.HasSequenceName + //ExFor:FieldIndex.SequenceName + //ExFor:FieldIndex.SequenceSeparator + //ExSummary:Shows how to split a document into portions by combining INDEX and SEQ fields. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create an INDEX field which will display an entry for each XE field found in the document. + // Each entry will display the XE field's Text property value on the left side, + // and the number of the page that contains the XE field on the right. + // If the XE fields have the same value in their "Text" property, + // the INDEX field will group them into one entry. + FieldIndex index = (FieldIndex) builder.insertField(FieldType.FIELD_INDEX, true); + + // In the SequenceName property, name a SEQ field sequence. Each entry of this INDEX field will now also display + // the number that the sequence count is on at the XE field location that created this entry. + index.setSequenceName("MySequence"); + + // Set text that will around the sequence and page numbers to explain their meaning to the user. + // An entry created with this configuration will display something like "MySequence at 1 on page 1" at its page number. + // PageNumberSeparator and SequenceSeparator cannot be longer than 15 characters. + index.setPageNumberSeparator("\tMySequence at "); + index.setSequenceSeparator(" on page "); + Assert.assertTrue(index.hasSequenceName()); + + Assert.assertEquals(" INDEX \\s MySequence \\e \"\tMySequence at \" \\d \" on page \"", index.getFieldCode()); + + // SEQ fields display a count that increments at each SEQ field. + // These fields also maintain separate counts for each unique named sequence + // identified by the SEQ field's "SequenceIdentifier" property. + // Insert a SEQ field which moves the "MySequence" sequence to 1. + // This field no different from normal document text. It will not appear on an INDEX field's table of contents. + builder.insertBreak(BreakType.PAGE_BREAK); + FieldSeq sequenceField = (FieldSeq) builder.insertField(FieldType.FIELD_SEQUENCE, true); + sequenceField.setSequenceIdentifier("MySequence"); + + Assert.assertEquals(" SEQ MySequence", sequenceField.getFieldCode()); + + // Insert an XE field which will create an entry in the INDEX field. + // Since "MySequence" is at 1 and this XE field is on page 2, along with the custom separators we defined above, + // this field's INDEX entry will display "Cat" on the left side, and "MySequence at 1 on page 2" on the right. + FieldXE indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("Cat"); + + Assert.assertEquals(" XE Cat", indexEntry.getFieldCode()); + + // Insert a page break, and use SEQ fields to advance "MySequence" to 3. + builder.insertBreak(BreakType.PAGE_BREAK); + sequenceField = (FieldSeq) builder.insertField(FieldType.FIELD_SEQUENCE, true); + sequenceField.setSequenceIdentifier("MySequence"); + sequenceField = (FieldSeq) builder.insertField(FieldType.FIELD_SEQUENCE, true); + sequenceField.setSequenceIdentifier("MySequence"); + + // Insert an XE field with the same Text property as the one above. + // The INDEX entry will group XE fields with matching values in the "Text" property + // into one entry as opposed to making an entry for each XE field. + // Since we are on page 2 with "MySequence" at 3, ", 3 on page 3" will be appended to the same INDEX entry as above. + // The page number portion of that INDEX entry will now display "MySequence at 1 on page 2, 3 on page 3". + indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("Cat"); + + // Insert an XE field with a new and unique Text property value. + // This will add a new entry, with MySequence at 3 on page 4. + builder.insertBreak(BreakType.PAGE_BREAK); + indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("Dog"); + + doc.updatePageLayout(); + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.INDEX.XE.Sequence.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.INDEX.XE.Sequence.docx"); + index = (FieldIndex) doc.getRange().getFields().get(0); + + Assert.assertEquals("MySequence", index.getSequenceName()); + Assert.assertEquals("\tMySequence at ", index.getPageNumberSeparator()); + Assert.assertEquals(" on page ", index.getSequenceSeparator()); + Assert.assertTrue(index.hasSequenceName()); + Assert.assertEquals(" INDEX \\s MySequence \\e \"\tMySequence at \" \\d \" on page \"", index.getFieldCode()); + Assert.assertEquals("Cat\tMySequence at 1 on page 2, 3 on page 3\r" + + "Dog\tMySequence at 3 on page 4\r", index.getResult()); + + Assert.assertEquals(3, DocumentHelper.getFieldsCount(doc.getRange().getFields(), FieldType.FIELD_SEQUENCE)); + } + + @Test + public void fieldIndexPageNumberSeparator() throws Exception { + //ExStart + //ExFor:FieldIndex.HasPageNumberSeparator + //ExFor:FieldIndex.PageNumberSeparator + //ExFor:FieldIndex.PageNumberListSeparator + //ExSummary:Shows how to edit the page number separator in an INDEX field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create an INDEX field which will display an entry for each XE field found in the document. + // Each entry will display the XE field's Text property value on the left side, + // and the number of the page that contains the XE field on the right. + // The INDEX entry will group XE fields with matching values in the "Text" property + // into one entry as opposed to making an entry for each XE field. + FieldIndex index = (FieldIndex) builder.insertField(FieldType.FIELD_INDEX, true); + + // If our INDEX field has an entry for a group of XE fields, + // this entry will display the number of each page that contains an XE field that belongs to this group. + // We can set custom separators to customize the appearance of these page numbers. + index.setPageNumberSeparator(", on page(s) "); + index.setPageNumberListSeparator(" & "); + + Assert.assertEquals(" INDEX \\e \", on page(s) \" \\l \" & \"", index.getFieldCode()); + Assert.assertTrue(index.hasPageNumberSeparator()); + + // After we insert these XE fields, the INDEX field will display "First entry, on page(s) 2 & 3 & 4". + builder.insertBreak(BreakType.PAGE_BREAK); + FieldXE indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("First entry"); + + Assert.assertEquals(" XE \"First entry\"", indexEntry.getFieldCode()); + + builder.insertBreak(BreakType.PAGE_BREAK); + indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("First entry"); + + builder.insertBreak(BreakType.PAGE_BREAK); + indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("First entry"); + + doc.updatePageLayout(); + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.INDEX.XE.PageNumberList.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.INDEX.XE.PageNumberList.docx"); + index = (FieldIndex) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_INDEX, " INDEX \\e \", on page(s) \" \\l \" & \"", "First entry, on page(s) 2 & 3 & 4\r", index); + Assert.assertEquals(", on page(s) ", index.getPageNumberSeparator()); + Assert.assertEquals(" & ", index.getPageNumberListSeparator()); + Assert.assertTrue(index.hasPageNumberSeparator()); + } + + @Test + public void fieldIndexPageRangeBookmark() throws Exception { + //ExStart + //ExFor:FieldIndex.PageRangeSeparator + //ExFor:FieldXE.PageRangeBookmarkName + //ExSummary:Shows how to specify a bookmark's spanned pages as a page range for an INDEX field entry. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create an INDEX field which will display an entry for each XE field found in the document. + // Each entry will display the XE field's Text property value on the left side, + // and the number of the page that contains the XE field on the right. + // The INDEX entry will collect all XE fields with matching values in the "Text" property + // into one entry as opposed to making an entry for each XE field. + FieldIndex index = (FieldIndex) builder.insertField(FieldType.FIELD_INDEX, true); + + // For INDEX entries that display page ranges, we can specify a separator string + // which will appear between the number of the first page, and the number of the last. + index.setPageNumberSeparator(", on page(s) "); + index.setPageRangeSeparator(" to "); + + Assert.assertEquals(" INDEX \\e \", on page(s) \" \\g \" to \"", index.getFieldCode()); + + builder.insertBreak(BreakType.PAGE_BREAK); + FieldXE indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("My entry"); + + // If an XE field names a bookmark using the PageRangeBookmarkName property, + // its INDEX entry will show the range of pages that the bookmark spans + // instead of the number of the page that contains the XE field. + indexEntry.setPageRangeBookmarkName("MyBookmark"); + + Assert.assertEquals(" XE \"My entry\" \\r MyBookmark", indexEntry.getFieldCode()); + Assert.assertEquals(indexEntry.getPageRangeBookmarkName(), "MyBookmark"); + + // Insert a bookmark that starts on page 3 and ends on page 5. + // The INDEX entry for the XE field that references this bookmark will display this page range. + // In our table, the INDEX entry will display "My entry, on page(s) 3 to 5". + builder.insertBreak(BreakType.PAGE_BREAK); + builder.startBookmark("MyBookmark"); + builder.write("Start of MyBookmark"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.write("End of MyBookmark"); + builder.endBookmark("MyBookmark"); + + doc.updatePageLayout(); + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.INDEX.XE.PageRangeBookmark.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.INDEX.XE.PageRangeBookmark.docx"); + index = (FieldIndex) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_INDEX, " INDEX \\e \", on page(s) \" \\g \" to \"", "My entry, on page(s) 3 to 5\r", index); + Assert.assertEquals(", on page(s) ", index.getPageNumberSeparator()); + Assert.assertEquals(" to ", index.getPageRangeSeparator()); + + indexEntry = (FieldXE) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_INDEX_ENTRY, " XE \"My entry\" \\r MyBookmark", "", indexEntry); + Assert.assertEquals("My entry", indexEntry.getText()); + Assert.assertEquals("MyBookmark", indexEntry.getPageRangeBookmarkName()); + } + + @Test + public void fieldIndexCrossReferenceSeparator() throws Exception { + //ExStart + //ExFor:FieldIndex.CrossReferenceSeparator + //ExFor:FieldXE.PageNumberReplacement + //ExSummary:Shows how to define cross references in an INDEX field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create an INDEX field which will display an entry for each XE field found in the document. + // Each entry will display the XE field's Text property value on the left side, + // and the number of the page that contains the XE field on the right. + // The INDEX entry will collect all XE fields with matching values in the "Text" property + // into one entry as opposed to making an entry for each XE field. + FieldIndex index = (FieldIndex) builder.insertField(FieldType.FIELD_INDEX, true); + + // We can configure an XE field to get its INDEX entry to display a string instead of a page number. + // First, for entries that substitute a page number with a string, + // specify a custom separator between the XE field's Text property value and the string. + index.setCrossReferenceSeparator(", see: "); + + Assert.assertEquals(" INDEX \\k \", see: \"", index.getFieldCode()); + + // Insert an XE field, which creates a regular INDEX entry which displays this field's page number, + // and does not invoke the CrossReferenceSeparator value. + // The entry for this XE field will display "Apple, 2". + builder.insertBreak(BreakType.PAGE_BREAK); + FieldXE indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("Apple"); + + Assert.assertEquals(" XE Apple", indexEntry.getFieldCode()); + + // Insert another XE field on page 3 and set a value for the PageNumberReplacement property. + // This value will show up instead of the number of the page that this field is on, + // and the INDEX field's CrossReferenceSeparator value will appear in front of it. + // The entry for this XE field will display "Banana, see: Tropical fruit". + builder.insertBreak(BreakType.PAGE_BREAK); + indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("Banana"); + indexEntry.setPageNumberReplacement("Tropical fruit"); + + Assert.assertEquals(" XE Banana \\t \"Tropical fruit\"", indexEntry.getFieldCode()); + + doc.updatePageLayout(); + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.INDEX.XE.CrossReferenceSeparator.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.INDEX.XE.CrossReferenceSeparator.docx"); + index = (FieldIndex) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_INDEX, " INDEX \\k \", see: \"", + "Apple, 2\r" + + "Banana, see: Tropical fruit\r", index); + Assert.assertEquals(", see: ", index.getCrossReferenceSeparator()); + + indexEntry = (FieldXE) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_INDEX_ENTRY, " XE Apple", "", indexEntry); + Assert.assertEquals("Apple", indexEntry.getText()); + Assert.assertNull(indexEntry.getPageNumberReplacement()); + + indexEntry = (FieldXE) doc.getRange().getFields().get(2); + + TestUtil.verifyField(FieldType.FIELD_INDEX_ENTRY, " XE Banana \\t \"Tropical fruit\"", "", indexEntry); + Assert.assertEquals("Banana", indexEntry.getText()); + Assert.assertEquals("Tropical fruit", indexEntry.getPageNumberReplacement()); + } + + @Test(dataProvider = "fieldIndexSubheadingDataProvider") + public void fieldIndexSubheading(boolean runSubentriesOnTheSameLine) throws Exception { + //ExStart + //ExFor:FieldIndex.RunSubentriesOnSameLine + //ExSummary:Shows how to work with subentries in an INDEX field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create an INDEX field which will display an entry for each XE field found in the document. + // Each entry will display the XE field's Text property value on the left side, + // and the number of the page that contains the XE field on the right. + // The INDEX entry will collect all XE fields with matching values in the "Text" property + // into one entry as opposed to making an entry for each XE field. + FieldIndex index = (FieldIndex) builder.insertField(FieldType.FIELD_INDEX, true); + index.setPageNumberSeparator(", see page "); + index.setHeading("A"); + + // XE fields that have a Text property whose value becomes the heading of the INDEX entry. + // If this value contains two string segments split by a colon (the INDEX entry will treat :) delimiter, + // the first segment is heading, and the second segment will become the subheading. + // The INDEX field first groups entries alphabetically, then, if there are multiple XE fields with the same + // headings, the INDEX field will further subgroup them by the values of these headings. + // There can be multiple subgrouping layers, depending on how many times + // the Text properties of XE fields get segmented like this. + // By default, an INDEX field entry group will create a new line for every subheading within this group. + // We can set the RunSubentriesOnSameLine flag to true to keep the heading, + // and every subheading for the group on one line instead, which will make the INDEX field more compact. + index.setRunSubentriesOnSameLine(runSubentriesOnTheSameLine); + + if (runSubentriesOnTheSameLine) + Assert.assertEquals(" INDEX \\e \", see page \" \\h A \\r", index.getFieldCode()); + else + Assert.assertEquals(" INDEX \\e \", see page \" \\h A", index.getFieldCode()); + + // Insert two XE fields, each on a new page, and with the same heading named "Heading 1", + // which the INDEX field will use to group them. + // If RunSubentriesOnSameLine is false, then the INDEX table will create three lines: + // one line for the grouping heading "Heading 1", and one more line for each subheading. + // If RunSubentriesOnSameLine is true, then the INDEX table will create a one-line + // entry that encompasses the heading and every subheading. + builder.insertBreak(BreakType.PAGE_BREAK); + FieldXE indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("Heading 1:Subheading 1"); + + Assert.assertEquals(" XE \"Heading 1:Subheading 1\"", indexEntry.getFieldCode()); + + builder.insertBreak(BreakType.PAGE_BREAK); + indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("Heading 1:Subheading 2"); + + doc.updatePageLayout(); + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.INDEX.XE.Subheading.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.INDEX.XE.Subheading.docx"); + index = (FieldIndex) doc.getRange().getFields().get(0); + + if (runSubentriesOnTheSameLine) { + TestUtil.verifyField(FieldType.FIELD_INDEX, " INDEX \\e \", see page \" \\h A \\r", + "H\r" + + "Heading 1: Subheading 1, see page 2; Subheading 2, see page 3\r", index); + Assert.assertTrue(index.getRunSubentriesOnSameLine()); + } else { + TestUtil.verifyField(FieldType.FIELD_INDEX, " INDEX \\e \", see page \" \\h A", + "H\r" + + "Heading 1\r" + + "Subheading 1, see page 2\r" + + "Subheading 2, see page 3\r", index); + Assert.assertFalse(index.getRunSubentriesOnSameLine()); + } + + indexEntry = (FieldXE) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_INDEX_ENTRY, " XE \"Heading 1:Subheading 1\"", "", indexEntry); + Assert.assertEquals("Heading 1:Subheading 1", indexEntry.getText()); + + indexEntry = (FieldXE) doc.getRange().getFields().get(2); + + TestUtil.verifyField(FieldType.FIELD_INDEX_ENTRY, " XE \"Heading 1:Subheading 2\"", "", indexEntry); + Assert.assertEquals("Heading 1:Subheading 2", indexEntry.getText()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "fieldIndexSubheadingDataProvider") + public static Object[][] fieldIndexSubheadingDataProvider() throws Exception { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test(enabled = false, description = "WORDSNET-24595", dataProvider = "fieldIndexYomiDataProvider") + public void fieldIndexYomi(boolean sortEntriesUsingYomi) throws Exception { + //ExStart + //ExFor:FieldIndex.UseYomi + //ExFor:FieldXE.Yomi + //ExSummary:Shows how to sort INDEX field entries phonetically. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create an INDEX field which will display an entry for each XE field found in the document. + // Each entry will display the XE field's Text property value on the left side, + // and the number of the page that contains the XE field on the right. + // The INDEX entry will collect all XE fields with matching values in the "Text" property + // into one entry as opposed to making an entry for each XE field. + FieldIndex index = (FieldIndex) builder.insertField(FieldType.FIELD_INDEX, true); + + // The INDEX table automatically sorts its entries by the values of their Text properties in alphabetic order. + // Set the INDEX table to sort entries phonetically using Hiragana instead. + index.setUseYomi(sortEntriesUsingYomi); + + if (sortEntriesUsingYomi) + Assert.assertEquals(" INDEX \\y", index.getFieldCode()); + else + Assert.assertEquals(" INDEX ", index.getFieldCode()); + + // Insert 4 XE fields, which would show up as entries in the INDEX field's table of contents. + // The "Text" property may contain a word's spelling in Kanji, whose pronunciation may be ambiguous, + // while the "Yomi" version of the word will spell exactly how it is pronounced using Hiragana. + // If we set our INDEX field to use Yomi, it will sort these entries + // by the value of their Yomi properties, instead of their Text values. + builder.insertBreak(BreakType.PAGE_BREAK); + FieldXE indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("愛子"); + indexEntry.setYomi("あ"); + + Assert.assertEquals(" XE 愛子 \\y あ", indexEntry.getFieldCode()); + + builder.insertBreak(BreakType.PAGE_BREAK); + indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("明美"); + indexEntry.setYomi("あ"); + + builder.insertBreak(BreakType.PAGE_BREAK); + indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("恵美"); + indexEntry.setYomi("え"); + + builder.insertBreak(BreakType.PAGE_BREAK); + indexEntry = (FieldXE) builder.insertField(FieldType.FIELD_INDEX_ENTRY, true); + indexEntry.setText("愛美"); + indexEntry.setYomi("え"); + + doc.updatePageLayout(); + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.INDEX.XE.Yomi.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.INDEX.XE.Yomi.docx"); + index = (FieldIndex) doc.getRange().getFields().get(0); + + if (sortEntriesUsingYomi) { + Assert.assertTrue(index.getUseYomi()); + Assert.assertEquals(" INDEX \\y", index.getFieldCode()); + Assert.assertEquals("愛子, 2\r" + + "明美, 3\r" + + "恵美, 4\r" + + "愛美, 5\r", index.getResult()); + } else { + Assert.assertFalse(index.getUseYomi()); + Assert.assertEquals(" INDEX ", index.getFieldCode()); + Assert.assertEquals("恵美, 4\r" + + "愛子, 2\r" + + "愛美, 5\r" + + "明美, 3\r", index.getResult()); + } + + indexEntry = (FieldXE) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_INDEX_ENTRY, " XE 愛子 \\y あ", "", indexEntry); + Assert.assertEquals("愛子", indexEntry.getText()); + Assert.assertEquals("あ", indexEntry.getYomi()); + + indexEntry = (FieldXE) doc.getRange().getFields().get(2); + + TestUtil.verifyField(FieldType.FIELD_INDEX_ENTRY, " XE 明美 \\y あ", "", indexEntry); + Assert.assertEquals("明美", indexEntry.getText()); + Assert.assertEquals("あ", indexEntry.getYomi()); + + indexEntry = (FieldXE) doc.getRange().getFields().get(3); + + TestUtil.verifyField(FieldType.FIELD_INDEX_ENTRY, " XE 恵美 \\y え", "", indexEntry); + Assert.assertEquals("恵美", indexEntry.getText()); + Assert.assertEquals("え", indexEntry.getYomi()); + + indexEntry = (FieldXE) doc.getRange().getFields().get(4); + + TestUtil.verifyField(FieldType.FIELD_INDEX_ENTRY, " XE 愛美 \\y え", "", indexEntry); + Assert.assertEquals("愛美", indexEntry.getText()); + Assert.assertEquals("え", indexEntry.getYomi()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "fieldIndexYomiDataProvider") + public static Object[][] fieldIndexYomiDataProvider() throws Exception { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test + public void fieldBarcode() throws Exception { + //ExStart + //ExFor:FieldBarcode + //ExFor:FieldBarcode.FacingIdentificationMark + //ExFor:FieldBarcode.IsBookmark + //ExFor:FieldBarcode.IsUSPostalAddress + //ExFor:FieldBarcode.PostalAddress + //ExSummary:Shows how to use the BARCODE field to display U.S. ZIP codes in the form of a barcode. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln(); + + // Below are two ways of using BARCODE fields to display custom values as barcodes. + // 1 - Store the value that the barcode will display in the PostalAddress property: + FieldBarcode field = (FieldBarcode) builder.insertField(FieldType.FIELD_BARCODE, true); + + // This value needs to be a valid ZIP code. + field.setPostalAddress("96801"); + field.isUSPostalAddress(true); + field.setFacingIdentificationMark("C"); + + Assert.assertEquals(" BARCODE 96801 \\u \\f C", field.getFieldCode()); + + builder.insertBreak(BreakType.LINE_BREAK); + + // 2 - Reference a bookmark that stores the value that this barcode will display: + field = (FieldBarcode) builder.insertField(FieldType.FIELD_BARCODE, true); + field.setPostalAddress("BarcodeBookmark"); + field.isBookmark(true); + + Assert.assertEquals(" BARCODE BarcodeBookmark \\b", field.getFieldCode()); + + // The bookmark that the BARCODE field references in its PostalAddress property + // need to contain nothing besides the valid ZIP code. + builder.insertBreak(BreakType.PAGE_BREAK); + builder.startBookmark("BarcodeBookmark"); + builder.writeln("968877"); + builder.endBookmark("BarcodeBookmark"); + + doc.save(getArtifactsDir() + "Field.BARCODE.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.BARCODE.docx"); + + Assert.assertEquals(0, doc.getChildNodes(NodeType.SHAPE, true).getCount()); + + field = (FieldBarcode) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_BARCODE, " BARCODE 96801 \\u \\f C", "", field); + Assert.assertEquals("C", field.getFacingIdentificationMark()); + Assert.assertEquals("96801", field.getPostalAddress()); + Assert.assertTrue(field.isUSPostalAddress()); + + field = (FieldBarcode) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_BARCODE, " BARCODE BarcodeBookmark \\b", "", field); + Assert.assertEquals("BarcodeBookmark", field.getPostalAddress()); + Assert.assertTrue(field.isBookmark()); + } + + @Test + public void fieldDisplayBarcode() throws Exception { + //ExStart + //ExFor:FieldDisplayBarcode + //ExFor:FieldDisplayBarcode.AddStartStopChar + //ExFor:FieldDisplayBarcode.BackgroundColor + //ExFor:FieldDisplayBarcode.BarcodeType + //ExFor:FieldDisplayBarcode.BarcodeValue + //ExFor:FieldDisplayBarcode.CaseCodeStyle + //ExFor:FieldDisplayBarcode.DisplayText + //ExFor:FieldDisplayBarcode.ErrorCorrectionLevel + //ExFor:FieldDisplayBarcode.FixCheckDigit + //ExFor:FieldDisplayBarcode.ForegroundColor + //ExFor:FieldDisplayBarcode.PosCodeStyle + //ExFor:FieldDisplayBarcode.ScalingFactor + //ExFor:FieldDisplayBarcode.SymbolHeight + //ExFor:FieldDisplayBarcode.SymbolRotation + //ExSummary:Shows how to insert a DISPLAYBARCODE field, and set its properties. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + FieldDisplayBarcode field = (FieldDisplayBarcode) builder.insertField(FieldType.FIELD_DISPLAY_BARCODE, true); + + // Below are four types of barcodes, decorated in various ways, that the DISPLAYBARCODE field can display. + // 1 - QR code with custom colors: + field.setBarcodeType("QR"); + field.setBarcodeValue("ABC123"); + field.setBackgroundColor("0xF8BD69"); + field.setForegroundColor("0xB5413B"); + field.setErrorCorrectionLevel("3"); + field.setScalingFactor("250"); + field.setSymbolHeight("1000"); + field.setSymbolRotation("0"); + + Assert.assertEquals(field.getFieldCode(), " DISPLAYBARCODE ABC123 QR \\b 0xF8BD69 \\f 0xB5413B \\q 3 \\s 250 \\h 1000 \\r 0"); + builder.writeln(); + + // 2 - EAN13 barcode, with the digits displayed below the bars: + field = (FieldDisplayBarcode) builder.insertField(FieldType.FIELD_DISPLAY_BARCODE, true); + field.setBarcodeType("EAN13"); + field.setBarcodeValue("501234567890"); + field.setDisplayText(true); + field.setPosCodeStyle("CASE"); + field.setFixCheckDigit(true); + + Assert.assertEquals(field.getFieldCode(), " DISPLAYBARCODE 501234567890 EAN13 \\t \\p CASE \\x"); + builder.writeln(); + + // 3 - CODE39 barcode: + field = (FieldDisplayBarcode) builder.insertField(FieldType.FIELD_DISPLAY_BARCODE, true); + field.setBarcodeType("CODE39"); + field.setBarcodeValue("12345ABCDE"); + field.setAddStartStopChar(true); + + Assert.assertEquals(field.getFieldCode(), " DISPLAYBARCODE 12345ABCDE CODE39 \\d"); + builder.writeln(); + + // 4 - ITF4 barcode, with a specified case code: + field = (FieldDisplayBarcode) builder.insertField(FieldType.FIELD_DISPLAY_BARCODE, true); + field.setBarcodeType("ITF14"); + field.setBarcodeValue("09312345678907"); + field.setCaseCodeStyle("STD"); + + Assert.assertEquals(field.getFieldCode(), " DISPLAYBARCODE 09312345678907 ITF14 \\c STD"); + + doc.save(getArtifactsDir() + "Field.DISPLAYBARCODE.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.DISPLAYBARCODE.docx"); + + Assert.assertEquals(0, doc.getChildNodes(NodeType.SHAPE, true).getCount()); + + field = (FieldDisplayBarcode) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_DISPLAY_BARCODE, " DISPLAYBARCODE ABC123 QR \\b 0xF8BD69 \\f 0xB5413B \\q 3 \\s 250 \\h 1000 \\r 0", "", field); + Assert.assertEquals("QR", field.getBarcodeType()); + Assert.assertEquals("ABC123", field.getBarcodeValue()); + Assert.assertEquals("0xF8BD69", field.getBackgroundColor()); + Assert.assertEquals("0xB5413B", field.getForegroundColor()); + Assert.assertEquals("3", field.getErrorCorrectionLevel()); + Assert.assertEquals("250", field.getScalingFactor()); + Assert.assertEquals("1000", field.getSymbolHeight()); + Assert.assertEquals("0", field.getSymbolRotation()); + + field = (FieldDisplayBarcode) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_DISPLAY_BARCODE, " DISPLAYBARCODE 501234567890 EAN13 \\t \\p CASE \\x", "", field); + Assert.assertEquals("EAN13", field.getBarcodeType()); + Assert.assertEquals("501234567890", field.getBarcodeValue()); + Assert.assertTrue(field.getDisplayText()); + Assert.assertEquals("CASE", field.getPosCodeStyle()); + Assert.assertTrue(field.getFixCheckDigit()); + + field = (FieldDisplayBarcode) doc.getRange().getFields().get(2); + + TestUtil.verifyField(FieldType.FIELD_DISPLAY_BARCODE, " DISPLAYBARCODE 12345ABCDE CODE39 \\d", "", field); + Assert.assertEquals("CODE39", field.getBarcodeType()); + Assert.assertEquals("12345ABCDE", field.getBarcodeValue()); + Assert.assertTrue(field.getAddStartStopChar()); + + field = (FieldDisplayBarcode) doc.getRange().getFields().get(3); + + TestUtil.verifyField(FieldType.FIELD_DISPLAY_BARCODE, " DISPLAYBARCODE 09312345678907 ITF14 \\c STD", "", field); + Assert.assertEquals("ITF14", field.getBarcodeType()); + Assert.assertEquals("09312345678907", field.getBarcodeValue()); + Assert.assertEquals("STD", field.getCaseCodeStyle()); + } + + @Test + public void fieldMergeBarcode_QR() throws Exception { + //ExStart + //ExFor:FieldDisplayBarcode + //ExFor:FieldMergeBarcode + //ExFor:FieldMergeBarcode.BackgroundColor + //ExFor:FieldMergeBarcode.BarcodeType + //ExFor:FieldMergeBarcode.BarcodeValue + //ExFor:FieldMergeBarcode.ErrorCorrectionLevel + //ExFor:FieldMergeBarcode.ForegroundColor + //ExFor:FieldMergeBarcode.ScalingFactor + //ExFor:FieldMergeBarcode.SymbolHeight + //ExFor:FieldMergeBarcode.SymbolRotation + //ExSummary:Shows how to perform a mail merge on QR barcodes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a MERGEBARCODE field, which will accept values from a data source during a mail merge. + // This field will convert all values in a merge data source's "MyQRCode" column into QR codes. + FieldMergeBarcode field = (FieldMergeBarcode) builder.insertField(FieldType.FIELD_MERGE_BARCODE, true); + field.setBarcodeType("QR"); + field.setBarcodeValue("MyQRCode"); + + // Apply custom colors and scaling. + field.setBackgroundColor("0xF8BD69"); + field.setForegroundColor("0xB5413B"); + field.setErrorCorrectionLevel("3"); + field.setScalingFactor("250"); + field.setSymbolHeight("1000"); + field.setSymbolRotation("0"); + + Assert.assertEquals(FieldType.FIELD_MERGE_BARCODE, field.getType()); + Assert.assertEquals(" MERGEBARCODE MyQRCode QR \\b 0xF8BD69 \\f 0xB5413B \\q 3 \\s 250 \\h 1000 \\r 0", + field.getFieldCode()); + builder.writeln(); + + // Create a DataTable with a column with the same name as our MERGEBARCODE field's BarcodeValue. + // The mail merge will create a new page for each row. Each page will contain a DISPLAYBARCODE field, + // which will display a QR code with the value from the merged row. + DataTable table = new DataTable("Barcodes"); + table.getColumns().add("MyQRCode"); + table.getRows().add("ABC123"); + table.getRows().add("DEF456"); + + doc.getMailMerge().execute(table); + + Assert.assertEquals(FieldType.FIELD_DISPLAY_BARCODE, doc.getRange().getFields().get(0).getType()); + Assert.assertEquals("DISPLAYBARCODE \"ABC123\" QR \\q 3 \\s 250 \\h 1000 \\r 0 \\b 0xF8BD69 \\f 0xB5413B", + doc.getRange().getFields().get(0).getFieldCode()); + Assert.assertEquals(FieldType.FIELD_DISPLAY_BARCODE, doc.getRange().getFields().get(1).getType()); + Assert.assertEquals("DISPLAYBARCODE \"DEF456\" QR \\q 3 \\s 250 \\h 1000 \\r 0 \\b 0xF8BD69 \\f 0xB5413B", + doc.getRange().getFields().get(1).getFieldCode()); + + doc.save(getArtifactsDir() + "Field.MERGEBARCODE.QR.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.MERGEBARCODE.QR.docx"); + + Assert.assertEquals(0, DocumentHelper.getFieldsCount(doc.getRange().getFields(), FieldType.FIELD_MERGE_BARCODE)); + + FieldDisplayBarcode barcode = (FieldDisplayBarcode) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_DISPLAY_BARCODE, + "DISPLAYBARCODE \"ABC123\" QR \\q 3 \\s 250 \\h 1000 \\r 0 \\b 0xF8BD69 \\f 0xB5413B", "", barcode); + Assert.assertEquals("ABC123", barcode.getBarcodeValue()); + Assert.assertEquals("QR", barcode.getBarcodeType()); + + barcode = (FieldDisplayBarcode) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_DISPLAY_BARCODE, + "DISPLAYBARCODE \"DEF456\" QR \\q 3 \\s 250 \\h 1000 \\r 0 \\b 0xF8BD69 \\f 0xB5413B", "", barcode); + Assert.assertEquals("DEF456", barcode.getBarcodeValue()); + Assert.assertEquals("QR", barcode.getBarcodeType()); + } + + @Test + public void fieldMergeBarcode_EAN13() throws Exception { + //ExStart + //ExFor:FieldMergeBarcode + //ExFor:FieldMergeBarcode.BarcodeType + //ExFor:FieldMergeBarcode.BarcodeValue + //ExFor:FieldMergeBarcode.DisplayText + //ExFor:FieldMergeBarcode.FixCheckDigit + //ExFor:FieldMergeBarcode.PosCodeStyle + //ExSummary:Shows how to perform a mail merge on EAN13 barcodes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a MERGEBARCODE field, which will accept values from a data source during a mail merge. + // This field will convert all values in a merge data source's "MyEAN13Barcode" column into EAN13 barcodes. + FieldMergeBarcode field = (FieldMergeBarcode) builder.insertField(FieldType.FIELD_MERGE_BARCODE, true); + field.setBarcodeType("EAN13"); + field.setBarcodeValue("MyEAN13Barcode"); + + // Display the numeric value of the barcode underneath the bars. + field.setDisplayText(true); + field.setPosCodeStyle("CASE"); + field.setFixCheckDigit(true); + + Assert.assertEquals(FieldType.FIELD_MERGE_BARCODE, field.getType()); + Assert.assertEquals(" MERGEBARCODE MyEAN13Barcode EAN13 \\t \\p CASE \\x", field.getFieldCode()); + builder.writeln(); + + // Create a DataTable with a column with the same name as our MERGEBARCODE field's BarcodeValue. + // The mail merge will create a new page for each row. Each page will contain a DISPLAYBARCODE field, + // which will display an EAN13 barcode with the value from the merged row. + DataTable table = new DataTable("Barcodes"); + table.getColumns().add("MyEAN13Barcode"); + table.getRows().add("501234567890"); + table.getRows().add("123456789012"); + + doc.getMailMerge().execute(table); + + Assert.assertEquals(FieldType.FIELD_DISPLAY_BARCODE, doc.getRange().getFields().get(0).getType()); + Assert.assertEquals("DISPLAYBARCODE \"501234567890\" EAN13 \\t \\p CASE \\x", + doc.getRange().getFields().get(0).getFieldCode()); + Assert.assertEquals(FieldType.FIELD_DISPLAY_BARCODE, doc.getRange().getFields().get(1).getType()); + Assert.assertEquals("DISPLAYBARCODE \"123456789012\" EAN13 \\t \\p CASE \\x", + doc.getRange().getFields().get(1).getFieldCode()); + + doc.save(getArtifactsDir() + "Field.MERGEBARCODE.EAN13.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.MERGEBARCODE.EAN13.docx"); + + Assert.assertEquals(0, DocumentHelper.getFieldsCount(doc.getRange().getFields(), FieldType.FIELD_MERGE_BARCODE)); + + FieldDisplayBarcode barcode = (FieldDisplayBarcode) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_DISPLAY_BARCODE, "DISPLAYBARCODE \"501234567890\" EAN13 \\t \\p CASE \\x", "", barcode); + Assert.assertEquals("501234567890", barcode.getBarcodeValue()); + Assert.assertEquals("EAN13", barcode.getBarcodeType()); + + barcode = (FieldDisplayBarcode) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_DISPLAY_BARCODE, "DISPLAYBARCODE \"123456789012\" EAN13 \\t \\p CASE \\x", "", barcode); + Assert.assertEquals("123456789012", barcode.getBarcodeValue()); + Assert.assertEquals("EAN13", barcode.getBarcodeType()); + } + + @Test + public void fieldMergeBarcode_CODE39() throws Exception { + //ExStart + //ExFor:FieldMergeBarcode + //ExFor:FieldMergeBarcode.AddStartStopChar + //ExFor:FieldMergeBarcode.BarcodeType + //ExSummary:Shows how to perform a mail merge on CODE39 barcodes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a MERGEBARCODE field, which will accept values from a data source during a mail merge. + // This field will convert all values in a merge data source's "MyCODE39Barcode" column into CODE39 barcodes. + FieldMergeBarcode field = (FieldMergeBarcode) builder.insertField(FieldType.FIELD_MERGE_BARCODE, true); + field.setBarcodeType("CODE39"); + field.setBarcodeValue("MyCODE39Barcode"); + + // Edit its appearance to display start/stop characters. + field.setAddStartStopChar(true); + + Assert.assertEquals(FieldType.FIELD_MERGE_BARCODE, field.getType()); + Assert.assertEquals(" MERGEBARCODE MyCODE39Barcode CODE39 \\d", field.getFieldCode()); + builder.writeln(); + + // Create a DataTable with a column with the same name as our MERGEBARCODE field's BarcodeValue. + // The mail merge will create a new page for each row. Each page will contain a DISPLAYBARCODE field, + // which will display a CODE39 barcode with the value from the merged row. + DataTable table = new DataTable("Barcodes"); + table.getColumns().add("MyCODE39Barcode"); + table.getRows().add("12345ABCDE"); + table.getRows().add("67890FGHIJ"); + + doc.getMailMerge().execute(table); + + Assert.assertEquals(FieldType.FIELD_DISPLAY_BARCODE, doc.getRange().getFields().get(0).getType()); + Assert.assertEquals("DISPLAYBARCODE \"12345ABCDE\" CODE39 \\d", + doc.getRange().getFields().get(0).getFieldCode()); + Assert.assertEquals(FieldType.FIELD_DISPLAY_BARCODE, doc.getRange().getFields().get(1).getType()); + Assert.assertEquals("DISPLAYBARCODE \"67890FGHIJ\" CODE39 \\d", + doc.getRange().getFields().get(1).getFieldCode()); + + doc.save(getArtifactsDir() + "Field.MERGEBARCODE.CODE39.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.MERGEBARCODE.CODE39.docx"); + + Assert.assertEquals(0, DocumentHelper.getFieldsCount(doc.getRange().getFields(), FieldType.FIELD_MERGE_BARCODE)); + + FieldDisplayBarcode barcode = (FieldDisplayBarcode) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_DISPLAY_BARCODE, "DISPLAYBARCODE \"12345ABCDE\" CODE39 \\d", "", barcode); + Assert.assertEquals("12345ABCDE", barcode.getBarcodeValue()); + Assert.assertEquals("CODE39", barcode.getBarcodeType()); + + barcode = (FieldDisplayBarcode) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_DISPLAY_BARCODE, "DISPLAYBARCODE \"67890FGHIJ\" CODE39 \\d", "", barcode); + Assert.assertEquals("67890FGHIJ", barcode.getBarcodeValue()); + Assert.assertEquals("CODE39", barcode.getBarcodeType()); + } + + @Test + public void fieldMergeBarcode_ITF14() throws Exception { + //ExStart + //ExFor:FieldMergeBarcode + //ExFor:FieldMergeBarcode.BarcodeType + //ExFor:FieldMergeBarcode.CaseCodeStyle + //ExSummary:Shows how to perform a mail merge on ITF14 barcodes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a MERGEBARCODE field, which will accept values from a data source during a mail merge. + // This field will convert all values in a merge data source's "MyITF14Barcode" column into ITF14 barcodes. + FieldMergeBarcode field = (FieldMergeBarcode) builder.insertField(FieldType.FIELD_MERGE_BARCODE, true); + field.setBarcodeType("ITF14"); + field.setBarcodeValue("MyITF14Barcode"); + field.setCaseCodeStyle("STD"); + + Assert.assertEquals(FieldType.FIELD_MERGE_BARCODE, field.getType()); + Assert.assertEquals(" MERGEBARCODE MyITF14Barcode ITF14 \\c STD", field.getFieldCode()); + + // Create a DataTable with a column with the same name as our MERGEBARCODE field's BarcodeValue. + // The mail merge will create a new page for each row. Each page will contain a DISPLAYBARCODE field, + // which will display an ITF14 barcode with the value from the merged row. + DataTable table = new DataTable("Barcodes"); + table.getColumns().add("MyITF14Barcode"); + table.getRows().add("09312345678907"); + table.getRows().add("1234567891234"); + + doc.getMailMerge().execute(table); + + Assert.assertEquals(FieldType.FIELD_DISPLAY_BARCODE, doc.getRange().getFields().get(0).getType()); + Assert.assertEquals("DISPLAYBARCODE \"09312345678907\" ITF14 \\c STD", + doc.getRange().getFields().get(0).getFieldCode()); + Assert.assertEquals(FieldType.FIELD_DISPLAY_BARCODE, doc.getRange().getFields().get(1).getType()); + Assert.assertEquals("DISPLAYBARCODE \"1234567891234\" ITF14 \\c STD", + doc.getRange().getFields().get(1).getFieldCode()); + + doc.save(getArtifactsDir() + "Field.MERGEBARCODE.ITF14.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.MERGEBARCODE.ITF14.docx"); + + Assert.assertEquals(0, DocumentHelper.getFieldsCount(doc.getRange().getFields(), FieldType.FIELD_MERGE_BARCODE)); + + FieldDisplayBarcode barcode = (FieldDisplayBarcode) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_DISPLAY_BARCODE, "DISPLAYBARCODE \"09312345678907\" ITF14 \\c STD", "", barcode); + Assert.assertEquals("09312345678907", barcode.getBarcodeValue()); + Assert.assertEquals("ITF14", barcode.getBarcodeType()); + + barcode = (FieldDisplayBarcode) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_DISPLAY_BARCODE, "DISPLAYBARCODE \"1234567891234\" ITF14 \\c STD", "", barcode); + Assert.assertEquals("1234567891234", barcode.getBarcodeValue()); + Assert.assertEquals("ITF14", barcode.getBarcodeType()); + } + + //ExStart + //ExFor:FieldLink + //ExFor:FieldLink.AutoUpdate + //ExFor:FieldLink.FormatUpdateType + //ExFor:FieldLink.InsertAsBitmap + //ExFor:FieldLink.InsertAsHtml + //ExFor:FieldLink.InsertAsPicture + //ExFor:FieldLink.InsertAsRtf + //ExFor:FieldLink.InsertAsText + //ExFor:FieldLink.InsertAsUnicode + //ExFor:FieldLink.IsLinked + //ExFor:FieldLink.ProgId + //ExFor:FieldLink.SourceFullName + //ExFor:FieldLink.SourceItem + //ExFor:FieldDde + //ExFor:FieldDde.AutoUpdate + //ExFor:FieldDde.InsertAsBitmap + //ExFor:FieldDde.InsertAsHtml + //ExFor:FieldDde.InsertAsPicture + //ExFor:FieldDde.InsertAsRtf + //ExFor:FieldDde.InsertAsText + //ExFor:FieldDde.InsertAsUnicode + //ExFor:FieldDde.IsLinked + //ExFor:FieldDde.ProgId + //ExFor:FieldDde.SourceFullName + //ExFor:FieldDde.SourceItem + //ExFor:FieldDdeAuto + //ExFor:FieldDdeAuto.InsertAsBitmap + //ExFor:FieldDdeAuto.InsertAsHtml + //ExFor:FieldDdeAuto.InsertAsPicture + //ExFor:FieldDdeAuto.InsertAsRtf + //ExFor:FieldDdeAuto.InsertAsText + //ExFor:FieldDdeAuto.InsertAsUnicode + //ExFor:FieldDdeAuto.IsLinked + //ExFor:FieldDdeAuto.ProgId + //ExFor:FieldDdeAuto.SourceFullName + //ExFor:FieldDdeAuto.SourceItem + //ExSummary:Shows how to use various field types to link to other documents in the local file system, and display their contents. + @Test(enabled = false, description = "WORDSNET-16226", dataProvider = "fieldLinkedObjectsAsTextDataProvider")//ExSkip + public void fieldLinkedObjectsAsText(/*InsertLinkedObjectAs*/int insertLinkedObjectAs) throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are three types of fields we can use to display contents from a linked document in the form of text. + // 1 - A LINK field: + builder.writeln("FieldLink:\n"); + insertFieldLink(builder, insertLinkedObjectAs, "Word.Document.8", getMyDir() + "Document.docx", null, true); + + // 2 - A DDE field: + builder.writeln("FieldDde:\n"); + insertFieldDde(builder, insertLinkedObjectAs, "Excel.Sheet", getMyDir() + "Spreadsheet.xlsx", + "Sheet1!R1C1", true, true); + + // 3 - A DDEAUTO field: + builder.writeln("FieldDdeAuto:\n"); + insertFieldDdeAuto(builder, insertLinkedObjectAs, "Excel.Sheet", getMyDir() + "Spreadsheet.xlsx", + "Sheet1!R1C1", true); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.LINK.DDE.DDEAUTO.docx"); + } + + @DataProvider(name = "fieldLinkedObjectsAsTextDataProvider")//ExSkip + public static Object[][] fieldLinkedObjectsAsTextDataProvider() { + return new Object[][] + { + {InsertLinkedObjectAs.TEXT}, + {InsertLinkedObjectAs.UNICODE}, + {InsertLinkedObjectAs.HTML}, + {InsertLinkedObjectAs.RTF}, + }; + } + + @Test(enabled = false, description = "WORDSNET-16226", dataProvider = "fieldLinkedObjectsAsImageDataProvider")//ExSkip + public void fieldLinkedObjectsAsImage(/*InsertLinkedObjectAs*/int insertLinkedObjectAs) throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are three types of fields we can use to display contents from a linked document in the form of an image. + // 1 - A LINK field: + builder.writeln("FieldLink:\n"); + insertFieldLink(builder, insertLinkedObjectAs, "Excel.Sheet", getMyDir() + "MySpreadsheet.xlsx", + "Sheet1!R2C2", true); + + // 2 - A DDE field: + builder.writeln("FieldDde:\n"); + insertFieldDde(builder, insertLinkedObjectAs, "Excel.Sheet", getMyDir() + "Spreadsheet.xlsx", + "Sheet1!R1C1", true, true); + + // 3 - A DDEAUTO field: + builder.writeln("FieldDdeAuto:\n"); + insertFieldDdeAuto(builder, insertLinkedObjectAs, "Excel.Sheet", getMyDir() + "Spreadsheet.xlsx", + "Sheet1!R1C1", true); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.LINK.DDE.DDEAUTO.AsImage.docx"); + } + + @DataProvider(name = "fieldLinkedObjectsAsImageDataProvider")//ExSkip + public static Object[][] fieldLinkedObjectsAsImageDataProvider() { + return new Object[][] + { + {InsertLinkedObjectAs.PICTURE}, + {InsertLinkedObjectAs.BITMAP}, + }; + } + + /// <summary> + /// Use a document builder to insert a LINK field and set its properties according to parameters. + /// </summary> + private void insertFieldLink(final DocumentBuilder builder, final int insertLinkedObjectAs, + final String progId, final String sourceFullName, final String sourceItem, + final boolean shouldAutoUpdate) throws Exception { + FieldLink field = (FieldLink) builder.insertField(FieldType.FIELD_LINK, true); + + switch (insertLinkedObjectAs) { + case InsertLinkedObjectAs.TEXT: + field.setInsertAsText(true); + break; + case InsertLinkedObjectAs.UNICODE: + field.setInsertAsUnicode(true); + break; + case InsertLinkedObjectAs.HTML: + field.setInsertAsHtml(true); + break; + case InsertLinkedObjectAs.RTF: + field.setInsertAsRtf(true); + break; + case InsertLinkedObjectAs.PICTURE: + field.setInsertAsPicture(true); + break; + case InsertLinkedObjectAs.BITMAP: + field.setInsertAsBitmap(true); + break; + } + + field.setAutoUpdate(shouldAutoUpdate); + field.setProgId(progId); + field.setSourceFullName(sourceFullName); + field.setSourceItem(sourceItem); + + builder.writeln("\n"); + } + + /// <summary> + /// Use a document builder to insert a DDE field, and set its properties according to parameters. + /// </summary> + private void insertFieldDde(final DocumentBuilder builder, final int insertLinkedObjectAs, final String progId, + final String sourceFullName, final String sourceItem, final boolean isLinked, + final boolean shouldAutoUpdate) throws Exception { + FieldDde field = (FieldDde) builder.insertField(FieldType.FIELD_DDE, true); + + switch (insertLinkedObjectAs) { + case InsertLinkedObjectAs.TEXT: + field.setInsertAsText(true); + break; + case InsertLinkedObjectAs.UNICODE: + field.setInsertAsUnicode(true); + break; + case InsertLinkedObjectAs.HTML: + field.setInsertAsHtml(true); + break; + case InsertLinkedObjectAs.RTF: + field.setInsertAsRtf(true); + break; + case InsertLinkedObjectAs.PICTURE: + field.setInsertAsPicture(true); + break; + case InsertLinkedObjectAs.BITMAP: + field.setInsertAsBitmap(true); + break; + } + + field.setAutoUpdate(shouldAutoUpdate); + field.setProgId(progId); + field.setSourceFullName(sourceFullName); + field.setSourceItem(sourceItem); + field.isLinked(isLinked); + + builder.writeln("\n"); + } + + /// <summary> + /// Use a document builder to insert a DDEAUTO, field and set its properties according to parameters. + /// </summary> + private void insertFieldDdeAuto(final DocumentBuilder builder, final int insertLinkedObjectAs, + final String progId, final String sourceFullName, final String sourceItem, + final boolean isLinked) throws Exception { + FieldDdeAuto field = (FieldDdeAuto) builder.insertField(FieldType.FIELD_DDE_AUTO, true); + + switch (insertLinkedObjectAs) { + case InsertLinkedObjectAs.TEXT: + field.setInsertAsText(true); + break; + case InsertLinkedObjectAs.UNICODE: + field.setInsertAsUnicode(true); + break; + case InsertLinkedObjectAs.HTML: + field.setInsertAsHtml(true); + break; + case InsertLinkedObjectAs.RTF: + field.setInsertAsRtf(true); + break; + case InsertLinkedObjectAs.PICTURE: + field.setInsertAsPicture(true); + break; + case InsertLinkedObjectAs.BITMAP: + field.setInsertAsBitmap(true); + break; + } + + field.setProgId(progId); + field.setSourceFullName(sourceFullName); + field.setSourceItem(sourceItem); + field.isLinked(isLinked); + } + + public final class InsertLinkedObjectAs { + private InsertLinkedObjectAs() { + } + + // LinkedObjectAsText + public static final int TEXT = 0; + public static final int UNICODE = 1; + public static final int HTML = 2; + public static final int RTF = 3; + // LinkedObjectAsImage + public static final int PICTURE = 4; + public static final int BITMAP = 5; + + public static final int length = 6; + } + //ExEnd + + @Test + public void fieldUserAddress() throws Exception { + //ExStart + //ExFor:FieldUserAddress + //ExFor:FieldUserAddress.UserAddress + //ExSummary:Shows how to use the USERADDRESS field. + Document doc = new Document(); + + // Create a UserInformation object and set it as the source of user information for any fields that we create. + UserInformation userInformation = new UserInformation(); + userInformation.setAddress("123 Main Street"); + doc.getFieldOptions().setCurrentUser(userInformation); + + // Create a USERADDRESS field to display the current user's address, + // taken from the UserInformation object we created above. + DocumentBuilder builder = new DocumentBuilder(doc); + FieldUserAddress fieldUserAddress = (FieldUserAddress) builder.insertField(FieldType.FIELD_USER_ADDRESS, true); + Assert.assertEquals(userInformation.getAddress(), fieldUserAddress.getResult()); //ExSkip + + Assert.assertEquals(" USERADDRESS ", fieldUserAddress.getFieldCode()); + Assert.assertEquals("123 Main Street", fieldUserAddress.getResult()); + + // We can set this property to get our field to override the value currently stored in the UserInformation object. + fieldUserAddress.setUserAddress("456 North Road"); + fieldUserAddress.update(); + + Assert.assertEquals(" USERADDRESS \"456 North Road\"", fieldUserAddress.getFieldCode()); + Assert.assertEquals("456 North Road", fieldUserAddress.getResult()); + + // This does not affect the value in the UserInformation object. + Assert.assertEquals("123 Main Street", doc.getFieldOptions().getCurrentUser().getAddress()); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.USERADDRESS.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.USERADDRESS.docx"); + + fieldUserAddress = (FieldUserAddress) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_USER_ADDRESS, " USERADDRESS \"456 North Road\"", "456 North Road", fieldUserAddress); + Assert.assertEquals("456 North Road", fieldUserAddress.getUserAddress()); + } + + @Test + public void fieldUserInitials() throws Exception { + //ExStart + //ExFor:FieldUserInitials + //ExFor:FieldUserInitials.UserInitials + //ExSummary:Shows how to use the USERINITIALS field. + Document doc = new Document(); + + // Create a UserInformation object and set it as the source of user information for any fields that we create. + UserInformation userInformation = new UserInformation(); + userInformation.setInitials("J. D."); + doc.getFieldOptions().setCurrentUser(userInformation); + + // Create a USERINITIALS field to display the current user's initials, + // taken from the UserInformation object we created above. + DocumentBuilder builder = new DocumentBuilder(doc); + FieldUserInitials fieldUserInitials = (FieldUserInitials) builder.insertField(FieldType.FIELD_USER_INITIALS, true); + Assert.assertEquals(userInformation.getInitials(), fieldUserInitials.getResult()); + + Assert.assertEquals(" USERINITIALS ", fieldUserInitials.getFieldCode()); + Assert.assertEquals("J. D.", fieldUserInitials.getResult()); + + // We can set this property to get our field to override the value currently stored in the UserInformation object. + fieldUserInitials.setUserInitials("J. C."); + fieldUserInitials.update(); + + Assert.assertEquals(" USERINITIALS \"J. C.\"", fieldUserInitials.getFieldCode()); + Assert.assertEquals("J. C.", fieldUserInitials.getResult()); + + // This does not affect the value in the UserInformation object. + Assert.assertEquals("J. D.", doc.getFieldOptions().getCurrentUser().getInitials()); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.USERINITIALS.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.USERINITIALS.docx"); + + fieldUserInitials = (FieldUserInitials) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_USER_INITIALS, " USERINITIALS \"J. C.\"", "J. C.", fieldUserInitials); + Assert.assertEquals("J. C.", fieldUserInitials.getUserInitials()); + } + + @Test + public void fieldUserName() throws Exception { + //ExStart + //ExFor:FieldUserName + //ExFor:FieldUserName.UserName + //ExSummary:Shows how to use the USERNAME field. + Document doc = new Document(); + + // Create a UserInformation object and set it as the source of user information for any fields that we create. + UserInformation userInformation = new UserInformation(); + userInformation.setName("John Doe"); + doc.getFieldOptions().setCurrentUser(userInformation); + + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a USERNAME field to display the current user's name, + // taken from the UserInformation object we created above. + FieldUserName fieldUserName = (FieldUserName) builder.insertField(FieldType.FIELD_USER_NAME, true); + Assert.assertEquals(userInformation.getName(), fieldUserName.getResult()); + + Assert.assertEquals(" USERNAME ", fieldUserName.getFieldCode()); + Assert.assertEquals("John Doe", fieldUserName.getResult()); + + // We can set this property to get our field to override the value currently stored in the UserInformation object. + fieldUserName.setUserName("Jane Doe"); + fieldUserName.update(); + + Assert.assertEquals(" USERNAME \"Jane Doe\"", fieldUserName.getFieldCode()); + Assert.assertEquals("Jane Doe", fieldUserName.getResult()); + + // This does not affect the value in the UserInformation object. + Assert.assertEquals("John Doe", doc.getFieldOptions().getCurrentUser().getName()); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.USERNAME.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.USERNAME.docx"); + + fieldUserName = (FieldUserName) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_USER_NAME, " USERNAME \"Jane Doe\"", "Jane Doe", fieldUserName); + Assert.assertEquals("Jane Doe", fieldUserName.getUserName()); + } + + @Test + public void fieldStyleRefParagraphNumbers() throws Exception { + //ExStart + //ExFor:FieldStyleRef + //ExFor:FieldStyleRef.InsertParagraphNumber + //ExFor:FieldStyleRef.InsertParagraphNumberInFullContext + //ExFor:FieldStyleRef.InsertParagraphNumberInRelativeContext + //ExFor:FieldStyleRef.InsertRelativePosition + //ExFor:FieldStyleRef.SearchFromBottom + //ExFor:FieldStyleRef.StyleName + //ExFor:FieldStyleRef.SuppressNonDelimiters + //ExSummary:Shows how to use STYLEREF fields. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a list based using a Microsoft Word list template. + List list = doc.getLists().add(com.aspose.words.ListTemplate.NUMBER_DEFAULT); + + // This generated list will display "1.a )". + // Space before the bracket is a non-delimiter character, which we can suppress. + list.getListLevels().get(0).setNumberFormat("\u0000."); + list.getListLevels().get(1).setNumberFormat("\u0001 )"); + + // Add text and apply paragraph styles that STYLEREF fields will reference. + builder.getListFormat().setList(list); + builder.getListFormat().listIndent(); + builder.getParagraphFormat().setStyle(doc.getStyles().get("List Paragraph")); + builder.writeln("Item 1"); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Quote")); + builder.writeln("Item 2"); + builder.getParagraphFormat().setStyle(doc.getStyles().get("List Paragraph")); + builder.writeln("Item 3"); + builder.getListFormat().removeNumbers(); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Normal")); + + // Place a STYLEREF field in the header and display the first "List Paragraph"-styled text in the document. + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + FieldStyleRef field = (FieldStyleRef) builder.insertField(FieldType.FIELD_STYLE_REF, true); + field.setStyleName("List Paragraph"); + + // Place a STYLEREF field in the footer, and have it display the last text. + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + field = (FieldStyleRef) builder.insertField(FieldType.FIELD_STYLE_REF, true); + field.setStyleName("List Paragraph"); + field.setSearchFromBottom(true); + + builder.moveToDocumentEnd(); + + // We can also use STYLEREF fields to reference the list numbers of lists. + builder.write("\nParagraph number: "); + field = (FieldStyleRef) builder.insertField(FieldType.FIELD_STYLE_REF, true); + field.setStyleName("Quote"); + field.setInsertParagraphNumber(true); + + builder.write("\nParagraph number, relative context: "); + field = (FieldStyleRef) builder.insertField(FieldType.FIELD_STYLE_REF, true); + field.setStyleName("Quote"); + field.setInsertParagraphNumberInRelativeContext(true); + + builder.write("\nParagraph number, full context: "); + field = (FieldStyleRef) builder.insertField(FieldType.FIELD_STYLE_REF, true); + field.setStyleName("Quote"); + field.setInsertParagraphNumberInFullContext(true); + + builder.write("\nParagraph number, full context, non-delimiter chars suppressed: "); + field = (FieldStyleRef) builder.insertField(FieldType.FIELD_STYLE_REF, true); + field.setStyleName("Quote"); + field.setInsertParagraphNumberInFullContext(true); + field.setSuppressNonDelimiters(true); + + doc.updatePageLayout(); + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.STYLEREF.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.STYLEREF.docx"); + + field = (FieldStyleRef) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_STYLE_REF, " STYLEREF \"List Paragraph\"", "Item 1", field); + Assert.assertEquals("List Paragraph", field.getStyleName()); + + field = (FieldStyleRef) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_STYLE_REF, " STYLEREF \"List Paragraph\" \\l", "Item 3", field); + Assert.assertEquals("List Paragraph", field.getStyleName()); + Assert.assertTrue(field.getSearchFromBottom()); + + field = (FieldStyleRef) doc.getRange().getFields().get(2); + + TestUtil.verifyField(FieldType.FIELD_STYLE_REF, " STYLEREF Quote \\n", "‎b )", field); + Assert.assertEquals("Quote", field.getStyleName()); + Assert.assertTrue(field.getInsertParagraphNumber()); + + field = (FieldStyleRef) doc.getRange().getFields().get(3); + + TestUtil.verifyField(FieldType.FIELD_STYLE_REF, " STYLEREF Quote \\r", "‎b )", field); + Assert.assertEquals("Quote", field.getStyleName()); + Assert.assertTrue(field.getInsertParagraphNumberInRelativeContext()); + + field = (FieldStyleRef) doc.getRange().getFields().get(4); + + TestUtil.verifyField(FieldType.FIELD_STYLE_REF, " STYLEREF Quote \\w", "‎1.b )", field); + Assert.assertEquals("Quote", field.getStyleName()); + Assert.assertTrue(field.getInsertParagraphNumberInFullContext()); + + field = (FieldStyleRef) doc.getRange().getFields().get(5); + + TestUtil.verifyField(FieldType.FIELD_STYLE_REF, " STYLEREF Quote \\w \\t", "‎1.b)", field); + Assert.assertEquals("Quote", field.getStyleName()); + Assert.assertTrue(field.getInsertParagraphNumberInFullContext()); + Assert.assertTrue(field.getSuppressNonDelimiters()); + } + + @Test + public void fieldDate() throws Exception { + //ExStart + //ExFor:FieldDate + //ExFor:FieldDate.UseLunarCalendar + //ExFor:FieldDate.UseSakaEraCalendar + //ExFor:FieldDate.UseUmAlQuraCalendar + //ExFor:FieldDate.UseLastFormat + //ExSummary:Shows how to use DATE fields to display dates according to different kinds of calendars. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // If we want the text in the document always to display the correct date, we can use a DATE field. + // Below are three types of cultural calendars that a DATE field can use to display a date. + // 1 - Islamic Lunar Calendar: + FieldDate field = (FieldDate) builder.insertField(FieldType.FIELD_DATE, true); + field.setUseLunarCalendar(true); + Assert.assertEquals(" DATE \\h", field.getFieldCode()); + builder.writeln(); + + // 2 - Umm al-Qura calendar: + field = (FieldDate) builder.insertField(FieldType.FIELD_DATE, true); + field.setUseUmAlQuraCalendar(true); + Assert.assertEquals(" DATE \\u", field.getFieldCode()); + builder.writeln(); + + // 3 - Indian National Calendar: + field = (FieldDate) builder.insertField(FieldType.FIELD_DATE, true); + field.setUseSakaEraCalendar(true); + Assert.assertEquals(" DATE \\s", field.getFieldCode()); + builder.writeln(); + + // Insert a DATE field and set its calendar type to the one last used by the host application. + // In Microsoft Word, the type will be the most recently used in the Insert -> Text -> Date and Time dialog box. + field = (FieldDate) builder.insertField(FieldType.FIELD_DATE, true); + field.setUseLastFormat(true); + Assert.assertEquals(" DATE \\l", field.getFieldCode()); + builder.writeln(); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.DATE.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.DATE.docx"); + + field = (FieldDate) doc.getRange().getFields().get(0); + + Assert.assertEquals(FieldType.FIELD_DATE, field.getType()); + Assert.assertTrue(field.getUseLunarCalendar()); + Assert.assertEquals(" DATE \\h", field.getFieldCode()); + Assert.assertTrue(doc.getRange().getFields().get(0).getResult().matches("\\d{1,2}[/]\\d{1,2}[/]\\d{4}")); + + field = (FieldDate) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_DATE, " DATE \\u", LocalDate.now().format(DateTimeFormatter.ofPattern("M/d/YYYY")), field); + Assert.assertTrue(field.getUseUmAlQuraCalendar()); + + field = (FieldDate) doc.getRange().getFields().get(2); + + TestUtil.verifyField(FieldType.FIELD_DATE, " DATE \\s", LocalDate.now().format(DateTimeFormatter.ofPattern("M/d/YYYY")), field); + Assert.assertTrue(field.getUseSakaEraCalendar()); + + field = (FieldDate) doc.getRange().getFields().get(3); + + TestUtil.verifyField(FieldType.FIELD_DATE, " DATE \\l", LocalDate.now().format(DateTimeFormatter.ofPattern("M/d/YYYY")), field); + Assert.assertTrue(field.getUseLastFormat()); + } + + @Test(enabled = false, description = "WORDSNET-17669") + public void fieldSaveDate() throws Exception { + //ExStart + //ExFor:BuiltInDocumentProperties.LastSavedTime + //ExFor:FieldSaveDate + //ExFor:FieldSaveDate.UseLunarCalendar + //ExFor:FieldSaveDate.UseSakaEraCalendar + //ExFor:FieldSaveDate.UseUmAlQuraCalendar + //ExSummary:Shows how to use the SAVEDATE field to display the date/time of the document's most recent save operation performed using Microsoft Word. + Document doc = new Document(getMyDir() + "Document.docx"); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.moveToDocumentEnd(); + builder.writeln(" Date this document was last saved:"); + + // We can use the SAVEDATE field to display the last save operation's date and time on the document. + // The save operation that these fields refer to is the manual save in an application like Microsoft Word, + // not the document's Save method. + // Below are three different calendar types according to which the SAVEDATE field can display the date/time. + // 1 - Islamic Lunar Calendar: + builder.write("According to the Lunar Calendar - "); + FieldSaveDate field = (FieldSaveDate) builder.insertField(FieldType.FIELD_SAVE_DATE, true); + field.setUseLunarCalendar(true); + + Assert.assertEquals(" SAVEDATE \\h", field.getFieldCode()); + + // 2 - Umm al-Qura calendar: + builder.write("\nAccording to the Umm al-Qura calendar - "); + field = (FieldSaveDate) builder.insertField(FieldType.FIELD_SAVE_DATE, true); + field.setUseUmAlQuraCalendar(true); + + Assert.assertEquals(" SAVEDATE \\u", field.getFieldCode()); + + // 3 - Indian National calendar: + builder.write("\nAccording to the Indian National calendar - "); + field = (FieldSaveDate) builder.insertField(FieldType.FIELD_SAVE_DATE, true); + field.setUseSakaEraCalendar(true); + + Assert.assertEquals(" SAVEDATE \\s", field.getFieldCode()); + + // The SAVEDATE fields draw their date/time values from the LastSavedTime built-in property. + // The document's Save method will not update this value, but we can still update it manually. + doc.getBuiltInDocumentProperties().setLastSavedTime(new Date()); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.SAVEDATE.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.SAVEDATE.docx"); + + System.out.println(doc.getBuiltInDocumentProperties().getLastSavedTime()); + + field = (FieldSaveDate) doc.getRange().getFields().get(0); + + Assert.assertEquals(FieldType.FIELD_SAVE_DATE, field.getType()); + Assert.assertTrue(field.getUseLunarCalendar()); + Assert.assertEquals(" SAVEDATE \\h", field.getFieldCode()); + + Assert.assertTrue(field.getResult().matches("\\d{1,2}[/]\\d{1,2}[/]\\d{4} \\d{1,2}:\\d{1,2}:\\d{1,2} [A,P]M")); + + field = (FieldSaveDate) doc.getRange().getFields().get(1); + + Assert.assertEquals(FieldType.FIELD_SAVE_DATE, field.getType()); + Assert.assertTrue(field.getUseUmAlQuraCalendar()); + Assert.assertEquals(" SAVEDATE \\u", field.getFieldCode()); + Assert.assertTrue(field.getResult().matches("\\d{1,2}[/]\\d{1,2}[/]\\d{4} \\d{1,2}:\\d{1,2}:\\d{1,2} [A,P]M")); + } + + @Test + public void fieldBuilder() throws Exception { + //ExStart + //ExFor:FieldBuilder + //ExFor:FieldBuilder.AddArgument(Int32) + //ExFor:FieldBuilder.AddArgument(FieldArgumentBuilder) + //ExFor:FieldBuilder.AddArgument(String) + //ExFor:FieldBuilder.AddArgument(Double) + //ExFor:FieldBuilder.AddArgument(FieldBuilder) + //ExFor:FieldBuilder.AddSwitch(String) + //ExFor:FieldBuilder.AddSwitch(String, Double) + //ExFor:FieldBuilder.AddSwitch(String, Int32) + //ExFor:FieldBuilder.AddSwitch(String, String) + //ExFor:FieldBuilder.BuildAndInsert(Paragraph) + //ExFor:FieldArgumentBuilder + //ExFor:FieldArgumentBuilder.#ctor + //ExFor:FieldArgumentBuilder.AddField(FieldBuilder) + //ExFor:FieldArgumentBuilder.AddText(String) + //ExFor:FieldArgumentBuilder.AddNode(Inline) + //ExSummary:Shows how to construct fields using a field builder, and then insert them into the document. + Document doc = new Document(); + + // Below are three examples of field construction done using a field builder. + // 1 - Single field: + // Use a field builder to add a SYMBOL field which displays the ƒ (Florin) symbol. + FieldBuilder builder = new FieldBuilder(FieldType.FIELD_SYMBOL); + builder.addArgument(402); + builder.addSwitch("\\f", "Arial"); + builder.addSwitch("\\s", 25); + builder.addSwitch("\\u"); + Field field = builder.buildAndInsert(doc.getFirstSection().getBody().getFirstParagraph()); + + Assert.assertEquals(field.getFieldCode(), " SYMBOL 402 \\f Arial \\s 25 \\u "); + + // 2 - Nested field: + // Use a field builder to create a formula field used as an inner field by another field builder. + FieldBuilder innerFormulaBuilder = new FieldBuilder(FieldType.FIELD_FORMULA); + innerFormulaBuilder.addArgument(100); + innerFormulaBuilder.addArgument("+"); + innerFormulaBuilder.addArgument(74); + + // Create another builder for another SYMBOL field, and insert the formula field + // that we have created above into the SYMBOL field as its argument. + builder = new FieldBuilder(FieldType.FIELD_SYMBOL); + builder.addArgument(innerFormulaBuilder); + field = builder.buildAndInsert(doc.getFirstSection().getBody().appendParagraph("")); + + // The outer SYMBOL field will use the formula field result, 174, as its argument, + // which will make the field display the ® (Registered Sign) symbol since its character number is 174. + Assert.assertEquals(" SYMBOL \u0013 = 100 + 74 \u0014\u0015 ", field.getFieldCode()); + + // 3 - Multiple nested fields and arguments: + // Now, we will use a builder to create an IF field, which displays one of two custom string values, + // depending on the true/false value of its expression. To get a true/false value + // that determines which string the IF field displays, the IF field will test two numeric expressions for equality. + // We will provide the two expressions in the form of formula fields, which we will nest inside the IF field. + FieldBuilder leftExpression = new FieldBuilder(FieldType.FIELD_FORMULA); + leftExpression.addArgument(2); + leftExpression.addArgument("+"); + leftExpression.addArgument(3); + + FieldBuilder rightExpression = new FieldBuilder(FieldType.FIELD_FORMULA); + rightExpression.addArgument(2.5); + rightExpression.addArgument("*"); + rightExpression.addArgument(5.2); + + // Next, we will build two field arguments, which will serve as the true/false output strings for the IF field. + // These arguments will reuse the output values of our numeric expressions. + FieldArgumentBuilder trueOutput = new FieldArgumentBuilder(); + trueOutput.addText("True, both expressions amount to "); + trueOutput.addField(leftExpression); + + FieldArgumentBuilder falseOutput = new FieldArgumentBuilder(); + falseOutput.addNode(new Run(doc, "False, ")); + falseOutput.addField(leftExpression); + falseOutput.addNode(new Run(doc, " does not equal ")); + falseOutput.addField(rightExpression); + + // Finally, we will create one more field builder for the IF field and combine all of the expressions. + builder = new FieldBuilder(FieldType.FIELD_IF); + builder.addArgument(leftExpression); + builder.addArgument("="); + builder.addArgument(rightExpression); + builder.addArgument(trueOutput); + builder.addArgument(falseOutput); + field = builder.buildAndInsert(doc.getFirstSection().getBody().appendParagraph("")); + + Assert.assertEquals(" IF \u0013 = 2 + 3 \u0014\u0015 = \u0013 = 2.5 * 5.2 \u0014\u0015 " + + "\"True, both expressions amount to \u0013 = 2 + 3 \u0014\u0015\" " + + "\"False, \u0013 = 2 + 3 \u0014\u0015 does not equal \u0013 = 2.5 * 5.2 \u0014\u0015\" ", field.getFieldCode()); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.SYMBOL.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.SYMBOL.docx"); + + FieldSymbol fieldSymbol = (FieldSymbol) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_SYMBOL, " SYMBOL 402 \\f Arial \\s 25 \\u ", "", fieldSymbol); + Assert.assertEquals("ƒ", fieldSymbol.getDisplayResult()); + + fieldSymbol = (FieldSymbol) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_SYMBOL, " SYMBOL \u0013 = 100 + 74 \u0014174\u0015 ", "", fieldSymbol); + Assert.assertEquals("®", fieldSymbol.getDisplayResult()); + + TestUtil.verifyField(FieldType.FIELD_FORMULA, " = 100 + 74 ", "174", doc.getRange().getFields().get(2)); + + TestUtil.verifyField(FieldType.FIELD_IF, + " IF \u0013 = 2 + 3 \u00145\u0015 = \u0013 = 2.5 * 5.2 \u001413\u0015 " + + "\"True, both expressions amount to \u0013 = 2 + 3 \u0014\u0015\" " + + "\"False, \u0013 = 2 + 3 \u00145\u0015 does not equal \u0013 = 2.5 * 5.2 \u001413\u0015\" ", + "False, 5 does not equal 13", doc.getRange().getFields().get(3)); + + Document finalDoc = doc; + Assert.assertThrows(AssertionError.class, () -> TestUtil.fieldsAreNested(finalDoc.getRange().getFields().get(2), finalDoc.getRange().getFields().get(3))); + + TestUtil.verifyField(FieldType.FIELD_FORMULA, " = 2 + 3 ", "5", doc.getRange().getFields().get(4)); + TestUtil.fieldsAreNested(doc.getRange().getFields().get(4), doc.getRange().getFields().get(3)); + + TestUtil.verifyField(FieldType.FIELD_FORMULA, " = 2.5 * 5.2 ", "13", doc.getRange().getFields().get(5)); + TestUtil.fieldsAreNested(doc.getRange().getFields().get(5), doc.getRange().getFields().get(3)); + + TestUtil.verifyField(FieldType.FIELD_FORMULA, " = 2 + 3 ", "", doc.getRange().getFields().get(6)); + TestUtil.fieldsAreNested(doc.getRange().getFields().get(6), doc.getRange().getFields().get(3)); + + TestUtil.verifyField(FieldType.FIELD_FORMULA, " = 2 + 3 ", "5", doc.getRange().getFields().get(7)); + TestUtil.fieldsAreNested(doc.getRange().getFields().get(7), doc.getRange().getFields().get(3)); + + TestUtil.verifyField(FieldType.FIELD_FORMULA, " = 2.5 * 5.2 ", "13", doc.getRange().getFields().get(8)); + TestUtil.fieldsAreNested(doc.getRange().getFields().get(8), doc.getRange().getFields().get(3)); + } + + @Test + public void fieldAuthor() throws Exception { + //ExStart + //ExFor:FieldAuthor + //ExFor:FieldAuthor.AuthorName + //ExFor:FieldOptions.DefaultDocumentAuthor + //ExSummary:Shows how to use an AUTHOR field to display a document creator's name. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // AUTHOR fields source their results from the built-in document property called "Author". + // If we create and save a document in Microsoft Word, + // it will have our username in that property. + // However, if we create a document programmatically using Aspose.Words, + // the "Author" property, by default, will be an empty string. + Assert.assertEquals("", doc.getBuiltInDocumentProperties().getAuthor()); + + // Set a backup author name for AUTHOR fields to use + // if the "Author" property contains an empty string. + doc.getFieldOptions().setDefaultDocumentAuthor("Joe Bloggs"); + + builder.write("This document was created by "); + FieldAuthor field = (FieldAuthor) builder.insertField(FieldType.FIELD_AUTHOR, true); + field.update(); + + Assert.assertEquals(" AUTHOR ", field.getFieldCode()); + Assert.assertEquals("Joe Bloggs", field.getResult()); + + // Updating an AUTHOR field that contains a value + // will apply that value to the "Author" built-in property. + Assert.assertEquals("Joe Bloggs", doc.getBuiltInDocumentProperties().getAuthor()); + + // Changing this property, then updating the AUTHOR field will apply this value to the field. + doc.getBuiltInDocumentProperties().setAuthor("John Doe"); + field.update(); + + Assert.assertEquals(" AUTHOR ", field.getFieldCode()); + Assert.assertEquals("John Doe", field.getResult()); + + // If we update an AUTHOR field after changing its "Name" property, + // then the field will display the new name and apply the new name to the built-in property. + field.setAuthorName("Jane Doe"); + field.update(); + + Assert.assertEquals(field.getFieldCode(), " AUTHOR \"Jane Doe\""); + Assert.assertEquals(field.getResult(), "Jane Doe"); + + // AUTHOR fields do not affect the DefaultDocumentAuthor property. + Assert.assertEquals("Jane Doe", doc.getBuiltInDocumentProperties().getAuthor()); + Assert.assertEquals("Joe Bloggs", doc.getFieldOptions().getDefaultDocumentAuthor()); + + doc.save(getArtifactsDir() + "Field.AUTHOR.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.AUTHOR.docx"); + + Assert.assertNull(doc.getFieldOptions().getDefaultDocumentAuthor()); + Assert.assertEquals("Jane Doe", doc.getBuiltInDocumentProperties().getAuthor()); + + field = (FieldAuthor) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_AUTHOR, " AUTHOR \"Jane Doe\"", "Jane Doe", field); + Assert.assertEquals("Jane Doe", field.getAuthorName()); + } + + @Test + public void fieldDocVariable() throws Exception { + //ExStart + //ExFor:FieldDocProperty + //ExFor:FieldDocVariable + //ExFor:FieldDocVariable.VariableName + //ExSummary:Shows how to use DOCPROPERTY fields to display document properties and variables. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are two ways of using DOCPROPERTY fields. + // 1 - Display a built-in property: + // Set a custom value for the "Category" built-in property, then insert a DOCPROPERTY field that references it. + doc.getBuiltInDocumentProperties().setCategory("My category"); + + FieldDocProperty fieldDocProperty = (FieldDocProperty) builder.insertField(" DOCPROPERTY Category "); + fieldDocProperty.update(); + + Assert.assertEquals(fieldDocProperty.getFieldCode(), " DOCPROPERTY Category "); + Assert.assertEquals(fieldDocProperty.getResult(), "My category"); + + builder.insertParagraph(); + + // 2 - Display a custom document variable: + // Define a custom variable, then reference that variable with a DOCPROPERTY field. + Assert.assertTrue(doc.getVariables().getCount() == 0); + doc.getVariables().add("My variable", "My variable's value"); + + FieldDocVariable fieldDocVariable = (FieldDocVariable) builder.insertField(FieldType.FIELD_DOC_VARIABLE, true); + fieldDocVariable.setVariableName("My Variable"); + fieldDocVariable.update(); + + Assert.assertEquals(" DOCVARIABLE \"My Variable\"", fieldDocVariable.getFieldCode()); + Assert.assertEquals("My variable's value", fieldDocVariable.getResult()); + + doc.save(getArtifactsDir() + "Field.DOCPROPERTY.DOCVARIABLE.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.DOCPROPERTY.DOCVARIABLE.docx"); + + Assert.assertEquals("My category", doc.getBuiltInDocumentProperties().getCategory()); + + fieldDocProperty = (FieldDocProperty) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_DOC_PROPERTY, " DOCPROPERTY Category ", "My category", fieldDocProperty); + + fieldDocVariable = (FieldDocVariable) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_DOC_VARIABLE, " DOCVARIABLE \"My Variable\"", "My variable's value", fieldDocVariable); + Assert.assertEquals("My Variable", fieldDocVariable.getVariableName()); + } + + @Test + public void fieldSubject() throws Exception { + //ExStart + //ExFor:FieldSubject + //ExFor:FieldSubject.Text + //ExSummary:Shows how to use the SUBJECT field. + Document doc = new Document(); + + // Set a value for the document's "Subject" built-in property. + doc.getBuiltInDocumentProperties().setSubject("My subject"); + + // Create a SUBJECT field to display the value of that built-in property. + DocumentBuilder builder = new DocumentBuilder(doc); + FieldSubject field = (FieldSubject) builder.insertField(FieldType.FIELD_SUBJECT, true); + field.update(); + + Assert.assertEquals(field.getFieldCode(), " SUBJECT "); + Assert.assertEquals(field.getResult(), "My subject"); + + // If we give the SUBJECT field's Text property value and update it, the field will + // overwrite the current value of the "Subject" built-in property with the value of its Text property, + // and then display the new value. + field.setText("My new subject"); + field.update(); + + Assert.assertEquals(field.getFieldCode(), " SUBJECT \"My new subject\""); + Assert.assertEquals(field.getResult(), "My new subject"); + + Assert.assertEquals("My new subject", doc.getBuiltInDocumentProperties().getSubject()); + + doc.save(getArtifactsDir() + "Field.SUBJECT.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.SUBJECT.docx"); + + Assert.assertEquals("My new subject", doc.getBuiltInDocumentProperties().getSubject()); + + field = (FieldSubject) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_SUBJECT, " SUBJECT \"My new subject\"", "My new subject", field); + Assert.assertEquals("My new subject", field.getText()); + } + + @Test + public void fieldComments() throws Exception { + //ExStart + //ExFor:FieldComments + //ExFor:FieldComments.Text + //ExSummary:Shows how to use the COMMENTS field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Set a value for the document's "Comments" built-in property. + doc.getBuiltInDocumentProperties().setComments("My comment."); + + // Create a COMMENTS field to display the value of that built-in property. + FieldComments field = (FieldComments) builder.insertField(FieldType.FIELD_COMMENTS, true); + field.update(); + + Assert.assertEquals(" COMMENTS ", field.getFieldCode()); + Assert.assertEquals("My comment.", field.getResult()); + + // If we give the COMMENTS field's Text property value and update it, the field will + // overwrite the current value of the "Comments" built-in property with the value of its Text property, + // and then display the new value. + field.setText("My overriding comment."); + field.update(); + + Assert.assertEquals(" COMMENTS \"My overriding comment.\"", field.getFieldCode()); + Assert.assertEquals("My overriding comment.", field.getResult()); + + doc.save(getArtifactsDir() + "Field.COMMENTS.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.COMMENTS.docx"); + + Assert.assertEquals("My overriding comment.", doc.getBuiltInDocumentProperties().getComments()); + + field = (FieldComments) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_COMMENTS, " COMMENTS \"My overriding comment.\"", "My overriding comment.", field); + Assert.assertEquals("My overriding comment.", field.getText()); + } + + @Test + public void fieldFileSize() throws Exception { + //ExStart + //ExFor:FieldFileSize + //ExFor:FieldFileSize.IsInKilobytes + //ExFor:FieldFileSize.IsInMegabytes + //ExSummary:Shows how to display the file size of a document with a FILESIZE field. + Document doc = new Document(getMyDir() + "Document.docx"); + + Assert.assertEquals(doc.getBuiltInDocumentProperties().getBytes(), 18105); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.moveToDocumentEnd(); + builder.insertParagraph(); + + // Below are three different units of measure + // with which FILESIZE fields can display the document's file size. + // 1 - Bytes: + FieldFileSize field = (FieldFileSize) builder.insertField(FieldType.FIELD_FILE_SIZE, true); + field.update(); + + Assert.assertEquals(" FILESIZE ", field.getFieldCode()); + Assert.assertEquals("18105", field.getResult()); + + // 2 - Kilobytes: + builder.insertParagraph(); + field = (FieldFileSize) builder.insertField(FieldType.FIELD_FILE_SIZE, true); + field.isInKilobytes(true); + field.update(); + + Assert.assertEquals(" FILESIZE \\k", field.getFieldCode()); + Assert.assertEquals("18", field.getResult()); + + // 3 - Megabytes: + builder.insertParagraph(); + field = (FieldFileSize) builder.insertField(FieldType.FIELD_FILE_SIZE, true); + field.isInMegabytes(true); + field.update(); + + Assert.assertEquals(" FILESIZE \\m", field.getFieldCode()); + Assert.assertEquals("0", field.getResult()); + + // To update the values of these fields while editing in Microsoft Word, + // we must first save the changes, and then manually update these fields. + doc.save(getArtifactsDir() + "Field.FILESIZE.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.FILESIZE.docx"); + + field = (FieldFileSize) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_FILE_SIZE, " FILESIZE ", "18105", field); + + // These fields will need to be updated to produce an accurate result. + doc.updateFields(); + + field = (FieldFileSize) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_FILE_SIZE, " FILESIZE \\k", "13", field); + Assert.assertTrue(field.isInKilobytes()); + + field = (FieldFileSize) doc.getRange().getFields().get(2); + + TestUtil.verifyField(FieldType.FIELD_FILE_SIZE, " FILESIZE \\m", "0", field); + Assert.assertTrue(field.isInMegabytes()); + } + + @Test + public void fieldGoToButton() throws Exception { + //ExStart + //ExFor:FieldGoToButton + //ExFor:FieldGoToButton.DisplayText + //ExFor:FieldGoToButton.Location + //ExSummary:Shows to insert a GOTOBUTTON field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Add a GOTOBUTTON field. When we double-click this field in Microsoft Word, + // it will take the text cursor to the bookmark whose name the Location property references. + FieldGoToButton field = (FieldGoToButton) builder.insertField(FieldType.FIELD_GO_TO_BUTTON, true); + field.setDisplayText("My Button"); + field.setLocation("MyBookmark"); + + Assert.assertEquals(field.getFieldCode(), " GOTOBUTTON MyBookmark My Button"); + + // Insert a valid bookmark for the field to reference. + builder.insertBreak(BreakType.PAGE_BREAK); + builder.startBookmark(field.getLocation()); + builder.writeln("Bookmark text contents."); + builder.endBookmark(field.getLocation()); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.GOTOBUTTON.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.GOTOBUTTON.docx"); + field = (FieldGoToButton) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_GO_TO_BUTTON, " GOTOBUTTON MyBookmark My Button", "", field); + Assert.assertEquals("My Button", field.getDisplayText()); + Assert.assertEquals("MyBookmark", field.getLocation()); + } + + @Test + //ExStart + //ExFor:FieldFillIn + //ExFor:FieldFillIn.DefaultResponse + //ExFor:FieldFillIn.PromptOnceOnMailMerge + //ExFor:FieldFillIn.PromptText + //ExSummary:Shows how to use the FILLIN field to prompt the user for a response. + public void fieldFillIn() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a FILLIN field. When we manually update this field in Microsoft Word, + // it will prompt us to enter a response. The field will then display the response as text. + FieldFillIn field = (FieldFillIn) builder.insertField(FieldType.FIELD_FILL_IN, true); + field.setPromptText("Please enter a response:"); + field.setDefaultResponse("A default response."); + + // We can also use these fields to ask the user for a unique response for each page + // created during a mail merge done using Microsoft Word. + field.setPromptOnceOnMailMerge(true); + + Assert.assertEquals(" FILLIN \"Please enter a response:\" \\d \"A default response.\" \\o", field.getFieldCode()); + + FieldMergeField mergeField = (FieldMergeField) builder.insertField(FieldType.FIELD_MERGE_FIELD, true); + mergeField.setFieldName("MergeField"); + + // If we perform a mail merge programmatically, we can use a custom prompt respondent + // to automatically edit responses for FILLIN fields that the mail merge encounters. + doc.getFieldOptions().setUserPromptRespondent(new PromptRespondent()); + doc.getMailMerge().execute(new String[]{"MergeField"}, new Object[]{""}); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.FILLIN.docx"); + testFieldFillIn(new Document(getArtifactsDir() + "Field.FILLIN.docx")); //ExSKip + } + + /// <summary> + /// Prepends a line to the default response of every FILLIN field during a mail merge. + /// </summary> + private static class PromptRespondent implements IFieldUserPromptRespondent { + public String respond(final String promptText, final String defaultResponse) { + return "Response modified by PromptRespondent. " + defaultResponse; + } + } + //ExEnd + + private void testFieldFillIn(Document doc) throws Exception { + doc = DocumentHelper.saveOpen(doc); + + Assert.assertEquals(1, doc.getRange().getFields().getCount()); + + FieldFillIn field = (FieldFillIn) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_FILL_IN, " FILLIN \"Please enter a response:\" \\d \"A default response.\" \\o", + "Response modified by PromptRespondent. A default response.", field); + Assert.assertEquals("Please enter a response:", field.getPromptText()); + Assert.assertEquals("A default response.", field.getDefaultResponse()); + Assert.assertTrue(field.getPromptOnceOnMailMerge()); + } + + @Test + public void fieldInfo() throws Exception { + //ExStart + //ExFor:FieldInfo + //ExFor:FieldInfo.InfoType + //ExFor:FieldInfo.NewValue + //ExSummary:Shows how to work with INFO fields. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Set a value for the "Comments" built-in property and then insert an INFO field to display that property's value. + doc.getBuiltInDocumentProperties().setComments("My comment"); + FieldInfo field = (FieldInfo) builder.insertField(FieldType.FIELD_INFO, true); + field.setInfoType("Comments"); + field.update(); + + Assert.assertEquals(field.getFieldCode(), " INFO Comments"); + Assert.assertEquals(field.getResult(), "My comment"); + + builder.writeln(); + + // Setting a value for the field's NewValue property and updating + // the field will also overwrite the corresponding built-in property with the new value. + field = (FieldInfo) builder.insertField(FieldType.FIELD_INFO, true); + field.setInfoType("Comments"); + field.setNewValue("New comment"); + field.update(); + + Assert.assertEquals(" INFO Comments \"New comment\"", field.getFieldCode()); + Assert.assertEquals("New comment", field.getResult()); + Assert.assertEquals("New comment", doc.getBuiltInDocumentProperties().getComments()); + + doc.save(getArtifactsDir() + "Field.INFO.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.INFO.docx"); + + Assert.assertEquals("New comment", doc.getBuiltInDocumentProperties().getComments()); + + field = (FieldInfo) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_INFO, " INFO Comments", "My comment", field); + Assert.assertEquals("Comments", field.getInfoType()); + + field = (FieldInfo) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_INFO, " INFO Comments \"New comment\"", "New comment", field); + Assert.assertEquals("Comments", field.getInfoType()); + Assert.assertEquals("New comment", field.getNewValue()); + } + + @Test + public void fieldMacroButton() throws Exception { + //ExStart + //ExFor:Document.HasMacros + //ExFor:FieldMacroButton + //ExFor:FieldMacroButton.DisplayText + //ExFor:FieldMacroButton.MacroName + //ExSummary:Shows how to use MACROBUTTON fields to allow us to run a document's macros by clicking. + Document doc = new Document(getMyDir() + "Macro.docm"); + DocumentBuilder builder = new DocumentBuilder(doc); + + Assert.assertTrue(doc.hasMacros()); + + // Insert a MACROBUTTON field, and reference one of the document's macros by name in the MacroName property. + FieldMacroButton field = (FieldMacroButton) builder.insertField(FieldType.FIELD_MACRO_BUTTON, true); + field.setMacroName("MyMacro"); + field.setDisplayText("Double click to run macro: " + field.getMacroName()); + + Assert.assertEquals(" MACROBUTTON MyMacro Double click to run macro: MyMacro", field.getFieldCode()); + + // Use the property to reference "ViewZoom200", a macro that ships with Microsoft Word. + // We can find all other macros via View -> Macros (dropdown) -> View Macros. + // In that menu, select "Word Commands" from the "Macros in:" drop down. + // If our document contains a custom macro with the same name as a stock macro, + // our macro will be the one that the MACROBUTTON field runs. + builder.insertParagraph(); + field = (FieldMacroButton) builder.insertField(FieldType.FIELD_MACRO_BUTTON, true); + field.setMacroName("ViewZoom200"); + field.setDisplayText("Run " + field.getMacroName()); + + Assert.assertEquals(field.getFieldCode(), " MACROBUTTON ViewZoom200 Run ViewZoom200"); + + // Save the document as a macro-enabled document type. + doc.save(getArtifactsDir() + "Field.MACROBUTTON.docm"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.MACROBUTTON.docm"); + + field = (FieldMacroButton) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_MACRO_BUTTON, " MACROBUTTON MyMacro Double click to run macro: MyMacro", "", field); + Assert.assertEquals("MyMacro", field.getMacroName()); + Assert.assertEquals("Double click to run macro: MyMacro", field.getDisplayText()); + + field = (FieldMacroButton) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_MACRO_BUTTON, " MACROBUTTON ViewZoom200 Run ViewZoom200", "", field); + Assert.assertEquals("ViewZoom200", field.getMacroName()); + Assert.assertEquals("Run ViewZoom200", field.getDisplayText()); + } + + @Test + public void fieldKeywords() throws Exception { + //ExStart + //ExFor:FieldKeywords + //ExFor:FieldKeywords.Text + //ExSummary:Shows to insert a KEYWORDS field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Add some keywords, also referred to as "tags" in File Explorer. + doc.getBuiltInDocumentProperties().setKeywords("Keyword1, Keyword2"); + + // The KEYWORDS field displays the value of this property. + FieldKeywords field = (FieldKeywords) builder.insertField(FieldType.FIELD_KEYWORD, true); + field.update(); + + Assert.assertEquals(field.getFieldCode(), " KEYWORDS "); + Assert.assertEquals(field.getResult(), "Keyword1, Keyword2"); + + // Setting a value for the field's Text property, + // and then updating the field will also overwrite the corresponding built-in property with the new value. + field.setText("OverridingKeyword"); + field.update(); + + Assert.assertEquals(" KEYWORDS OverridingKeyword", field.getFieldCode()); + Assert.assertEquals("OverridingKeyword", field.getResult()); + Assert.assertEquals("OverridingKeyword", doc.getBuiltInDocumentProperties().getKeywords()); + + doc.save(getArtifactsDir() + "Field.KEYWORDS.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.KEYWORDS.docx"); + + Assert.assertEquals("OverridingKeyword", doc.getBuiltInDocumentProperties().getKeywords()); + + field = (FieldKeywords) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_KEYWORD, " KEYWORDS OverridingKeyword", "OverridingKeyword", field); + Assert.assertEquals("OverridingKeyword", field.getText()); + } + + @Test + public void fieldNum() throws Exception { + //ExStart + //ExFor:FieldPage + //ExFor:FieldNumChars + //ExFor:FieldNumPages + //ExFor:FieldNumWords + //ExSummary:Shows how to use NUMCHARS, NUMWORDS, NUMPAGES and PAGE fields to track the size of our documents. + Document doc = new Document(getMyDir() + "Paragraphs.docx"); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + + // Below are three types of fields that we can use to track the size of our documents. + // 1 - Track the character count with a NUMCHARS field: + FieldNumChars fieldNumChars = (FieldNumChars) builder.insertField(FieldType.FIELD_NUM_CHARS, true); + builder.writeln(" characters"); + + // 2 - Track the word count with a NUMWORDS field: + FieldNumWords fieldNumWords = (FieldNumWords) builder.insertField(FieldType.FIELD_NUM_WORDS, true); + builder.writeln(" words"); + + // 3 - Use both PAGE and NUMPAGES fields to display what page the field is on, + // and the total number of pages in the document: + builder.getParagraphFormat().setAlignment(ParagraphAlignment.RIGHT); + builder.write("Page "); + FieldPage fieldPage = (FieldPage) builder.insertField(FieldType.FIELD_PAGE, true); + builder.write(" of "); + FieldNumPages fieldNumPages = (FieldNumPages) builder.insertField(FieldType.FIELD_NUM_PAGES, true); + + Assert.assertEquals(fieldNumChars.getFieldCode(), " NUMCHARS "); + Assert.assertEquals(fieldNumWords.getFieldCode(), " NUMWORDS "); + Assert.assertEquals(fieldNumPages.getFieldCode(), " NUMPAGES "); + Assert.assertEquals(fieldPage.getFieldCode(), " PAGE "); + + // These fields will not maintain accurate values in real time + // while we edit the document programmatically using Aspose.Words, or in Microsoft Word. + // We need to update them every we need to see an up-to-date value. + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.NUMCHARS.NUMWORDS.NUMPAGES.PAGE.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.NUMCHARS.NUMWORDS.NUMPAGES.PAGE.docx"); + + TestUtil.verifyField(FieldType.FIELD_NUM_CHARS, " NUMCHARS ", "6009", doc.getRange().getFields().get(0)); + TestUtil.verifyField(FieldType.FIELD_NUM_WORDS, " NUMWORDS ", "1054", doc.getRange().getFields().get(1)); + + TestUtil.verifyField(FieldType.FIELD_PAGE, " PAGE ", "6", doc.getRange().getFields().get(2)); + TestUtil.verifyField(FieldType.FIELD_NUM_PAGES, " NUMPAGES ", "6", doc.getRange().getFields().get(3)); + } + + @Test + public void fieldPrint() throws Exception { + //ExStart + //ExFor:FieldPrint + //ExFor:FieldPrint.PostScriptGroup + //ExFor:FieldPrint.PrinterInstructions + //ExSummary:Shows to insert a PRINT field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("My paragraph"); + + // The PRINT field can send instructions to the printer. + FieldPrint field = (FieldPrint) builder.insertField(FieldType.FIELD_PRINT, true); + + // Set the area for the printer to perform instructions over. + // In this case, it will be the paragraph that contains our PRINT field. + field.setPostScriptGroup("para"); + + // When we use a printer that supports PostScript to print our document, + // this command will turn the entire area that we specified in "field.PostScriptGroup" white. + field.setPrinterInstructions("erasepage"); + + Assert.assertEquals(" PRINT erasepage \\p para", field.getFieldCode()); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.PRINT.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.PRINT.docx"); + + field = (FieldPrint) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_PRINT, " PRINT erasepage \\p para", "", field); + Assert.assertEquals("para", field.getPostScriptGroup()); + Assert.assertEquals("erasepage", field.getPrinterInstructions()); + } + + @Test + public void fieldPrintDate() throws Exception { + //ExStart + //ExFor:FieldPrintDate + //ExFor:FieldPrintDate.UseLunarCalendar + //ExFor:FieldPrintDate.UseSakaEraCalendar + //ExFor:FieldPrintDate.UseUmAlQuraCalendar + //ExSummary:Shows read PRINTDATE fields. + Document doc = new Document(getMyDir() + "Field sample - PRINTDATE.docx"); + + // When a document is printed by a printer or printed as a PDF (but not exported to PDF), + // PRINTDATE fields will display the print operation's date/time. + // If no printing has taken place, these fields will display "0/0/0000". + FieldPrintDate field = (FieldPrintDate) doc.getRange().getFields().get(0); + + Assert.assertEquals("3/25/2020 12:00:00 AM", field.getResult()); + Assert.assertEquals(" PRINTDATE ", field.getFieldCode()); + + // Below are three different calendar types according to which the PRINTDATE field + // can display the date and time of the last printing operation. + // 1 - Islamic Lunar Calendar: + field = (FieldPrintDate) doc.getRange().getFields().get(1); + + Assert.assertTrue(field.getUseLunarCalendar()); + Assert.assertEquals("8/1/1441 12:00:00 AM", field.getResult()); + Assert.assertEquals(" PRINTDATE \\h", field.getFieldCode()); + + field = (FieldPrintDate) doc.getRange().getFields().get(2); + + // 2 - Umm al-Qura calendar: + Assert.assertTrue(field.getUseUmAlQuraCalendar()); + Assert.assertEquals("8/1/1441 12:00:00 AM", field.getResult()); + Assert.assertEquals(" PRINTDATE \\u", field.getFieldCode()); + + field = (FieldPrintDate) doc.getRange().getFields().get(3); + + // 3 - Indian National Calendar: + Assert.assertTrue(field.getUseSakaEraCalendar()); + Assert.assertEquals("1/5/1942 12:00:00 AM", field.getResult()); + Assert.assertEquals(" PRINTDATE \\s", field.getFieldCode()); + //ExEnd + } + + @Test + public void fieldQuote() throws Exception { + //ExStart + //ExFor:FieldQuote + //ExFor:FieldQuote.Text + //ExFor:Document.UpdateFields + //ExSummary:Shows to use the QUOTE field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a QUOTE field, which will display the value of its Text property. + FieldQuote field = (FieldQuote) builder.insertField(FieldType.FIELD_QUOTE, true); + field.setText("\"Quoted text\""); + + Assert.assertEquals(" QUOTE \"\\\"Quoted text\\\"\"", field.getFieldCode()); + + // Insert a QUOTE field and nest a DATE field inside it. + // DATE fields update their value to the current date every time we open the document using Microsoft Word. + // Nesting the DATE field inside the QUOTE field like this will freeze its value + // to the date when we created the document. + builder.write("\nDocument creation date: "); + field = (FieldQuote) builder.insertField(FieldType.FIELD_QUOTE, true); + builder.moveTo(field.getSeparator()); + builder.insertField(FieldType.FIELD_DATE, true); + + Assert.assertEquals(" QUOTE \u0013 DATE \u0014" + LocalDate.now().format(DateTimeFormatter.ofPattern("M/d/YYYY")) + "\u0015", field.getFieldCode()); + + // Update all the fields to display their correct results. + doc.updateFields(); + + Assert.assertEquals("\"Quoted text\"", doc.getRange().getFields().get(0).getResult()); + + doc.save(getArtifactsDir() + "Field.QUOTE.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.QUOTE.docx"); + + TestUtil.verifyField(FieldType.FIELD_QUOTE, " QUOTE \"\\\"Quoted text\\\"\"", "\"Quoted text\"", doc.getRange().getFields().get(0)); + + TestUtil.verifyField(FieldType.FIELD_QUOTE, " QUOTE \u0013 DATE \u0014" + LocalDate.now().format(DateTimeFormatter.ofPattern("M/d/YYYY")) + "\u0015", + LocalDate.now().format(DateTimeFormatter.ofPattern("M/d/YYYY")), doc.getRange().getFields().get(1)); + + } + + //ExStart + //ExFor:FieldNext + //ExFor:FieldNextIf + //ExFor:FieldNextIf.ComparisonOperator + //ExFor:FieldNextIf.LeftExpression + //ExFor:FieldNextIf.RightExpression + //ExSummary:Shows how to use NEXT/NEXTIF fields to merge multiple rows into one page during a mail merge. + @Test //ExSkip + public void fieldNext() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a data source for our mail merge with 3 rows. + // A mail merge that uses this table would normally create a 3-page document. + DataTable table = new DataTable("Employees"); + table.getColumns().add("Courtesy Title"); + table.getColumns().add("First Name"); + table.getColumns().add("Last Name"); + table.getRows().add("Mr.", "John", "Doe"); + table.getRows().add("Mrs.", "Jane", "Cardholder"); + table.getRows().add("Mr.", "Joe", "Bloggs"); + + insertMergeFields(builder, "First row: "); + + // If we have multiple merge fields with the same FieldName, + // they will receive data from the same row of the data source and display the same value after the merge. + // A NEXT field tells the mail merge instantly to move down one row, + // which means any MERGEFIELDs that follow the NEXT field will receive data from the next row. + // Make sure never to try to skip to the next row while already on the last row. + FieldNext fieldNext = (FieldNext) builder.insertField(FieldType.FIELD_NEXT, true); + + Assert.assertEquals(" NEXT ", fieldNext.getFieldCode()); + + // After the merge, the data source values that these MERGEFIELDs accept + // will end up on the same page as the MERGEFIELDs above. + insertMergeFields(builder, "Second row: "); + + // A NEXTIF field has the same function as a NEXT field, + // but it skips to the next row only if a statement constructed by the following 3 properties is true. + FieldNextIf fieldNextIf = (FieldNextIf) builder.insertField(FieldType.FIELD_NEXT_IF, true); + fieldNextIf.setLeftExpression("5"); + fieldNextIf.setRightExpression("2 + 3"); + fieldNextIf.setComparisonOperator("="); + + Assert.assertEquals(" NEXTIF 5 = \"2 + 3\"", fieldNextIf.getFieldCode()); + + // If the comparison asserted by the above field is correct, + // the following 3 merge fields will take data from the third row. + // Otherwise, these fields will take data from row 2 again. + insertMergeFields(builder, "Third row: "); + + doc.getMailMerge().execute(table); + + // Our data source has 3 rows, and we skipped rows twice. + // Our output document will have 1 page with data from all 3 rows. + doc.save(getArtifactsDir() + "Field.NEXT.NEXTIF.docx"); + testFieldNext(doc); //ExSKip + } + + /// <summary> + /// Uses a document builder to insert MERGEFIELDs for a data source that contains columns named "Courtesy Title", "First Name" and "Last Name". + /// </summary> + @Test(enabled = false) //ExSkip + public void insertMergeFields(final DocumentBuilder builder, final String firstFieldTextBefore) throws Exception { + insertMergeField(builder, "Courtesy Title", firstFieldTextBefore, " "); + insertMergeField(builder, "First Name", null, " "); + insertMergeField(builder, "Last Name", null, null); + builder.insertParagraph(); + } + + /// <summary> + /// Uses a document builder to insert a MERRGEFIELD with specified properties. + /// </summary> + @Test(enabled = false) //ExSkip + public void insertMergeField(final DocumentBuilder builder, final String fieldName, final String textBefore, final String textAfter) throws Exception { + FieldMergeField field = (FieldMergeField) builder.insertField(FieldType.FIELD_MERGE_FIELD, true); + field.setFieldName(fieldName); + field.setTextBefore(textBefore); + field.setTextAfter(textAfter); + } + //ExEnd + + private void testFieldNext(Document doc) throws Exception { + doc = DocumentHelper.saveOpen(doc); + + Assert.assertEquals(0, doc.getRange().getFields().getCount()); + Assert.assertEquals("First row: Mr. John Doe\r" + + "Second row: Mrs. Jane Cardholder\r" + + "Third row: Mr. Joe Bloggs\r\f", doc.getText()); + } + + //ExStart + //ExFor:FieldNoteRef + //ExFor:FieldNoteRef.BookmarkName + //ExFor:FieldNoteRef.InsertHyperlink + //ExFor:FieldNoteRef.InsertReferenceMark + //ExFor:FieldNoteRef.InsertRelativePosition + //ExSummary:Shows to insert NOTEREF fields, and modify their appearance. + @Test//ExSkip + public void fieldNoteRef() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a bookmark with a footnote that the NOTEREF field will reference. + insertBookmarkWithFootnote(builder, "MyBookmark1", "Contents of MyBookmark1", "Footnote from MyBookmark1"); + + // This NOTEREF field will display the number of the footnote inside the referenced bookmark. + // Setting the InsertHyperlink property lets us jump to the bookmark by Ctrl + clicking the field in Microsoft Word. + Assert.assertEquals(" NOTEREF MyBookmark2 \\h", + insertFieldNoteRef(builder, "MyBookmark2", true, false, false, "Hyperlink to Bookmark2, with footnote number ").getFieldCode()); + + // When using the \p flag, after the footnote number, the field also displays the bookmark's position relative to the field. + // Bookmark1 is above this field and contains footnote number 1, so the result will be "1 above" on update. + Assert.assertEquals(" NOTEREF MyBookmark1 \\h \\p", + insertFieldNoteRef(builder, "MyBookmark1", true, true, false, "Bookmark1, with footnote number ").getFieldCode()); + + // Bookmark2 is below this field and contains footnote number 2, so the field will display "2 below". + // The \f flag makes the number 2 appear in the same format as the footnote number label in the actual text. + Assert.assertEquals(" NOTEREF MyBookmark2 \\h \\p \\f", + insertFieldNoteRef(builder, "MyBookmark2", true, true, true, "Bookmark2, with footnote number ").getFieldCode()); + + builder.insertBreak(BreakType.PAGE_BREAK); + insertBookmarkWithFootnote(builder, "MyBookmark2", "Contents of MyBookmark2", "Footnote from MyBookmark2"); + + doc.updatePageLayout(); + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.NOTEREF.docx"); + testNoteRef(new Document(getArtifactsDir() + "Field.NOTEREF.docx")); //ExSkip + } + + /// <summary> + /// Uses a document builder to insert a NOTEREF field with specified properties. + /// </summary> + private static FieldNoteRef insertFieldNoteRef(DocumentBuilder builder, String bookmarkName, boolean insertHyperlink, boolean insertRelativePosition, boolean insertReferenceMark, String textBefore) throws Exception { + builder.write(textBefore); + + FieldNoteRef field = (FieldNoteRef) builder.insertField(FieldType.FIELD_NOTE_REF, true); + field.setBookmarkName(bookmarkName); + field.setInsertHyperlink(insertHyperlink); + field.setInsertRelativePosition(insertRelativePosition); + field.setInsertReferenceMark(insertReferenceMark); + builder.writeln(); + + return field; + } + + /// <summary> + /// Uses a document builder to insert a named bookmark with a footnote at the end. + /// </summary> + private void insertBookmarkWithFootnote(final DocumentBuilder builder, final String bookmarkName, + final String bookmarkText, final String footnoteText) { + builder.startBookmark(bookmarkName); + builder.write(bookmarkText); + builder.insertFootnote(FootnoteType.FOOTNOTE, footnoteText); + builder.endBookmark(bookmarkName); + builder.writeln(); + } + //ExEnd + + private void testNoteRef(Document doc) throws Exception + { + FieldNoteRef field = (FieldNoteRef) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_NOTE_REF, " NOTEREF MyBookmark2 \\h", "2", field); + Assert.assertEquals("MyBookmark2", field.getBookmarkName()); + Assert.assertTrue(field.getInsertHyperlink()); + Assert.assertFalse(field.getInsertRelativePosition()); + Assert.assertFalse(field.getInsertReferenceMark()); + + field = (FieldNoteRef) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_NOTE_REF, " NOTEREF MyBookmark1 \\h \\p", "1 above", field); + Assert.assertEquals("MyBookmark1", field.getBookmarkName()); + Assert.assertTrue(field.getInsertHyperlink()); + Assert.assertTrue(field.getInsertRelativePosition()); + Assert.assertFalse(field.getInsertReferenceMark()); + + field = (FieldNoteRef) doc.getRange().getFields().get(2); + + TestUtil.verifyField(FieldType.FIELD_NOTE_REF, " NOTEREF MyBookmark2 \\h \\p \\f", "2 below", field); + Assert.assertEquals("MyBookmark2", field.getBookmarkName()); + Assert.assertTrue(field.getInsertHyperlink()); + Assert.assertTrue(field.getInsertRelativePosition()); + Assert.assertTrue(field.getInsertReferenceMark()); + } + + @Test + public void noteRef() throws Exception { + //ExStart + //ExFor:FieldNoteRef + //ExSummary:Shows how to cross-reference footnotes with the NOTEREF field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("CrossReference: "); + + FieldNoteRef field = (FieldNoteRef)builder.insertField(FieldType.FIELD_NOTE_REF, false); // <--- don't update field + field.setBookmarkName("CrossRefBookmark"); + field.setInsertHyperlink(true); + field.setInsertReferenceMark(true); + field.setInsertRelativePosition(false); + builder.writeln(); + + builder.startBookmark("CrossRefBookmark"); + builder.write("Hello world!"); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Cross referenced footnote."); + builder.endBookmark("CrossRefBookmark"); + builder.writeln(); + + doc.updateFields(); + + // This field works only in older versions of Microsoft Word. + doc.save(getArtifactsDir() + "Field.NOTEREF.doc"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.NOTEREF.doc"); + field = (FieldNoteRef)doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_NOTE_REF, " NOTEREF CrossRefBookmark \\h \\f", "1", field); + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, null, "Cross referenced footnote.", + (Footnote)doc.getChild(NodeType.FOOTNOTE, 0, true)); + } + + //ExStart + //ExFor:FieldPageRef + //ExFor:FieldPageRef.BookmarkName + //ExFor:FieldPageRef.InsertHyperlink + //ExFor:FieldPageRef.InsertRelativePosition + //ExSummary:Shows to insert PAGEREF fields to display the relative location of bookmarks. + @Test//ExSkip + public void fieldPageRef() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + insertAndNameBookmark(builder, "MyBookmark1"); + + // Insert a PAGEREF field that displays what page a bookmark is on. + // Set the InsertHyperlink flag to make the field also function as a clickable link to the bookmark. + Assert.assertEquals(" PAGEREF MyBookmark3 \\h", + insertFieldPageRef(builder, "MyBookmark3", true, false, "Hyperlink to Bookmark3, on page: ").getFieldCode()); + + // We can use the \p flag to get the PAGEREF field to display + // the bookmark's position relative to the position of the field. + // Bookmark1 is on the same page and above this field, so this field's displayed result will be "above". + Assert.assertEquals(" PAGEREF MyBookmark1 \\h \\p", + insertFieldPageRef(builder, "MyBookmark1", true, true, "Bookmark1 is ").getFieldCode()); + + // Bookmark2 will be on the same page and below this field, so this field's displayed result will be "below". + Assert.assertEquals(" PAGEREF MyBookmark2 \\h \\p", + insertFieldPageRef(builder, "MyBookmark2", true, true, "Bookmark2 is ").getFieldCode()); + + // Bookmark3 will be on a different page, so the field will display "on page 2". + Assert.assertEquals(" PAGEREF MyBookmark3 \\h \\p", + insertFieldPageRef(builder, "MyBookmark3", true, true, "Bookmark3 is ").getFieldCode()); + + insertAndNameBookmark(builder, "MyBookmark2"); + builder.insertBreak(BreakType.PAGE_BREAK); + insertAndNameBookmark(builder, "MyBookmark3"); + + doc.updatePageLayout(); + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.PAGEREF.docx"); + testPageRef(new Document(getArtifactsDir() + "Field.PAGEREF.docx")); //ExSkip + } + + /// <summary> + /// Uses a document builder to insert a PAGEREF field and sets its properties. + /// </summary> + private FieldPageRef insertFieldPageRef(final DocumentBuilder builder, final String bookmarkName, final boolean insertHyperlink, + final boolean insertRelativePosition, final String textBefore) throws Exception { + builder.write(textBefore); + + FieldPageRef field = (FieldPageRef) builder.insertField(FieldType.FIELD_PAGE_REF, true); + field.setBookmarkName(bookmarkName); + field.setInsertHyperlink(insertHyperlink); + field.setInsertRelativePosition(insertRelativePosition); + builder.writeln(); + + return field; + } + + /// <summary> + /// Uses a document builder to insert a named bookmark. + /// </summary> + private void insertAndNameBookmark(final DocumentBuilder builder, final String bookmarkName) { + builder.startBookmark(bookmarkName); + builder.writeln(MessageFormat.format("Contents of bookmark \"{0}\".", bookmarkName)); + builder.endBookmark(bookmarkName); + } + //ExEnd + + private void testPageRef(Document doc) throws Exception + { + FieldPageRef field = (FieldPageRef) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_PAGE_REF, " PAGEREF MyBookmark3 \\h", "2", field); + Assert.assertEquals("MyBookmark3", field.getBookmarkName()); + Assert.assertTrue(field.getInsertHyperlink()); + Assert.assertFalse(field.getInsertRelativePosition()); + + field = (FieldPageRef) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_PAGE_REF, " PAGEREF MyBookmark1 \\h \\p", "above", field); + Assert.assertEquals("MyBookmark1", field.getBookmarkName()); + Assert.assertTrue(field.getInsertHyperlink()); + Assert.assertTrue(field.getInsertRelativePosition()); + + field = (FieldPageRef) doc.getRange().getFields().get(2); + + TestUtil.verifyField(FieldType.FIELD_PAGE_REF, " PAGEREF MyBookmark2 \\h \\p", "below", field); + Assert.assertEquals("MyBookmark2", field.getBookmarkName()); + Assert.assertTrue(field.getInsertHyperlink()); + Assert.assertTrue(field.getInsertRelativePosition()); + + field = (FieldPageRef) doc.getRange().getFields().get(3); + + TestUtil.verifyField(FieldType.FIELD_PAGE_REF, " PAGEREF MyBookmark3 \\h \\p", "on page 2", field); + Assert.assertEquals("MyBookmark3", field.getBookmarkName()); + Assert.assertTrue(field.getInsertHyperlink()); + Assert.assertTrue(field.getInsertRelativePosition()); + } + + //ExStart + //ExFor:FieldRef + //ExFor:FieldRef.BookmarkName + //ExFor:FieldRef.IncludeNoteOrComment + //ExFor:FieldRef.InsertHyperlink + //ExFor:FieldRef.InsertParagraphNumber + //ExFor:FieldRef.InsertParagraphNumberInFullContext + //ExFor:FieldRef.InsertParagraphNumberInRelativeContext + //ExFor:FieldRef.InsertRelativePosition + //ExFor:FieldRef.NumberSeparator + //ExFor:FieldRef.SuppressNonDelimiters + //ExSummary:Shows how to insert REF fields to reference bookmarks. + @Test//ExSkip + public void fieldRef() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startBookmark("MyBookmark"); + builder.insertFootnote(FootnoteType.FOOTNOTE, "MyBookmark footnote #1"); + builder.write("Text that will appear in REF field"); + builder.insertFootnote(FootnoteType.FOOTNOTE, "MyBookmark footnote #2"); + builder.endBookmark("MyBookmark"); + builder.moveToDocumentStart(); + + // We will apply a custom list format, where the amount of angle brackets indicates the list level we are currently at. + builder.getListFormat().applyNumberDefault(); + builder.getListFormat().getListLevel().setNumberFormat("> \u0000"); + + // Insert a REF field that will contain the text within our bookmark, act as a hyperlink, and clone the bookmark's footnotes. + FieldRef field = insertFieldRef(builder, "MyBookmark", "", "\n"); + field.setIncludeNoteOrComment(true); + field.setInsertHyperlink(true); + + Assert.assertEquals(field.getFieldCode(), " REF MyBookmark \\f \\h"); + + // Insert a REF field, and display whether the referenced bookmark is above or below it. + field = insertFieldRef(builder, "MyBookmark", "The referenced paragraph is ", " this field.\n"); + field.setInsertRelativePosition(true); + + Assert.assertEquals(field.getFieldCode(), " REF MyBookmark \\p"); + + // Display the list number of the bookmark as it appears in the document. + field = insertFieldRef(builder, "MyBookmark", "The bookmark's paragraph number is ", "\n"); + field.setInsertParagraphNumber(true); + + Assert.assertEquals(" REF MyBookmark \\n", field.getFieldCode()); + + // Display the bookmark's list number, but with non-delimiter characters, such as the angle brackets, omitted. + field = insertFieldRef(builder, "MyBookmark", "The bookmark's paragraph number, non-delimiters suppressed, is ", "\n"); + field.setInsertParagraphNumber(true); + field.setSuppressNonDelimiters(true); + + Assert.assertEquals(field.getFieldCode(), " REF MyBookmark \\n \\t"); + + // Move down one list level. + builder.getListFormat().setListLevelNumber(builder.getListFormat().getListLevelNumber() + 1)/*Property++*/; + builder.getListFormat().getListLevel().setNumberFormat(">> \u0001"); + + // Display the list number of the bookmark and the numbers of all the list levels above it. + field = insertFieldRef(builder, "MyBookmark", "The bookmark's full context paragraph number is ", "\n"); + field.setInsertParagraphNumberInFullContext(true); + + Assert.assertEquals(field.getFieldCode(), " REF MyBookmark \\w"); + + builder.insertBreak(BreakType.PAGE_BREAK); + + // Display the list level numbers between this REF field, and the bookmark that it is referencing. + field = insertFieldRef(builder, "MyBookmark", "The bookmark's relative paragraph number is ", "\n"); + field.setInsertParagraphNumberInRelativeContext(true); + + Assert.assertEquals(field.getFieldCode(), " REF MyBookmark \\r"); + + // At the end of the document, the bookmark will show up as a list item here. + builder.writeln("List level above bookmark"); + builder.getListFormat().setListLevelNumber(builder.getListFormat().getListLevelNumber() + 1)/*Property++*/; + builder.getListFormat().getListLevel().setNumberFormat(">>> \u0002"); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.REF.docx"); + testFieldRef(new Document(getArtifactsDir() + "Field.REF.docx")); //ExSkip + } + + /// <summary> + /// Get the document builder to insert a REF field, reference a bookmark with it, and add text before and after it. + /// </summary> + private FieldRef insertFieldRef(final DocumentBuilder builder, final String bookmarkName, + final String textBefore, final String textAfter) throws Exception { + builder.write(textBefore); + FieldRef field = (FieldRef) builder.insertField(FieldType.FIELD_REF, true); + field.setBookmarkName(bookmarkName); + builder.write(textAfter); + return field; + } + //ExEnd + + private void testFieldRef(Document doc) throws Exception { + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", "MyBookmark footnote #1", + (Footnote) doc.getChild(NodeType.FOOTNOTE, 0, true)); + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", "MyBookmark footnote #2", + (Footnote) doc.getChild(NodeType.FOOTNOTE, 1, true)); + + FieldRef field = (FieldRef) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_REF, " REF MyBookmark \\f \\h", + "Text that will appear in REF field", field); + Assert.assertEquals("MyBookmark", field.getBookmarkName()); + Assert.assertTrue(field.getIncludeNoteOrComment()); + Assert.assertTrue(field.getInsertHyperlink()); + + field = (FieldRef) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_REF, " REF MyBookmark \\p", "below", field); + Assert.assertEquals("MyBookmark", field.getBookmarkName()); + Assert.assertTrue(field.getInsertRelativePosition()); + + field = (FieldRef) doc.getRange().getFields().get(2); + + TestUtil.verifyField(FieldType.FIELD_REF, " REF MyBookmark \\n", "‎>>> i", field); + Assert.assertEquals("MyBookmark", field.getBookmarkName()); + Assert.assertTrue(field.getInsertParagraphNumber()); + Assert.assertEquals(" REF MyBookmark \\n", field.getFieldCode()); + Assert.assertEquals("‎>>> i", field.getResult()); + + field = (FieldRef) doc.getRange().getFields().get(3); + + TestUtil.verifyField(FieldType.FIELD_REF, " REF MyBookmark \\n \\t", "‎i", field); + Assert.assertEquals("MyBookmark", field.getBookmarkName()); + Assert.assertTrue(field.getInsertParagraphNumber()); + Assert.assertTrue(field.getSuppressNonDelimiters()); + + field = (FieldRef) doc.getRange().getFields().get(4); + + TestUtil.verifyField(FieldType.FIELD_REF, " REF MyBookmark \\w", "‎> 4>> c>>> i", field); + Assert.assertEquals("MyBookmark", field.getBookmarkName()); + Assert.assertTrue(field.getInsertParagraphNumberInFullContext()); + + field = (FieldRef) doc.getRange().getFields().get(5); + + TestUtil.verifyField(FieldType.FIELD_REF, " REF MyBookmark \\r", "‎>> c>>> i", field); + Assert.assertEquals("MyBookmark", field.getBookmarkName()); + Assert.assertTrue(field.getInsertParagraphNumberInRelativeContext()); + } + + @Test(enabled = false, description = "WORDSNET-18068") + public void fieldRD() throws Exception { + //ExStart + //ExFor:FieldRD + //ExFor:FieldRD.FileName + //ExFor:FieldRD.IsPathRelative + //ExSummary:Shows to use the RD field to create a table of contents entries from headings in other documents. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Use a document builder to insert a table of contents, + // and then add one entry for the table of contents on the following page. + builder.insertField(FieldType.FIELD_TOC, true); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.getCurrentParagraph().getParagraphFormat().setStyleName("Heading 1"); + builder.writeln("TOC entry from within this document"); + + // Insert an RD field, which references another local file system document in its FileName property. + // The TOC will also now accept all headings from the referenced document as entries for its table. + FieldRD field = (FieldRD) builder.insertField(FieldType.FIELD_REF_DOC, true); + field.setFileName("ReferencedDocument.docx"); + field.isPathRelative(true); + + Assert.assertEquals(field.getFieldCode(), " RD ReferencedDocument.docx \\f"); + + // Create the document that the RD field is referencing and insert a heading. + // This heading will show up as an entry in the TOC field in our first document. + Document referencedDoc = new Document(); + DocumentBuilder refDocBuilder = new DocumentBuilder(referencedDoc); + refDocBuilder.getCurrentParagraph().getParagraphFormat().setStyleName("Heading 1"); + refDocBuilder.writeln("TOC entry from referenced document"); + referencedDoc.save(getArtifactsDir() + "ReferencedDocument.docx"); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.RD.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.RD.docx"); + + FieldToc fieldToc = (FieldToc) doc.getRange().getFields().get(0); + + Assert.assertEquals("TOC entry from within this document\t\u0013 PAGEREF _Toc36149519 \\h \u00142\u0015\r" + + "TOC entry from referenced document\t1\r", fieldToc.getResult()); + + FieldPageRef fieldPageRef = (FieldPageRef) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_PAGE_REF, " PAGEREF _Toc36149519 \\h ", "2", fieldPageRef); + + field = (FieldRD) doc.getRange().getFields().get(2); + + TestUtil.verifyField(FieldType.FIELD_REF_DOC, " RD ReferencedDocument.docx \\f", "", field); + Assert.assertEquals("ReferencedDocument.docx", field.getFileName()); + Assert.assertTrue(field.isPathRelative()); + } + + @Test + public void skipIf() throws Exception { + //ExStart + //ExFor:FieldSkipIf + //ExFor:FieldSkipIf.ComparisonOperator + //ExFor:FieldSkipIf.LeftExpression + //ExFor:FieldSkipIf.RightExpression + //ExSummary:Shows how to skip pages in a mail merge using the SKIPIF field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a SKIPIF field. If the current row of a mail merge operation fulfills the condition + // which the expressions of this field state, then the mail merge operation aborts the current row, + // discards the current merge document, and then immediately moves to the next row to begin the next merge document. + FieldSkipIf fieldSkipIf = (FieldSkipIf) builder.insertField(FieldType.FIELD_SKIP_IF, true); + + // Move the builder to the SKIPIF field's separator so we can place a MERGEFIELD inside the SKIPIF field. + builder.moveTo(fieldSkipIf.getSeparator()); + FieldMergeField fieldMergeField = (FieldMergeField) builder.insertField(FieldType.FIELD_MERGE_FIELD, true); + fieldMergeField.setFieldName("Department"); + + // The MERGEFIELD refers to the "Department" column in our data table. If a row from that table + // has a value of "HR" in its "Department" column, then this row will fulfill the condition. + fieldSkipIf.setLeftExpression("="); + fieldSkipIf.setRightExpression("HR"); + + // Add content to our document, create the data source, and execute the mail merge. + builder.moveToDocumentEnd(); + builder.write("Dear "); + fieldMergeField = (FieldMergeField) builder.insertField(FieldType.FIELD_MERGE_FIELD, true); + fieldMergeField.setFieldName("Name"); + builder.writeln(", "); + + // This table has three rows, and one of them fulfills the condition of our SKIPIF field. + // The mail merge will produce two pages. + DataTable table = new DataTable("Employees"); + table.getColumns().add("Name"); + table.getColumns().add("Department"); + table.getRows().add("John Doe", "Sales"); + table.getRows().add("Jane Doe", "Accounting"); + table.getRows().add("John Cardholder", "HR"); + + doc.getMailMerge().execute(table); + doc.save(getArtifactsDir() + "Field.SKIPIF.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.SKIPIF.docx"); + + Assert.assertEquals(0, doc.getRange().getFields().getCount()); + Assert.assertEquals("Dear John Doe, \r" + + "\fDear Jane Doe, \r\f", doc.getText()); + } + + @Test + public void fieldSetRef() throws Exception { + //ExStart + //ExFor:FieldRef + //ExFor:FieldRef.BookmarkName + //ExFor:FieldSet + //ExFor:FieldSet.BookmarkName + //ExFor:FieldSet.BookmarkText + //ExSummary:Shows how to create bookmarked text with a SET field, and then display it in the document using a REF field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Name bookmarked text with a SET field. + // This field refers to the "bookmark" not a bookmark structure that appears within the text, but a named variable. + FieldSet fieldSet = (FieldSet) builder.insertField(FieldType.FIELD_SET, false); + fieldSet.setBookmarkName("MyBookmark"); + fieldSet.setBookmarkText("Hello world!"); + fieldSet.update(); + + Assert.assertEquals(" SET MyBookmark \"Hello world!\"", fieldSet.getFieldCode()); + + // Refer to the bookmark by name in a REF field and display its contents. + FieldRef fieldRef = (FieldRef) builder.insertField(FieldType.FIELD_REF, true); + fieldRef.setBookmarkName("MyBookmark"); + fieldRef.update(); + + Assert.assertEquals(" REF MyBookmark", fieldRef.getFieldCode()); + Assert.assertEquals("Hello world!", fieldRef.getResult()); + + doc.save(getArtifactsDir() + "Field.SET.REF.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.SET.REF.docx"); + + Assert.assertEquals("Hello world!", doc.getRange().getBookmarks().get(0).getText()); + + fieldSet = (FieldSet) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_SET, " SET MyBookmark \"Hello world!\"", "Hello world!", fieldSet); + Assert.assertEquals("MyBookmark", fieldSet.getBookmarkName()); + Assert.assertEquals("Hello world!", fieldSet.getBookmarkText()); + + TestUtil.verifyField(FieldType.FIELD_REF, " REF MyBookmark", "Hello world!", fieldRef); + Assert.assertEquals("Hello world!", fieldRef.getResult()); + } + + @Test + public void fieldTemplate() throws Exception { + //ExStart + //ExFor:FieldTemplate + //ExFor:FieldTemplate.IncludeFullPath + //ExFor:FieldOptions.TemplateName + //ExSummary:Shows how to use a TEMPLATE field to display the local file system location of a document's template. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // We can set a template name using by the fields. This property is used when the "doc.AttachedTemplate" is empty. + // If this property is empty the default template file name "Normal.dotm" is used. + doc.getFieldOptions().setTemplateName(""); + + FieldTemplate field = (FieldTemplate) builder.insertField(FieldType.FIELD_TEMPLATE, false); + Assert.assertEquals(field.getFieldCode(), " TEMPLATE "); + + builder.writeln(); + field = (FieldTemplate) builder.insertField(FieldType.FIELD_TEMPLATE, false); + field.setIncludeFullPath(true); + + Assert.assertEquals(field.getFieldCode(), " TEMPLATE \\p"); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.TEMPLATE.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.TEMPLATE.docx"); + + field = (FieldTemplate) doc.getRange().getFields().get(0); + Assert.assertEquals(" TEMPLATE ", field.getFieldCode()); + Assert.assertEquals("Normal.dotm", field.getResult()); + + field = (FieldTemplate) doc.getRange().getFields().get(1); + Assert.assertEquals(" TEMPLATE \\p", field.getFieldCode()); + Assert.assertEquals("Normal.dotm", field.getResult()); + } + + @Test + public void fieldSymbol() throws Exception { + //ExStart + //ExFor:FieldSymbol + //ExFor:FieldSymbol.CharacterCode + //ExFor:FieldSymbol.DontAffectsLineSpacing + //ExFor:FieldSymbol.FontName + //ExFor:FieldSymbol.FontSize + //ExFor:FieldSymbol.IsAnsi + //ExFor:FieldSymbol.IsShiftJis + //ExFor:FieldSymbol.IsUnicode + //ExSummary:Shows how to use the SYMBOL field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are three ways to use a SYMBOL field to display a single character. + // 1 - Add a SYMBOL field which displays the © (Copyright) symbol, specified by an ANSI character code: + FieldSymbol field = (FieldSymbol) builder.insertField(FieldType.FIELD_SYMBOL, true); + + // The ANSI character code "U+00A9", or "169" in integer form, is reserved for the copyright symbol. + field.setCharacterCode(Integer.toString(0x00a9)); + field.isAnsi(true); + + Assert.assertEquals(field.getFieldCode(), " SYMBOL 169 \\a"); + + builder.writeln(" Line 1"); + + // 2 - Add a SYMBOL field which displays the ∞ (Infinity) symbol, and modify its appearance: + field = (FieldSymbol) builder.insertField(FieldType.FIELD_SYMBOL, true); + + // In Unicode, the infinity symbol occupies the "221E" code. + field.setCharacterCode(Integer.toString(0x221E)); + field.isUnicode(true); + + // Change the font of our symbol after using the Windows Character Map + // to ensure that the font can represent that symbol. + field.setFontName("Calibri"); + field.setFontSize("24"); + + // We can set this flag for tall symbols to make them not push down the rest of the text on their line. + field.setDontAffectsLineSpacing(true); + + Assert.assertEquals(field.getFieldCode(), " SYMBOL 8734 \\u \\f Calibri \\s 24 \\h"); + + builder.writeln("Line 2"); + + // 3 - Add a SYMBOL field which displays the あ character, + // with a font that supports Shift-JIS (Windows-932) codepage: + field = (FieldSymbol) builder.insertField(FieldType.FIELD_SYMBOL, true); + field.setFontName("MS Gothic"); + field.setCharacterCode(Integer.toString(0x82A0)); + field.isShiftJis(true); + + Assert.assertEquals(field.getFieldCode(), " SYMBOL 33440 \\f \"MS Gothic\" \\j"); + + builder.write("Line 3"); + + doc.save(getArtifactsDir() + "Field.SYMBOL.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.SYMBOL.docx"); + + field = (FieldSymbol) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_SYMBOL, " SYMBOL 169 \\a", "", field); + Assert.assertEquals(Integer.toString(0x00a9), field.getCharacterCode()); + Assert.assertTrue(field.isAnsi()); + Assert.assertEquals("©", field.getDisplayResult()); + + field = (FieldSymbol) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_SYMBOL, " SYMBOL 8734 \\u \\f Calibri \\s 24 \\h", "", field); + Assert.assertEquals(Integer.toString(0x221E), field.getCharacterCode()); + Assert.assertEquals("Calibri", field.getFontName()); + Assert.assertEquals("24", field.getFontSize()); + Assert.assertTrue(field.isUnicode()); + Assert.assertTrue(field.getDontAffectsLineSpacing()); + Assert.assertEquals("∞", field.getDisplayResult()); + + field = (FieldSymbol) doc.getRange().getFields().get(2); + + TestUtil.verifyField(FieldType.FIELD_SYMBOL, " SYMBOL 33440 \\f \"MS Gothic\" \\j", "", field); + Assert.assertEquals(Integer.toString(0x82A0), field.getCharacterCode()); + Assert.assertEquals("MS Gothic", field.getFontName()); + Assert.assertTrue(field.isShiftJis()); + } + + @Test + public void fieldTitle() throws Exception { + //ExStart + //ExFor:FieldTitle + //ExFor:FieldTitle.Text + //ExSummary:Shows how to use the TITLE field. + Document doc = new Document(); + + // Set a value for the "Title" built-in document property. + doc.getBuiltInDocumentProperties().setTitle("My Title"); + + // We can use the TITLE field to display the value of this property in the document. + DocumentBuilder builder = new DocumentBuilder(doc); + FieldTitle field = (FieldTitle) builder.insertField(FieldType.FIELD_TITLE, false); + field.update(); + + Assert.assertEquals(field.getFieldCode(), " TITLE "); + Assert.assertEquals(field.getResult(), "My Title"); + + // Setting a value for the field's Text property, + // and then updating the field will also overwrite the corresponding built-in property with the new value. + builder.writeln(); + field = (FieldTitle) builder.insertField(FieldType.FIELD_TITLE, false); + field.setText("My New Title"); + field.update(); + + Assert.assertEquals(" TITLE \"My New Title\"", field.getFieldCode()); + Assert.assertEquals("My New Title", field.getResult()); + Assert.assertEquals("My New Title", doc.getBuiltInDocumentProperties().getTitle()); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.TITLE.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.TITLE.docx"); + + Assert.assertEquals("My New Title", doc.getBuiltInDocumentProperties().getTitle()); + + field = (FieldTitle) doc.getRange().getFields().get(0); + + TestUtil.verifyField(FieldType.FIELD_TITLE, " TITLE ", "My New Title", field); + + field = (FieldTitle) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_TITLE, " TITLE \"My New Title\"", "My New Title", field); + Assert.assertEquals("My New Title", field.getText()); + } + + //ExStart + //ExFor:FieldToa + //ExFor:FieldToa.BookmarkName + //ExFor:FieldToa.EntryCategory + //ExFor:FieldToa.EntrySeparator + //ExFor:FieldToa.PageNumberListSeparator + //ExFor:FieldToa.PageRangeSeparator + //ExFor:FieldToa.RemoveEntryFormatting + //ExFor:FieldToa.SequenceName + //ExFor:FieldToa.SequenceSeparator + //ExFor:FieldToa.UseHeading + //ExFor:FieldToa.UsePassim + //ExFor:FieldTA + //ExFor:FieldTA.EntryCategory + //ExFor:FieldTA.IsBold + //ExFor:FieldTA.IsItalic + //ExFor:FieldTA.LongCitation + //ExFor:FieldTA.PageRangeBookmarkName + //ExFor:FieldTA.ShortCitation + //ExSummary:Shows how to build and customize a table of authorities using TOA and TA fields. + @Test //ExSkip + public void fieldTOA() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a TOA field, which will create an entry for each TA field in the document, + // displaying long citations and page numbers for each entry. + FieldToa fieldToa = (FieldToa) builder.insertField(FieldType.FIELD_TOA, false); + + // Set the entry category for our table. This TOA will now only include TA fields + // that have a matching value in their EntryCategory property. + fieldToa.setEntryCategory("1"); + + // Moreover, the Table of Authorities category at index 1 is "Cases", + // which will show up as our table's title if we set this variable to true. + fieldToa.setUseHeading(true); + + // We can further filter TA fields by naming a bookmark that they will need to be within the TOA bounds. + fieldToa.setBookmarkName("MyBookmark"); + + // By default, a dotted line page-wide tab appears between the TA field's citation + // and its page number. We can replace it with any text we put on this property. + // Inserting a tab character will preserve the original tab. + fieldToa.setEntrySeparator(" \t p."); + + // If we have multiple TA entries that share the same long citation, + // all their respective page numbers will show up on one row. + // We can use this property to specify a string that will separate their page numbers. + fieldToa.setPageNumberListSeparator(" & p. "); + + // We can set this to true to get our table to display the word "passim" + // if there are five or more page numbers in one row. + fieldToa.setUsePassim(true); + + // One TA field can refer to a range of pages. + // We can specify a string here to appear between the start and end page numbers for such ranges. + fieldToa.setPageRangeSeparator(" to "); + + // The format from the TA fields will carry over into our table. + // We can disable this by setting the RemoveEntryFormatting flag. + fieldToa.setRemoveEntryFormatting(true); + builder.getFont().setColor(Color.GREEN); + builder.getFont().setName("Arial Black"); + + Assert.assertEquals(fieldToa.getFieldCode(), " TOA \\c 1 \\h \\b MyBookmark \\e \" \t p.\" \\l \" & p. \" \\p \\g \" to \" \\f"); + + builder.insertBreak(BreakType.PAGE_BREAK); + + // This TA field will not appear as an entry in the TOA since it is outside + // the bookmark's bounds that the TOA's BookmarkName property specifies. + FieldTA fieldTA = insertToaEntry(builder, "1", "Source 1"); + + Assert.assertEquals(fieldTA.getFieldCode(), " TA \\c 1 \\l \"Source 1\""); + + // This TA field is inside the bookmark, + // but the entry category does not match that of the table, so the TA field will not include it. + builder.startBookmark("MyBookmark"); + fieldTA = insertToaEntry(builder, "2", "Source 2"); + + // This entry will appear in the table. + fieldTA = insertToaEntry(builder, "1", "Source 3"); + + // A TOA table does not display short citations, + // but we can use them as a shorthand to refer to bulky source names that multiple TA fields reference. + fieldTA.setShortCitation("S.3"); + + Assert.assertEquals(fieldTA.getFieldCode(), " TA \\c 1 \\l \"Source 3\" \\s S.3"); + + // We can format the page number to make it bold/italic using the following properties. + // We will still see these effects if we set our table to ignore formatting. + fieldTA = insertToaEntry(builder, "1", "Source 2"); + fieldTA.isBold(true); + fieldTA.isItalic(true); + + Assert.assertEquals(fieldTA.getFieldCode(), " TA \\c 1 \\l \"Source 2\" \\b \\i"); + + // We can configure TA fields to get their TOA entries to refer to a range of pages that a bookmark spans across. + // Note that this entry refers to the same source as the one above to share one row in our table. + // This row will have the page number of the entry above and the page range of this entry, + // with the table's page list and page number range separators between page numbers. + fieldTA = insertToaEntry(builder, "1", "Source 3"); + fieldTA.setPageRangeBookmarkName("MyMultiPageBookmark"); + + builder.startBookmark("MyMultiPageBookmark"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.endBookmark("MyMultiPageBookmark"); + + Assert.assertEquals(fieldTA.getFieldCode(), " TA \\c 1 \\l \"Source 3\" \\r MyMultiPageBookmark"); + + // If we have enabled the "Passim" feature of our table, having 5 or more TA entries with the same source will invoke it. + for (int i = 0; i < 5; i++) { + insertToaEntry(builder, "1", "Source 4"); + } + + builder.endBookmark("MyBookmark"); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.TOA.TA.docx"); + testFieldTOA(new Document(getArtifactsDir() + "Field.TOA.TA.docx")); //ExSKip + } + + private static FieldTA insertToaEntry(DocumentBuilder builder, String entryCategory, String longCitation) throws Exception { + FieldTA field = (FieldTA) builder.insertField(FieldType.FIELD_TOA_ENTRY, false); + field.setEntryCategory(entryCategory); + field.setLongCitation(longCitation); + + builder.insertBreak(BreakType.PAGE_BREAK); + + return field; + } + //ExEnd + + private void testFieldTOA(Document doc) throws Exception + { + FieldToa fieldTOA = (FieldToa) doc.getRange().getFields().get(0); + + Assert.assertEquals("1", fieldTOA.getEntryCategory()); + Assert.assertTrue(fieldTOA.getUseHeading()); + Assert.assertEquals("MyBookmark", fieldTOA.getBookmarkName()); + Assert.assertEquals(" \t p.", fieldTOA.getEntrySeparator()); + Assert.assertEquals(" & p. ", fieldTOA.getPageNumberListSeparator()); + Assert.assertTrue(fieldTOA.getUsePassim()); + Assert.assertEquals(" to ", fieldTOA.getPageRangeSeparator()); + Assert.assertTrue(fieldTOA.getRemoveEntryFormatting()); + Assert.assertEquals(" TOA \\c 1 \\h \\b MyBookmark \\e \" \t p.\" \\l \" & p. \" \\p \\g \" to \" \\f", fieldTOA.getFieldCode()); + Assert.assertEquals("Cases\r" + + "Source 2 \t p.5\r" + + "Source 3 \t p.4 & p. 7 to 10\r" + + "Source 4 \t p.passim\r", fieldTOA.getResult()); + + FieldTA fieldTA = (FieldTA) doc.getRange().getFields().get(1); + + TestUtil.verifyField(FieldType.FIELD_TOA_ENTRY, " TA \\c 1 \\l \"Source 1\"", "", fieldTA); + Assert.assertEquals("1", fieldTA.getEntryCategory()); + Assert.assertEquals("Source 1", fieldTA.getLongCitation()); + + fieldTA = (FieldTA) doc.getRange().getFields().get(2); + + TestUtil.verifyField(FieldType.FIELD_TOA_ENTRY, " TA \\c 2 \\l \"Source 2\"", "", fieldTA); + Assert.assertEquals("2", fieldTA.getEntryCategory()); + Assert.assertEquals("Source 2", fieldTA.getLongCitation()); + + fieldTA = (FieldTA) doc.getRange().getFields().get(3); + + TestUtil.verifyField(FieldType.FIELD_TOA_ENTRY, " TA \\c 1 \\l \"Source 3\" \\s S.3", "", fieldTA); + Assert.assertEquals("1", fieldTA.getEntryCategory()); + Assert.assertEquals("Source 3", fieldTA.getLongCitation()); + Assert.assertEquals("S.3", fieldTA.getShortCitation()); + + fieldTA = (FieldTA) doc.getRange().getFields().get(4); + + TestUtil.verifyField(FieldType.FIELD_TOA_ENTRY, " TA \\c 1 \\l \"Source 2\" \\b \\i", "", fieldTA); + Assert.assertEquals("1", fieldTA.getEntryCategory()); + Assert.assertEquals("Source 2", fieldTA.getLongCitation()); + Assert.assertTrue(fieldTA.isBold()); + Assert.assertTrue(fieldTA.isItalic()); + + fieldTA = (FieldTA) doc.getRange().getFields().get(5); + + TestUtil.verifyField(FieldType.FIELD_TOA_ENTRY, " TA \\c 1 \\l \"Source 3\" \\r MyMultiPageBookmark", "", fieldTA); + Assert.assertEquals("1", fieldTA.getEntryCategory()); + Assert.assertEquals("Source 3", fieldTA.getLongCitation()); + Assert.assertEquals("MyMultiPageBookmark", fieldTA.getPageRangeBookmarkName()); + + for (int i = 6; i < 11; i++) { + fieldTA = (FieldTA) doc.getRange().getFields().get(i); + + TestUtil.verifyField(FieldType.FIELD_TOA_ENTRY, " TA \\c 1 \\l \"Source 4\"", "", fieldTA); + Assert.assertEquals("1", fieldTA.getEntryCategory()); + Assert.assertEquals("Source 4", fieldTA.getLongCitation()); + } + } + + @Test + public void fieldAddIn() throws Exception { + //ExStart + //ExFor:FieldAddIn + //ExSummary:Shows how to process an ADDIN field. + Document doc = new Document(getMyDir() + "Field sample - ADDIN.docx"); + + // Aspose.Words does not support inserting ADDIN fields, but we can still load and read them. + FieldAddIn field = (FieldAddIn) doc.getRange().getFields().get(0); + + Assert.assertEquals(" ADDIN \"My value\" ", field.getFieldCode()); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + + TestUtil.verifyField(FieldType.FIELD_ADDIN, " ADDIN \"My value\" ", "", doc.getRange().getFields().get(0)); + } + + @Test + public void fieldEditTime() throws Exception { + //ExStart + //ExFor:FieldEditTime + //ExSummary:Shows how to use the EDITTIME field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // The EDITTIME field will show, in minutes, + // the time spent with the document open in a Microsoft Word window. + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.write("You've been editing this document for "); + FieldEditTime field = (FieldEditTime) builder.insertField(FieldType.FIELD_EDIT_TIME, true); + builder.writeln(" minutes."); + + // This built in document property tracks the minutes. Microsoft Word uses this property + // to track the time spent with the document open. We can also edit it ourselves. + doc.getBuiltInDocumentProperties().setTotalEditingTime(10); + field.update(); + + Assert.assertEquals(field.getFieldCode(), " EDITTIME "); + Assert.assertEquals(field.getResult(), "10"); + + // The field does not update itself in real-time, and will also have to be + // manually updated in Microsoft Word anytime we need an accurate value. + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.EDITTIME.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.EDITTIME.docx"); + + Assert.assertEquals(10, doc.getBuiltInDocumentProperties().getTotalEditingTime()); + + TestUtil.verifyField(FieldType.FIELD_EDIT_TIME, " EDITTIME ", "10", doc.getRange().getFields().get(0)); + } + + //ExStart + //ExFor:FieldEQ + //ExSummary:Shows how to use the EQ field to display a variety of mathematical equations. + @Test //ExSkip + public void fieldEQ() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // An EQ field displays a mathematical equation consisting of one or many elements. + // Each element takes the following form: [switch][options][arguments]. + // There may be one switch, and several possible options. + // The arguments are a set of coma-separated values enclosed by round braces. + + // Here we use a document builder to insert an EQ field, with an "\f" switch, which corresponds to "Fraction". + // We will pass values 1 and 4 as arguments, and we will not use any options. + // This field will display a fraction with 1 as the numerator and 4 as the denominator. + FieldEQ field = insertFieldEQ(builder, "\\f(1,4)"); + + Assert.assertEquals(" EQ \\f(1,4)", field.getFieldCode()); + + // One EQ field may contain multiple elements placed sequentially. + // We can also nest elements inside one another by placing the inner elements + // inside the argument brackets of outer elements. + // We can find the full list of switches, along with their uses here: + // https://blogs.msdn.microsoft.com/murrays/2018/01/23/microsoft-word-eq-field/ + + // Below are applications of nine different EQ field switches that we can use to create different kinds of objects. + // 1 - Array switch "\a", aligned left, 2 columns, 3 points of horizontal and vertical spacing: + insertFieldEQ(builder, "\\a \\al \\co2 \\vs3 \\hs3(4x,- 4y,-4x,+ y)"); + + // 2 - Bracket switch "\b", bracket character "[", to enclose the contents in a set of square braces: + // Note that we are nesting an array inside the brackets, which will altogether look like a matrix in the output. + insertFieldEQ(builder, "\\b \\bc\\[ (\\a \\al \\co3 \\vs3 \\hs3(1,0,0,0,1,0,0,0,1))"); + + // 3 - Displacement switch "\d", displacing text "B" 30 spaces to the right of "A", displaying the gap as an underline: + insertFieldEQ(builder, "A \\d \\fo30 \\li() B"); + + // 4 - Formula consisting of multiple fractions: + insertFieldEQ(builder, "\\f(d,dx)(u + v) = \\f(du,dx) + \\f(dv,dx)"); + + // 5 - Integral switch "\i", with a summation symbol: + insertFieldEQ(builder, "\\i \\su(n=1,5,n)"); + + // 6 - List switch "\l": + insertFieldEQ(builder, "\\l(1,1,2,3,n,8,13)"); + + // 7 - Radical switch "\r", displaying a cubed root of x: + insertFieldEQ(builder, "\\r (3,x)"); + + // 8 - Subscript/superscript switch "/s", first as a superscript and then as a subscript: + insertFieldEQ(builder, "\\s \\up8(Superscript) Text \\s \\do8(Subscript)"); + + // 9 - Box switch "\x", with lines at the top, bottom, left and right of the input: + insertFieldEQ(builder, "\\x \\to \\bo \\le \\ri(5)"); + + // Some more complex combinations. + insertFieldEQ(builder, "\\a \\ac \\vs1 \\co1(lim,n→∞) \\b (\\f(n,n2 + 12) + \\f(n,n2 + 22) + ... + \\f(n,n2 + n2))"); + insertFieldEQ(builder, "\\i (,, \\b(\\f(x,x2 + 3x + 2))) \\s \\up10(2)"); + insertFieldEQ(builder, "\\i \\in( tan x, \\s \\up2(sec x), \\b(\\r(3) )\\s \\up4(t) \\s \\up7(2) dt)"); + + doc.save(getArtifactsDir() + "Field.EQ.docx"); + testFieldEQ(new Document(getArtifactsDir() + "Field.EQ.docx")); //ExSkip + } + + /// <summary> + /// Use a document builder to insert an EQ field, set its arguments and start a new paragraph. + /// </summary> + private static FieldEQ insertFieldEQ(DocumentBuilder builder, String args) throws Exception { + FieldEQ field = (FieldEQ) builder.insertField(FieldType.FIELD_EQUATION, true); + builder.moveTo(field.getSeparator()); + builder.write(args); + builder.moveTo(field.getStart().getParentNode()); + + builder.insertParagraph(); + return field; + } + //ExEnd + + private void testFieldEQ(Document doc) throws Exception { + TestUtil.verifyField(FieldType.FIELD_EQUATION, " EQ \\f(1,4)", "", doc.getRange().getFields().get(0)); + TestUtil.verifyField(FieldType.FIELD_EQUATION, " EQ \\a \\al \\co2 \\vs3 \\hs3(4x,- 4y,-4x,+ y)", "", doc.getRange().getFields().get(1)); + TestUtil.verifyField(FieldType.FIELD_EQUATION, " EQ \\b \\bc\\[ (\\a \\al \\co3 \\vs3 \\hs3(1,0,0,0,1,0,0,0,1))", "", doc.getRange().getFields().get(2)); + TestUtil.verifyField(FieldType.FIELD_EQUATION, " EQ A \\d \\fo30 \\li() B", "", doc.getRange().getFields().get(3)); + TestUtil.verifyField(FieldType.FIELD_EQUATION, " EQ \\f(d,dx)(u + v) = \\f(du,dx) + \\f(dv,dx)", "", doc.getRange().getFields().get(4)); + TestUtil.verifyField(FieldType.FIELD_EQUATION, " EQ \\i \\su(n=1,5,n)", "", doc.getRange().getFields().get(5)); + TestUtil.verifyField(FieldType.FIELD_EQUATION, " EQ \\l(1,1,2,3,n,8,13)", "", doc.getRange().getFields().get(6)); + TestUtil.verifyField(FieldType.FIELD_EQUATION, " EQ \\r (3,x)", "", doc.getRange().getFields().get(7)); + TestUtil.verifyField(FieldType.FIELD_EQUATION, " EQ \\s \\up8(Superscript) Text \\s \\do8(Subscript)", "", doc.getRange().getFields().get(8)); + TestUtil.verifyField(FieldType.FIELD_EQUATION, " EQ \\x \\to \\bo \\le \\ri(5)", "", doc.getRange().getFields().get(9)); + TestUtil.verifyField(FieldType.FIELD_EQUATION, " EQ \\a \\ac \\vs1 \\co1(lim,n→∞) \\b (\\f(n,n2 + 12) + \\f(n,n2 + 22) + ... + \\f(n,n2 + n2))", "", doc.getRange().getFields().get(10)); + TestUtil.verifyField(FieldType.FIELD_EQUATION, " EQ \\i (,, \\b(\\f(x,x2 + 3x + 2))) \\s \\up10(2)", "", doc.getRange().getFields().get(11)); + TestUtil.verifyField(FieldType.FIELD_EQUATION, " EQ \\i \\in( tan x, \\s \\up2(sec x), \\b(\\r(3) )\\s \\up4(t) \\s \\up7(2) dt)", "", doc.getRange().getFields().get(12)); + TestUtil.verifyWebResponseStatusCode(200, new URL("https://blogs.msdn.microsoft.com/murrays/2018/01/23/microsoft-word-eq-field/")); + } + + @Test + public void fieldEQAsOfficeMath() throws Exception + { + //ExStart + //ExFor:FieldEQ + //ExFor:FieldEQ.AsOfficeMath + //ExSummary:Shows how to replace the EQ field with Office Math. + Document doc = new Document(getMyDir() + "Field sample - EQ.docx"); + FieldCollection fields = doc.getRange().getFields(); + + for (Field field : fields) { + if (field.getType() == FieldType.FIELD_EQUATION) { + FieldEQ fieldEQ = (FieldEQ) field; + OfficeMath officeMath = fieldEQ.asOfficeMath(); + + fieldEQ.getStart().getParentNode().insertBefore(officeMath, fieldEQ.getStart()); + fieldEQ.remove(); + } + } + + doc.save(getArtifactsDir() + "Field.EQAsOfficeMath.docx"); + //ExEnd + } + + @Test + public void fieldForms() throws Exception + { + //ExStart + //ExFor:FieldFormCheckBox + //ExFor:FieldFormDropDown + //ExFor:FieldFormText + //ExSummary:Shows how to process FORMCHECKBOX, FORMDROPDOWN and FORMTEXT fields. + // These fields are legacy equivalents of the FormField. We can read, but not create these fields using Aspose.Words. + // In Microsoft Word, we can insert these fields via the Legacy Tools menu in the Developer tab. + Document doc = new Document(getMyDir() + "Form fields.docx"); + + FieldFormCheckBox fieldFormCheckBox = (FieldFormCheckBox) doc.getRange().getFields().get(1); + Assert.assertEquals(" FORMCHECKBOX \u0001", fieldFormCheckBox.getFieldCode()); + + FieldFormDropDown fieldFormDropDown = (FieldFormDropDown) doc.getRange().getFields().get(2); + Assert.assertEquals(" FORMDROPDOWN \u0001", fieldFormDropDown.getFieldCode()); + + FieldFormText fieldFormText = (FieldFormText) doc.getRange().getFields().get(0); + Assert.assertEquals(" FORMTEXT \u0001", fieldFormText.getFieldCode()); + //ExEnd + } + + @Test + public void fieldFormula() throws Exception { + //ExStart + //ExFor:FieldFormula + //ExSummary:Shows how to use the formula field to display the result of an equation. + Document doc = new Document(); + + // Use a field builder to construct a mathematical equation, + // then create a formula field to display the equation's result in the document. + FieldBuilder fieldBuilder = new FieldBuilder(FieldType.FIELD_FORMULA); + fieldBuilder.addArgument(2); + fieldBuilder.addArgument("*"); + fieldBuilder.addArgument(5); + + FieldFormula field = (FieldFormula) fieldBuilder.buildAndInsert(doc.getFirstSection().getBody().getFirstParagraph()); + field.update(); + + Assert.assertEquals(field.getFieldCode(), " = 2 * 5 "); + Assert.assertEquals(field.getResult(), "10"); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.FORMULA.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.FORMULA.docx"); + + TestUtil.verifyField(FieldType.FIELD_FORMULA, " = 2 * 5 ", "10", doc.getRange().getFields().get(0)); + } + + @Test + public void fieldLastSavedBy() throws Exception { + //ExStart + //ExFor:FieldLastSavedBy + //ExSummary:Shows how to use the LASTSAVEDBY field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // If we create a document in Microsoft Word, it will have the user's name in the "Last saved by" built-in property. + // If we make a document programmatically, this property will be null, and we will need to assign a value. + doc.getBuiltInDocumentProperties().setLastSavedBy("John Doe"); + + // We can use the LASTSAVEDBY field to display the value of this property in the document. + FieldLastSavedBy field = (FieldLastSavedBy) builder.insertField(FieldType.FIELD_LAST_SAVED_BY, true); + + Assert.assertEquals(" LASTSAVEDBY ", field.getFieldCode()); + Assert.assertEquals("John Doe", field.getResult()); + + doc.save(getArtifactsDir() + "Field.LASTSAVEDBY.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.LASTSAVEDBY.docx"); + + Assert.assertEquals("John Doe", doc.getBuiltInDocumentProperties().getLastSavedBy()); + TestUtil.verifyField(FieldType.FIELD_LAST_SAVED_BY, " LASTSAVEDBY ", "John Doe", doc.getRange().getFields().get(0)); + } + + @Test + public void fieldMergeRec() throws Exception { + //ExStart + //ExFor:FieldMergeRec + //ExFor:FieldMergeSeq + //ExFor:FieldSkipIf + //ExFor:FieldSkipIf.ComparisonOperator + //ExFor:FieldSkipIf.LeftExpression + //ExFor:FieldSkipIf.RightExpression + //ExSummary:Shows how to use MERGEREC and MERGESEQ fields to the number and count mail merge records in a mail merge's output documents. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Dear "); + FieldMergeField fieldMergeField = (FieldMergeField) builder.insertField(FieldType.FIELD_MERGE_FIELD, true); + fieldMergeField.setFieldName("Name"); + builder.writeln(","); + + // A MERGEREC field will print the row number of the data being merged in every merge output document. + builder.write("\nRow number of record in data source: "); + FieldMergeRec fieldMergeRec = (FieldMergeRec) builder.insertField(FieldType.FIELD_MERGE_REC, true); + + Assert.assertEquals(fieldMergeRec.getFieldCode(), " MERGEREC "); + + // A MERGESEQ field will count the number of successful merges and print the current value on each respective page. + // If a mail merge skips no rows and invokes no SKIP/SKIPIF/NEXT/NEXTIF fields, then all merges are successful. + // The MERGESEQ and MERGEREC fields will display the same results of their mail merge was successful. + builder.write("\nSuccessful merge number: "); + FieldMergeSeq fieldMergeSeq = (FieldMergeSeq) builder.insertField(FieldType.FIELD_MERGE_SEQ, true); + + Assert.assertEquals(fieldMergeSeq.getFieldCode(), " MERGESEQ "); + + // Insert a SKIPIF field, which will skip a merge if the name is "John Doe". + FieldSkipIf fieldSkipIf = (FieldSkipIf) builder.insertField(FieldType.FIELD_SKIP_IF, true); + builder.moveTo(fieldSkipIf.getSeparator()); + fieldMergeField = (FieldMergeField) builder.insertField(FieldType.FIELD_MERGE_FIELD, true); + fieldMergeField.setFieldName("Name"); + fieldSkipIf.setLeftExpression("="); + fieldSkipIf.setRightExpression("John Doe"); + + // Create a data source with 3 rows, one of them having "John Doe" as a value for the "Name" column. + // Since a SKIPIF field will be triggered once by that value, the output of our mail merge will have 2 pages instead of 3. + // On page 1, the MERGESEQ and MERGEREC fields will both display "1". + // On page 2, the MERGEREC field will display "3" and the MERGESEQ field will display "2". + DataTable table = new DataTable("Employees"); + table.getColumns().add("Name"); + table.getRows().add("Jane Doe"); + table.getRows().add("John Doe"); + table.getRows().add("Joe Bloggs"); + + doc.getMailMerge().execute(table); + doc.save(getArtifactsDir() + "Field.MERGEREC.MERGESEQ.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.MERGEREC.MERGESEQ.docx"); + + Assert.assertEquals(0, doc.getRange().getFields().getCount()); + + Assert.assertEquals("Dear Jane Doe,\r" + + "\r" + + "Row number of record in data source: 1\r" + + "Successful merge number: 1\fDear Joe Bloggs,\r" + + "\r" + + "Row number of record in data source: 3\r" + + "Successful merge number: 2", doc.getText().trim()); + } + + @Test + public void fieldOcx() throws Exception { + //ExStart + //ExFor:FieldOcx + //ExSummary:Shows how to insert an OCX field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + FieldOcx field = (FieldOcx) builder.insertField(FieldType.FIELD_OCX, true); + + Assert.assertEquals(field.getFieldCode(), " OCX "); + //ExEnd + + TestUtil.verifyField(FieldType.FIELD_OCX, " OCX ", "", field); + } + + //ExStart + //ExFor:Field.Remove + //ExFor:FieldPrivate + //ExSummary:Shows how to process PRIVATE fields. + @Test //ExSkip + public void fieldPrivate() throws Exception { + // Open a Corel WordPerfect document which we have converted to .docx format. + Document doc = new Document(getMyDir() + "Field sample - PRIVATE.docx"); + + // WordPerfect 5.x/6.x documents like the one we have loaded may contain PRIVATE fields. + // Microsoft Word preserves PRIVATE fields during load/save operations, + // but provides no functionality for them. + FieldPrivate field = (FieldPrivate) doc.getRange().getFields().get(0); + + Assert.assertEquals(" PRIVATE \"My value\" ", field.getFieldCode()); + Assert.assertEquals(FieldType.FIELD_PRIVATE, field.getType()); + + // We can also insert PRIVATE fields using a document builder. + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertField(FieldType.FIELD_PRIVATE, true); + + // These fields are not a viable way of protecting sensitive information. + // Unless backward compatibility with older versions of WordPerfect is essential, + // we can safely remove these fields. We can do this using a DocumentVisiitor implementation. + Assert.assertEquals(2, doc.getRange().getFields().getCount()); + + FieldPrivateRemover remover = new FieldPrivateRemover(); + doc.accept(remover); + + Assert.assertEquals(remover.getFieldsRemovedCount(), 2); + Assert.assertEquals(doc.getRange().getFields().getCount(), 0); + } + + /// <summary> + /// Removes all encountered PRIVATE fields. + /// </summary> + public static class FieldPrivateRemover extends DocumentVisitor { + public FieldPrivateRemover() { + mFieldsRemovedCount = 0; + } + + public int getFieldsRemovedCount() { + return mFieldsRemovedCount; + } + + /// <summary> + /// Called when a FieldEnd node is encountered in the document. + /// If the node belongs to a PRIVATE field, the entire field is removed. + /// </summary> + public int visitFieldEnd(final FieldEnd fieldEnd) throws Exception { + if (fieldEnd.getFieldType() == FieldType.FIELD_PRIVATE) { + fieldEnd.getField().remove(); + mFieldsRemovedCount++; + } + + return VisitorAction.CONTINUE; + } + + private int mFieldsRemovedCount; + } + //ExEnd + + @Test + public void fieldSection() throws Exception { + //ExStart + //ExFor:FieldSection + //ExFor:FieldSectionPages + //ExSummary:Shows how to use SECTION and SECTIONPAGES fields to number pages by sections. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.RIGHT); + + // A SECTION field displays the number of the section it is in. + builder.write("Section "); + FieldSection fieldSection = (FieldSection) builder.insertField(FieldType.FIELD_SECTION, true); + + Assert.assertEquals(fieldSection.getFieldCode(), " SECTION "); + + // A PAGE field displays the number of the page it is in. + builder.write("\nPage "); + FieldPage fieldPage = (FieldPage) builder.insertField(FieldType.FIELD_PAGE, true); + + Assert.assertEquals(fieldPage.getFieldCode(), " PAGE "); + + // A SECTIONPAGES field displays the number of pages that the section it is in spans across. + builder.write(" of "); + FieldSectionPages fieldSectionPages = (FieldSectionPages) builder.insertField(FieldType.FIELD_SECTION_PAGES, true); + + Assert.assertEquals(fieldSectionPages.getFieldCode(), " SECTIONPAGES "); + + // Move out of the header back into the main document and insert two pages. + // All these pages will be in the first section. Our fields, which appear once every header, + // will number the current/total pages of this section. + builder.moveToDocumentEnd(); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.insertBreak(BreakType.PAGE_BREAK); + + // We can insert a new section with the document builder like this. + // This will affect the values displayed in the SECTION and SECTIONPAGES fields in all upcoming headers. + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + + // The PAGE field will keep counting pages across the whole document. + // We can manually reset its count at each section to keep track of pages section-by-section. + builder.getCurrentSection().getPageSetup().setRestartPageNumbering(true); + builder.insertBreak(BreakType.PAGE_BREAK); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Field.SECTION.SECTIONPAGES.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.SECTION.SECTIONPAGES.docx"); + + TestUtil.verifyField(FieldType.FIELD_SECTION, " SECTION ", "2", doc.getRange().getFields().get(0)); + TestUtil.verifyField(FieldType.FIELD_PAGE, " PAGE ", "2", doc.getRange().getFields().get(1)); + TestUtil.verifyField(FieldType.FIELD_SECTION_PAGES, " SECTIONPAGES ", "2", doc.getRange().getFields().get(2)); + } + + //ExStart + //ExFor:FieldTime + //ExSummary:Shows how to display the current time using the TIME field. + @Test //ExSkip + public void fieldTime() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // By default, time is displayed in the "h:mm am/pm" format. + FieldTime field = insertFieldTime(builder, ""); + + Assert.assertEquals(" TIME ", field.getFieldCode()); + + // We can use the \@ flag to change the format of our displayed time. + field = insertFieldTime(builder, "\\@ HHmm"); + + Assert.assertEquals(" TIME \\@ HHmm", field.getFieldCode()); + + // We can adjust the format to get TIME field to also display the date, according to the Gregorian calendar. + field = insertFieldTime(builder, "\\@ \"M/d/yyyy h mm:ss am/pm\""); + Assert.assertEquals(field.getFieldCode(), " TIME \\@ \"M/d/yyyy h mm:ss am/pm\""); + + doc.save(getArtifactsDir() + "Field.TIME.docx"); + testFieldTime(new Document(getArtifactsDir() + "Field.TIME.docx")); //ExSkip + } + + /// <summary> + /// Use a document builder to insert a TIME field, insert a new paragraph and return the field. + /// </summary> + private FieldTime insertFieldTime(final DocumentBuilder builder, final String format) throws Exception { + FieldTime field = (FieldTime) builder.insertField(FieldType.FIELD_TIME, true); + builder.moveTo(field.getSeparator()); + builder.write(format); + builder.moveTo(field.getStart().getParentNode()); + + builder.insertParagraph(); + return field; + } + //ExEnd + + private void testFieldTime(Document doc) throws Exception { + String docLoadingTime = LocalTime.now().format(DateTimeFormatter.ofPattern("h:mm a")); + doc = DocumentHelper.saveOpen(doc); + + FieldTime field = (FieldTime) doc.getRange().getFields().get(0); + + Assert.assertEquals(" TIME ", field.getFieldCode()); + Assert.assertEquals(FieldType.FIELD_TIME, field.getType()); + Assert.assertEquals(field.getResult(), docLoadingTime); + + field = (FieldTime) doc.getRange().getFields().get(1); + + Assert.assertEquals(" TIME \\@ HHmm", field.getFieldCode()); + Assert.assertEquals(FieldType.FIELD_TIME, field.getType()); + Assert.assertEquals(field.getResult(), docLoadingTime); + + field = (FieldTime) doc.getRange().getFields().get(2); + + Assert.assertEquals(" TIME \\@ \"M/d/yyyy h mm:ss am/pm\"", field.getFieldCode()); + Assert.assertEquals(FieldType.FIELD_TIME, field.getType()); + Assert.assertEquals(field.getResult(), docLoadingTime); + } + + @Test + public void bidiOutline() throws Exception { + //ExStart + //ExFor:FieldBidiOutline + //ExFor:FieldShape + //ExFor:FieldShape.Text + //ExFor:ParagraphFormat.Bidi + //ExSummary:Shows how to create right-to-left language-compatible lists with BIDIOUTLINE fields. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // The BIDIOUTLINE field numbers paragraphs like the AUTONUM/LISTNUM fields, + // but is only visible when a right-to-left editing language is enabled, such as Hebrew or Arabic. + // The following field will display ".1", the RTL equivalent of list number "1.". + FieldBidiOutline field = (FieldBidiOutline) builder.insertField(FieldType.FIELD_BIDI_OUTLINE, true); + builder.writeln("שלום"); + + Assert.assertEquals(" BIDIOUTLINE ", field.getFieldCode()); + + // Add two more BIDIOUTLINE fields, which will display ".2" and ".3". + builder.insertField(FieldType.FIELD_BIDI_OUTLINE, true); + builder.writeln("שלום"); + builder.insertField(FieldType.FIELD_BIDI_OUTLINE, true); + builder.writeln("שלום"); + + // Set the horizontal text alignment for every paragraph in the document to RTL. + for (Paragraph para : (Iterable<Paragraph>) doc.getChildNodes(NodeType.PARAGRAPH, true)) { + para.getParagraphFormat().setBidi(true); + } + + // If we enable a right-to-left editing language in Microsoft Word, our fields will display numbers. + // Otherwise, they will display "###". + doc.save(getArtifactsDir() + "Field.BIDIOUTLINE.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Field.BIDIOUTLINE.docx"); + + for (Field fieldBidiOutline : doc.getRange().getFields()) + TestUtil.verifyField(FieldType.FIELD_BIDI_OUTLINE, " BIDIOUTLINE ", "", fieldBidiOutline); + } + + @Test + public void legacy() throws Exception { + //ExStart + //ExFor:FieldEmbed + //ExFor:FieldShape + //ExFor:FieldShape.Text + //ExSummary:Shows how some older Microsoft Word fields such as SHAPE and EMBED are handled during loading. + // Open a document that was created in Microsoft Word 2003. + Document doc = new Document(getMyDir() + "Legacy fields.doc"); + + // If we open the Word document and press Alt+F9, we will see a SHAPE and an EMBED field. + // A SHAPE field is the anchor/canvas for an AutoShape object with the "In line with text" wrapping style enabled. + // An EMBED field has the same function, but for an embedded object, + // such as a spreadsheet from an external Excel document. + // However, these fields will not appear in the document's Fields collection. + Assert.assertEquals(0, doc.getRange().getFields().getCount()); + + // These fields are supported only by old versions of Microsoft Word. + // The document loading process will convert these fields into Shape objects, + // which we can access in the document's node collection. + NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); + Assert.assertEquals(shapes.getCount(), 3); + + // The first Shape node corresponds to the SHAPE field in the input document, + // which is the inline canvas for the AutoShape. + Shape shape = (Shape) shapes.get(0); + Assert.assertEquals(ShapeType.IMAGE, shape.getShapeType()); + + // The second Shape node is the AutoShape itself. + shape = (Shape) shapes.get(1); + Assert.assertEquals(ShapeType.CAN, shape.getShapeType()); + + // The third Shape is what was the EMBED field that contained the external spreadsheet. + shape = (Shape) shapes.get(2); + Assert.assertEquals(ShapeType.OLE_OBJECT, shape.getShapeType()); + //ExEnd + } + + @Test + public void setFieldIndexFormat() throws Exception { + //ExStart + //ExFor:FieldIndexFormat + //ExFor:FieldOptions.FieldIndexFormat + //ExSummary:Shows how to formatting FieldIndex fields. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.write("A"); + builder.insertBreak(BreakType.LINE_BREAK); + builder.insertField("XE \"A\""); + builder.write("B"); + + builder.insertField(" INDEX \\e \" · \" \\h \"A\" \\c \"2\" \\z \"1033\"", null); + + doc.getFieldOptions().setFieldIndexFormat(FieldIndexFormat.FANCY); + doc.updateFields(); + + doc.save(getArtifactsDir() + "Field.SetFieldIndexFormat.docx"); + //ExEnd + } + + //ExStart + //ExFor:ComparisonEvaluationResult.#ctor(bool) + //ExFor:ComparisonEvaluationResult.#ctor(string) + //ExFor:ComparisonEvaluationResult + //ExFor:ComparisonEvaluationResult.ErrorMessage + //ExFor:ComparisonEvaluationResult.Result + //ExFor:ComparisonExpression + //ExFor:ComparisonExpression.LeftExpression + //ExFor:ComparisonExpression.ComparisonOperator + //ExFor:ComparisonExpression.RightExpression + //ExFor:FieldOptions.ComparisonExpressionEvaluator + //ExFor:IComparisonExpressionEvaluator + //ExFor:IComparisonExpressionEvaluator.Evaluate(Field,ComparisonExpression) + //ExSummary:Shows how to implement custom evaluation for the IF and COMPARE fields. + @Test(dataProvider = "conditionEvaluationExtensionPointDataProvider") //ExSkip + public void conditionEvaluationExtensionPoint(String fieldCode, byte comparisonResult, String comparisonError, + String expectedResult) throws Exception { + final String LEFT = "\"left expression\""; + final String _OPERATOR = "<>"; + final String RIGHT = "\"right expression\""; + + DocumentBuilder builder = new DocumentBuilder(); + + // Field codes that we use in this example: + // 1. " IF %s %s %s \"true argument\" \"false argument\" ". + // 2. " COMPARE %s %s %s ". + Field field = builder.insertField(String.format(fieldCode, LEFT, _OPERATOR, RIGHT), null); + + // If the "comparisonResult" is undefined, we create "ComparisonEvaluationResult" with string, instead of bool. + ComparisonEvaluationResult result = comparisonResult != -1 + ? new ComparisonEvaluationResult(comparisonResult == 1) + : comparisonError != null ? new ComparisonEvaluationResult(comparisonError) : null; + + ComparisonExpressionEvaluator evaluator = new ComparisonExpressionEvaluator(result); + builder.getDocument().getFieldOptions().setComparisonExpressionEvaluator(evaluator); + + builder.getDocument().updateFields(); + + Assert.assertEquals(expectedResult, field.getResult()); + evaluator.assertInvocationsCount(1).assertInvocationArguments(0, LEFT, _OPERATOR, RIGHT); + } + + @DataProvider(name = "conditionEvaluationExtensionPointDataProvider") //ExSkip + public static Object[][] conditionEvaluationExtensionPointDataProvider() { + return new Object[][] + { + {" IF %s %s %s \"true argument\" \"false argument\" ", (byte) 1, null, "true argument"}, + {" IF %s %s %s \"true argument\" \"false argument\" ", (byte) 0, null, "false argument"}, + {" IF %s %s %s \"true argument\" \"false argument\" ", (byte) -1, "Custom Error", "Custom Error"}, + {" IF %s %s %s \"true argument\" \"false argument\" ", (byte) -1, null, "true argument"}, + {" COMPARE %s %s %s ", (byte) 1, null, "1"}, + {" COMPARE %s %s %s ", (byte) 0, null, "0"}, + {" COMPARE %s %s %s ", (byte) -1, "Custom Error", "Custom Error"}, + {" COMPARE %s %s %s ", (byte) -1, null, "1"}, + }; + } + + /// <summary> + /// Comparison expressions evaluation for the FieldIf and FieldCompare. + /// </summary> + private static class ComparisonExpressionEvaluator implements IComparisonExpressionEvaluator { + public ComparisonExpressionEvaluator(ComparisonEvaluationResult result) { + mResult = result; + } + + public ComparisonEvaluationResult evaluate(Field field, ComparisonExpression expression) { + mInvocations.add(new String[] + { + expression.getLeftExpression(), + expression.getComparisonOperator(), + expression.getRightExpression() + }); + + return mResult; + } + + public ComparisonExpressionEvaluator assertInvocationsCount(int expected) { + Assert.assertEquals(expected, mInvocations.size()); + return this; + } + + public ComparisonExpressionEvaluator assertInvocationArguments( + int invocationIndex, + String expectedLeftExpression, + String expectedComparisonOperator, + String expectedRightExpression) { + String[] arguments = mInvocations.get(invocationIndex); + + Assert.assertEquals(expectedLeftExpression, arguments[0]); + Assert.assertEquals(expectedComparisonOperator, arguments[1]); + Assert.assertEquals(expectedRightExpression, arguments[2]); + + return this; + } + + private final ComparisonEvaluationResult mResult; + private final ArrayList<String[]> mInvocations = new ArrayList<>(); + } + //ExEnd + + @Test + public void comparisonExpressionEvaluatorNestedFields() throws Exception { + Document document = new Document(); + + new FieldBuilder(FieldType.FIELD_IF) + .addArgument( + new FieldBuilder(FieldType.FIELD_IF) + .addArgument(123) + .addArgument(">") + .addArgument(666) + .addArgument("left greater than right") + .addArgument("left less than right")) + .addArgument("<>") + .addArgument(new FieldBuilder(FieldType.FIELD_IF) + .addArgument("left expression") + .addArgument("=") + .addArgument("right expression") + .addArgument("expression are equal") + .addArgument("expression are not equal")) + .addArgument(new FieldBuilder(FieldType.FIELD_IF) + .addArgument(new FieldArgumentBuilder() + .addText("#") + .addField(new FieldBuilder(FieldType.FIELD_PAGE))) + .addArgument("=") + .addArgument(new FieldArgumentBuilder() + .addText("#") + .addField(new FieldBuilder(FieldType.FIELD_NUM_PAGES))) + .addArgument("the last page") + .addArgument("not the last page")) + .addArgument(new FieldBuilder(FieldType.FIELD_IF) + .addArgument("unexpected") + .addArgument("=") + .addArgument("unexpected") + .addArgument("unexpected") + .addArgument("unexpected")) + .buildAndInsert(document.getFirstSection().getBody().getFirstParagraph()); + + ComparisonExpressionEvaluator evaluator = new ComparisonExpressionEvaluator(null); + document.getFieldOptions().setComparisonExpressionEvaluator(evaluator); + + document.updateFields(); + + evaluator + .assertInvocationsCount(4) + .assertInvocationArguments(0, "123", ">", "666") + .assertInvocationArguments(1, "\"left expression\"", "=", "\"right expression\"") + .assertInvocationArguments(2, "left less than right", "<>", "expression are not equal") + .assertInvocationArguments(3, "\"#1\"", "=", "\"#1\""); + } + + @Test + public void comparisonExpressionEvaluatorHeaderFooterFields() throws Exception { + Document document = new Document(); + DocumentBuilder builder = new DocumentBuilder(document); + + builder.insertBreak(BreakType.PAGE_BREAK); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + + new FieldBuilder(FieldType.FIELD_IF) + .addArgument(new FieldBuilder(FieldType.FIELD_PAGE)) + .addArgument("=") + .addArgument(new FieldBuilder(FieldType.FIELD_NUM_PAGES)) + .addArgument(new FieldArgumentBuilder() + .addField(new FieldBuilder(FieldType.FIELD_PAGE)) + .addText(" / ") + .addField(new FieldBuilder(FieldType.FIELD_NUM_PAGES))) + .addArgument(new FieldArgumentBuilder() + .addField(new FieldBuilder(FieldType.FIELD_PAGE)) + .addText(" / ") + .addField(new FieldBuilder(FieldType.FIELD_NUM_PAGES))) + .buildAndInsert(builder.getCurrentParagraph()); + + ComparisonExpressionEvaluator evaluator = new ComparisonExpressionEvaluator(null); + document.getFieldOptions().setComparisonExpressionEvaluator(evaluator); + + document.updateFields(); + + evaluator + .assertInvocationsCount(3) + .assertInvocationArguments(0, "1", "=", "3") + .assertInvocationArguments(1, "2", "=", "3") + .assertInvocationArguments(2, "3", "=", "3"); + } + + //ExStart + //ExFor:FieldOptions.FieldUpdatingCallback + //ExFor:FieldOptions.FieldUpdatingProgressCallback + //ExFor:IFieldUpdatingCallback + //ExFor:IFieldUpdatingProgressCallback + //ExFor:IFieldUpdatingProgressCallback.Notify(FieldUpdatingProgressArgs) + //ExFor:FieldUpdatingProgressArgs + //ExFor:FieldUpdatingProgressArgs.UpdateCompleted + //ExFor:FieldUpdatingProgressArgs.TotalFieldsCount + //ExFor:FieldUpdatingProgressArgs.UpdatedFieldsCount + //ExFor:IFieldUpdatingCallback.FieldUpdating(Field) + //ExFor:IFieldUpdatingCallback.FieldUpdated(Field) + //ExSummary:Shows how to use callback methods during a field update. + @Test //ExSkip + public void fieldUpdatingCallbackTest() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField(" DATE \\@ \"dddd, d MMMM yyyy\" "); + builder.insertField(" TIME "); + builder.insertField(" REVNUM "); + builder.insertField(" AUTHOR \"John Doe\" "); + builder.insertField(" SUBJECT \"My Subject\" "); + builder.insertField(" QUOTE \"Hello world!\" "); + + FieldUpdatingCallback callback = new FieldUpdatingCallback(); + doc.getFieldOptions().setFieldUpdatingCallback(callback); + + doc.updateFields(); + + Assert.assertTrue(callback.getFieldUpdatedCalls().contains("Updating John Doe")); + } + + /// <summary> + /// Implement this interface if you want to have your own custom methods called during a field update. + /// </summary> + public static class FieldUpdatingCallback implements IFieldUpdatingCallback + { + public FieldUpdatingCallback() + { + mFieldUpdatedCalls = new ArrayList<String>(); + } + + /// <summary> + /// A user defined method that is called just before a field is updated. + /// </summary> + public void /*IFieldUpdatingCallback.*/fieldUpdating(Field field) { + if (field.getType() == FieldType.FIELD_AUTHOR) + { + FieldAuthor fieldAuthor = (FieldAuthor) field; + try { + fieldAuthor.setAuthorName("Updating John Doe"); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /// <summary> + /// A user defined method that is called just after a field is updated. + /// </summary> + public void /*IFieldUpdatingCallback.*/fieldUpdated(Field field) + { + getFieldUpdatedCalls().add(field.getResult()); + } + + public ArrayList<String> getFieldUpdatedCalls() { return mFieldUpdatedCalls; }; + + private ArrayList<String> mFieldUpdatedCalls; + } + //ExEnd + + @Test + public void bibliographySources() throws Exception + { + //ExStart:BibliographySources + //GistId:b9e728d2381f759edd5b31d64c1c4d3f + //ExFor:Document.Bibliography + //ExFor:Bibliography + //ExFor:Bibliography.Sources + //ExFor:Source + //ExFor:Source.#ctor(string, SourceType) + //ExFor:Source.Title + //ExFor:Source.AbbreviatedCaseNumber + //ExFor:Source.AlbumTitle + //ExFor:Source.BookTitle + //ExFor:Source.Broadcaster + //ExFor:Source.BroadcastTitle + //ExFor:Source.CaseNumber + //ExFor:Source.ChapterNumber + //ExFor:Source.City + //ExFor:Source.Comments + //ExFor:Source.ConferenceName + //ExFor:Source.CountryOrRegion + //ExFor:Source.Court + //ExFor:Source.Day + //ExFor:Source.DayAccessed + //ExFor:Source.Department + //ExFor:Source.Distributor + //ExFor:Source.Doi + //ExFor:Source.Edition + //ExFor:Source.Guid + //ExFor:Source.Institution + //ExFor:Source.InternetSiteTitle + //ExFor:Source.Issue + //ExFor:Source.JournalName + //ExFor:Source.Lcid + //ExFor:Source.Medium + //ExFor:Source.Month + //ExFor:Source.MonthAccessed + //ExFor:Source.NumberVolumes + //ExFor:Source.Pages + //ExFor:Source.PatentNumber + //ExFor:Source.PeriodicalTitle + //ExFor:Source.ProductionCompany + //ExFor:Source.PublicationTitle + //ExFor:Source.Publisher + //ExFor:Source.RecordingNumber + //ExFor:Source.RefOrder + //ExFor:Source.Reporter + //ExFor:Source.ShortTitle + //ExFor:Source.SourceType + //ExFor:Source.StandardNumber + //ExFor:Source.StateOrProvince + //ExFor:Source.Station + //ExFor:Source.Tag + //ExFor:Source.Theater + //ExFor:Source.ThesisType + //ExFor:Source.Type + //ExFor:Source.Url + //ExFor:Source.Version + //ExFor:Source.Volume + //ExFor:Source.Year + //ExFor:Source.YearAccessed + //ExFor:Source.Contributors + //ExFor:SourceType + //ExFor:Contributor + //ExFor:ContributorCollection + //ExFor:ContributorCollection.Author + //ExFor:ContributorCollection.Artist + //ExFor:ContributorCollection.BookAuthor + //ExFor:ContributorCollection.Compiler + //ExFor:ContributorCollection.Composer + //ExFor:ContributorCollection.Conductor + //ExFor:ContributorCollection.Counsel + //ExFor:ContributorCollection.Director + //ExFor:ContributorCollection.Editor + //ExFor:ContributorCollection.Interviewee + //ExFor:ContributorCollection.Interviewer + //ExFor:ContributorCollection.Inventor + //ExFor:ContributorCollection.Performer + //ExFor:ContributorCollection.Producer + //ExFor:ContributorCollection.Translator + //ExFor:ContributorCollection.Writer + //ExFor:PersonCollection + //ExFor:PersonCollection.Count + //ExFor:PersonCollection.Item(Int32) + //ExFor:Person.#ctor(string, string, string) + //ExFor:Person + //ExFor:Person.First + //ExFor:Person.Middle + //ExFor:Person.Last + //ExSummary:Shows how to get bibliography sources available in the document. + Document document = new Document(getMyDir() + "Bibliography sources.docx"); + + Bibliography bibliography = document.getBibliography(); + Assert.assertEquals(12, bibliography.getSources().size()); + + // Get default data from bibliography sources. + Collection<Source> sources = bibliography.getSources(); + Source source = (Source)sources.toArray()[0]; + Assert.assertEquals("Book 0 (No LCID)", source.getTitle()); + Assert.assertEquals(SourceType.BOOK, source.getSourceType()); + Assert.assertNull(source.getAbbreviatedCaseNumber()); + Assert.assertNull(source.getAlbumTitle()); + Assert.assertNull(source.getBookTitle()); + Assert.assertNull(source.getBroadcaster()); + Assert.assertNull(source.getBroadcastTitle()); + Assert.assertNull(source.getCaseNumber()); + Assert.assertNull(source.getChapterNumber()); + Assert.assertNull(source.getComments()); + Assert.assertNull(source.getConferenceName()); + Assert.assertNull(source.getCountryOrRegion()); + Assert.assertNull(source.getCourt()); + Assert.assertNull(source.getDay()); + Assert.assertNull(source.getDayAccessed()); + Assert.assertNull(source.getDepartment()); + Assert.assertNull(source.getDistributor()); + Assert.assertNull(source.getDoi()); + Assert.assertNull(source.getEdition()); + Assert.assertNull(source.getGuid()); + Assert.assertNull(source.getInstitution()); + Assert.assertNull(source.getInternetSiteTitle()); + Assert.assertNull(source.getIssue()); + Assert.assertNull(source.getJournalName()); + Assert.assertNull(source.getLcid()); + Assert.assertNull(source.getMedium()); + Assert.assertNull(source.getMonth()); + Assert.assertNull(source.getMonthAccessed()); + Assert.assertNull(source.getNumberVolumes()); + Assert.assertNull(source.getPages()); + Assert.assertNull(source.getPatentNumber()); + Assert.assertNull(source.getPeriodicalTitle()); + Assert.assertNull(source.getProductionCompany()); + Assert.assertNull(source.getPublicationTitle()); + Assert.assertNull(source.getPublisher()); + Assert.assertNull(source.getRecordingNumber()); + Assert.assertNull(source.getRefOrder()); + Assert.assertNull(source.getReporter()); + Assert.assertNull(source.getShortTitle()); + Assert.assertNull(source.getStandardNumber()); + Assert.assertNull(source.getStateOrProvince()); + Assert.assertNull(source.getStation()); + Assert.assertEquals("BookNoLCID", source.getTag()); + Assert.assertNull(source.getTheater()); + Assert.assertNull(source.getThesisType()); + Assert.assertNull(source.getType()); + Assert.assertNull(source.getUrl()); + Assert.assertNull(source.getVersion()); + Assert.assertNull(source.getVolume()); + Assert.assertNull(source.getYear()); + Assert.assertNull(source.getYearAccessed()); + + // Also, you can create a new source. + Source newSource = new Source("New source", SourceType.MISC); + + ContributorCollection contributors = source.getContributors(); + Assert.assertNull(contributors.getArtist()); + Assert.assertNull(contributors.getBookAuthor()); + Assert.assertNull(contributors.getCompiler()); + Assert.assertNull(contributors.getComposer()); + Assert.assertNull(contributors.getConductor()); + Assert.assertNull(contributors.getCounsel()); + Assert.assertNull(contributors.getDirector()); + Assert.assertNotNull(contributors.getEditor()); + Assert.assertNull(contributors.getInterviewee()); + Assert.assertNull(contributors.getInterviewer()); + Assert.assertNull(contributors.getInventor()); + Assert.assertNull(contributors.getPerformer()); + Assert.assertNull(contributors.getProducer()); + Assert.assertNotNull(contributors.getTranslator()); + Assert.assertNull(contributors.getWriter()); + + Contributor editor = contributors.getEditor(); + Assert.assertEquals(2, ((PersonCollection)editor).getCount()); + + PersonCollection authors = (PersonCollection)contributors.getAuthor(); + Assert.assertEquals(2, authors.getCount()); + + Person person = authors.get(0); + Assert.assertEquals("Roxanne", person.getFirst()); + Assert.assertEquals("Brielle", person.getMiddle()); + Assert.assertEquals("Tejeda", person.getLast()); + //ExEnd:BibliographySources + } + + @Test + public void bibliographyPersons() + { + //ExStart + //ExFor:Person.#ctor(string, string, string) + //ExFor:PersonCollection.#ctor + //ExFor:PersonCollection.#ctor(Person[]) + //ExFor:PersonCollection.Add(Person) + //ExFor:PersonCollection.Contains(Person) + //ExFor:PersonCollection.Clear + //ExFor:PersonCollection.Remove(Person) + //ExFor:PersonCollection.RemoveAt(Int32) + //ExSummary:Shows how to work with person collection. + // Create a new person collection. + PersonCollection persons = new PersonCollection(); + Person person = new Person("Roxanne", "Brielle", "Tejeda_updated"); + // Add new person to the collection. + persons.add(person); + Assert.assertEquals(1, persons.getCount()); + // Remove person from the collection if it exists. + if (persons.contains(person)) + persons.remove(person); + Assert.assertEquals(0, persons.getCount()); + + // Create person collection with two persons. + persons = new PersonCollection(new Person[] { new Person("Roxanne_1", "Brielle_1", "Tejeda_1"), new Person("Roxanne_2", "Brielle_2", "Tejeda_2") }); + Assert.assertEquals(2, persons.getCount()); + // Remove person from the collection by the index. + persons.removeAt(0); + Assert.assertEquals(1, persons.getCount()); + // Remove all persons from the collection. + persons.clear(); + Assert.assertEquals(0, persons.getCount()); + //ExEnd + } + + @Test + public void captionlessTableOfFiguresLabel() throws Exception + { + //ExStart + //ExFor:FieldToc.CaptionlessTableOfFiguresLabel + //ExSummary:Shows how to set the name of the sequence identifier. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + FieldToc fieldToc = (FieldToc)builder.insertField(FieldType.FIELD_TOC, true); + fieldToc.setCaptionlessTableOfFiguresLabel("Test"); + + Assert.assertEquals(" TOC \\a Test", fieldToc.getFieldCode()); + //ExEnd + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExFieldOptions.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExFieldOptions.java new file mode 100644 index 00000000..55d0e85f --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExFieldOptions.java @@ -0,0 +1,475 @@ +package Examples; + +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import com.aspose.words.net.System.Globalization.CultureInfo; +import com.aspose.words.net.System.Globalization.DateTimeFormatInfo; +import org.testng.Assert; +import org.testng.annotations.Test; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.util.Locale; + +@Test +public class ExFieldOptions extends ApiExampleBase { + @Test + public void currentUser() throws Exception { + //ExStart + //ExFor:Document.UpdateFields + //ExFor:FieldOptions.CurrentUser + //ExFor:UserInformation + //ExFor:UserInformation.Name + //ExFor:UserInformation.Initials + //ExFor:UserInformation.Address + //ExFor:UserInformation.DefaultUser + //ExSummary:Shows how to set user details, and display them using fields. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a UserInformation object and set it as the data source for fields that display user information. + UserInformation userInformation = new UserInformation(); + userInformation.setName("John Doe"); + userInformation.setInitials("J. D."); + userInformation.setAddress("123 Main Street"); + doc.getFieldOptions().setCurrentUser(userInformation); + + // Insert USERNAME, USERINITIALS, and USERADDRESS fields, which display values of + // the respective properties of the UserInformation object that we have created above. + Assert.assertEquals(userInformation.getName(), builder.insertField(" USERNAME ").getResult()); + Assert.assertEquals(userInformation.getInitials(), builder.insertField(" USERINITIALS ").getResult()); + Assert.assertEquals(userInformation.getAddress(), builder.insertField(" USERADDRESS ").getResult()); + + // The field options object also has a static default user that fields from all documents can refer to. + UserInformation.getDefaultUser().setName("Default User"); + UserInformation.getDefaultUser().setInitials("D. U."); + UserInformation.getDefaultUser().setAddress("One Microsoft Way"); + doc.getFieldOptions().setCurrentUser(UserInformation.getDefaultUser()); + + Assert.assertEquals("Default User", builder.insertField(" USERNAME ").getResult()); + Assert.assertEquals("D. U.", builder.insertField(" USERINITIALS ").getResult()); + Assert.assertEquals("One Microsoft Way", builder.insertField(" USERADDRESS ").getResult()); + + doc.updateFields(); + doc.save(getArtifactsDir() + "FieldOptions.CurrentUser.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "FieldOptions.CurrentUser.docx"); + + Assert.assertNull(doc.getFieldOptions().getCurrentUser()); + + FieldUserName fieldUserName = (FieldUserName) doc.getRange().getFields().get(0); + + Assert.assertNull(fieldUserName.getUserName()); + Assert.assertEquals("Default User", fieldUserName.getResult()); + + FieldUserInitials fieldUserInitials = (FieldUserInitials) doc.getRange().getFields().get(1); + + Assert.assertNull(fieldUserInitials.getUserInitials()); + Assert.assertEquals("D. U.", fieldUserInitials.getResult()); + + FieldUserAddress fieldUserAddress = (FieldUserAddress) doc.getRange().getFields().get(2); + + Assert.assertNull(fieldUserAddress.getUserAddress()); + Assert.assertEquals("One Microsoft Way", fieldUserAddress.getResult()); + } + + @Test + public void fileName() throws Exception { + //ExStart + //ExFor:FieldOptions.FileName + //ExFor:FieldFileName + //ExFor:FieldFileName.IncludeFullPath + //ExSummary:Shows how to use FieldOptions to override the default value for the FILENAME field. + Document doc = new Document(getMyDir() + "Document.docx"); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.moveToDocumentEnd(); + builder.writeln(); + + // This FILENAME field will display the local system file name of the document we loaded. + FieldFileName field = (FieldFileName) builder.insertField(FieldType.FIELD_FILE_NAME, true); + field.update(); + + Assert.assertEquals(" FILENAME ", field.getFieldCode()); + Assert.assertEquals("Document.docx", field.getResult()); + + builder.writeln(); + + // By default, the FILENAME field shows the file's name, but not its full local file system path. + // We can set a flag to make it show the full file path. + field = (FieldFileName) builder.insertField(FieldType.FIELD_FILE_NAME, true); + field.setIncludeFullPath(true); + field.update(); + + Assert.assertEquals(getMyDir() + "Document.docx", field.getResult()); + + // We can also set a value for this property to + // override the value that the FILENAME field displays. + doc.getFieldOptions().setFileName("FieldOptions.FILENAME.docx"); + field.update(); + + Assert.assertEquals(" FILENAME \\p", field.getFieldCode()); + Assert.assertEquals("FieldOptions.FILENAME.docx", field.getResult()); + + doc.updateFields(); + doc.save(getArtifactsDir() + doc.getFieldOptions().getFileName()); + //ExEnd + + doc = new Document(getArtifactsDir() + "FieldOptions.FILENAME.docx"); + + Assert.assertNull(doc.getFieldOptions().getFileName()); + TestUtil.verifyField(FieldType.FIELD_FILE_NAME, " FILENAME ", "FieldOptions.FILENAME.docx", doc.getRange().getFields().get(0)); + } + + @Test + public void bidi() throws Exception { + //ExStart + //ExFor:FieldOptions.IsBidiTextSupportedOnUpdate + //ExSummary:Shows how to use FieldOptions to ensure that field updating fully supports bi-directional text. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Ensure that any field operation involving right-to-left text is performs as expected. + doc.getFieldOptions().isBidiTextSupportedOnUpdate(true); + + // Use a document builder to insert a field that contains the right-to-left text. + FormField comboBox = builder.insertComboBox("MyComboBox", new String[]{"עֶשְׂרִים", "שְׁלוֹשִׁים", "אַרְבָּעִים", "חֲמִשִּׁים", "שִׁשִּׁים"}, 0); + comboBox.setCalculateOnExit(true); + + doc.updateFields(); + doc.save(getArtifactsDir() + "FieldOptions.Bidi.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "FieldOptions.Bidi.docx"); + + Assert.assertFalse(doc.getFieldOptions().isBidiTextSupportedOnUpdate()); + + comboBox = doc.getRange().getFormFields().get(0); + + Assert.assertEquals("עֶשְׂרִים", comboBox.getResult()); + } + + @Test + public void legacyNumberFormat() throws Exception { + //ExStart + //ExFor:FieldOptions.LegacyNumberFormat + //ExSummary:Shows how enable legacy number formatting for fields. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Field field = builder.insertField("= 2 + 3 \\# $##"); + + Assert.assertEquals("$ 5", field.getResult()); + + doc.getFieldOptions().setLegacyNumberFormat(true); + field.update(); + + Assert.assertEquals("$5", field.getResult()); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + + Assert.assertFalse(doc.getFieldOptions().getLegacyNumberFormat()); + TestUtil.verifyField(FieldType.FIELD_FORMULA, "= 2 + 3 \\# $##", "$5", doc.getRange().getFields().get(0)); + } + + @Test + public void preProcessCulture() throws Exception { + //ExStart + //ExFor:FieldOptions.PreProcessCulture + //ExSummary:Shows how to set the preprocess culture. + Document doc = new Document(getMyDir() + "Document.docx"); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Set the culture according to which some fields will format their displayed values. + doc.getFieldOptions().setPreProcessCulture(new CultureInfo("de-DE")); + + Field field = builder.insertField(" DOCPROPERTY CreateTime"); + + // The DOCPROPERTY field will display its result formatted according to the preprocess culture + // we have set to German. The field will display the date/time using the "dd.mm.yyyy hh:mm" format. + Assert.assertTrue(field.getResult().matches("\\d{2}[.]\\d{2}[.]\\d{4} \\d{2}[:]\\d{2}")); + + doc.getFieldOptions().setPreProcessCulture(new CultureInfo(Locale.ROOT)); + field.update(); + + // After switching to the invariant culture, the DOCPROPERTY field will use the "mm/dd/yyyy hh:mm" format. + Assert.assertTrue(field.getResult().matches("\\d{2}[/]\\d{2}[/]\\d{4} \\d{2}[:]\\d{2}")); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + + Assert.assertTrue(doc.getRange().getFields().get(0).getResult().matches("\\d{2}[/]\\d{2}[/]\\d{4} \\d{2}[:]\\d{2}")); + } + + @Test + public void tableOfAuthorityCategories() throws Exception { + //ExStart + //ExFor:FieldOptions.ToaCategories + //ExFor:ToaCategories + //ExFor:ToaCategories.Item(Int32) + //ExFor:ToaCategories.DefaultCategories + //ExSummary:Shows how to specify a set of categories for TOA fields. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // TOA fields can filter their entries by categories defined in this collection. + ToaCategories toaCategories = new ToaCategories(); + doc.getFieldOptions().setToaCategories(toaCategories); + + // This collection of categories comes with default values, which we can overwrite with custom values. + Assert.assertEquals("Cases", toaCategories.get(1)); + Assert.assertEquals("Statutes", toaCategories.get(2)); + + toaCategories.set(1, "My Category 1"); + toaCategories.set(2, "My Category 2"); + + // We can always access the default values via this collection. + Assert.assertEquals("Cases", ToaCategories.getDefaultCategories().get(1)); + Assert.assertEquals("Statutes", ToaCategories.getDefaultCategories().get(2)); + + // Insert 2 TOA fields. TOA fields create an entry for each TA field in the document. + // Use the "\c" switch to select the index of a category from our collection. + // With this switch, a TOA field will only pick up entries from TA fields that + // also have a "\c" switch with a matching category index. Each TOA field will also display + // the name of the category that its "\c" switch points to. + builder.insertField("TOA \\c 1 \\h", null); + builder.insertField("TOA \\c 2 \\h", null); + builder.insertBreak(BreakType.PAGE_BREAK); + + // Insert TOA entries across 2 categories. Our first TOA field will receive one entry, + // from the second TA field whose "\c" switch also points to the first category. + // The second TOA field will have two entries from the other two TA fields. + builder.insertField("TA \\c 2 \\l \"entry 1\""); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.insertField("TA \\c 1 \\l \"entry 2\""); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.insertField("TA \\c 2 \\l \"entry 3\""); + + doc.updateFields(); + doc.save(getArtifactsDir() + "FieldOptions.TOA.Categories.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "FieldOptions.TOA.Categories.docx"); + + Assert.assertNull(doc.getFieldOptions().getToaCategories()); + + TestUtil.verifyField(FieldType.FIELD_TOA, "TOA \\c 1 \\h", "My Category 1\rentry 2\t3\r", doc.getRange().getFields().get(0)); + TestUtil.verifyField(FieldType.FIELD_TOA, "TOA \\c 2 \\h", + "My Category 2\r" + + "entry 1\t2\r" + + "entry 3\t4\r", doc.getRange().getFields().get(1)); + } + + @Test + public void useInvariantCultureNumberFormat() throws Exception { + //ExStart + //ExFor:FieldOptions.UseInvariantCultureNumberFormat + //ExSummary:Shows how to format numbers according to the invariant culture. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Locale.setDefault(new Locale("de-DE")); + Field field = builder.insertField(" = 1234567,89 \\# $#,###,###.##"); + field.update(); + + // Sometimes, fields may not format their numbers correctly under certain cultures. + Assert.assertFalse(doc.getFieldOptions().getUseInvariantCultureNumberFormat()); + Assert.assertEquals("$123,456,789. ", field.getResult()); + + // To fix this, we could change the culture for the entire thread. + // Another way to fix this is to set this flag, + // which gets all fields to use the invariant culture when formatting numbers. + // This way allows us to avoid changing the culture for the entire thread. + doc.getFieldOptions().setUseInvariantCultureNumberFormat(true); + field.update(); + Assert.assertEquals("$123,456,789. ", field.getResult()); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + + Assert.assertFalse(doc.getFieldOptions().getUseInvariantCultureNumberFormat()); + TestUtil.verifyField(FieldType.FIELD_FORMULA, " = 1234567,89 \\# $#,###,###.##", "$123,456,789. ", doc.getRange().getFields().get(0)); + } + + //ExStart + //ExFor:FieldOptions.FieldUpdateCultureProvider + //ExFor:IFieldUpdateCultureProvider + //ExFor:IFieldUpdateCultureProvider.GetCulture(string, Field) + //ExSummary:Shows how to specify a culture which parses date/time formatting for each field. + @Test //ExSkip + public void defineDateTimeFormatting() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField(FieldType.FIELD_TIME, true); + + doc.getFieldOptions().setFieldUpdateCultureSource(FieldUpdateCultureSource.FIELD_CODE); + + // Set a provider that returns a culture object specific to each field. + doc.getFieldOptions().setFieldUpdateCultureProvider(new FieldUpdateCultureProvider()); + + FieldTime fieldDate = (FieldTime) doc.getRange().getFields().get(0); + if (fieldDate.getLocaleId() != EditingLanguage.RUSSIAN) + fieldDate.setLocaleId(EditingLanguage.RUSSIAN); + + doc.save(getArtifactsDir() + "FieldOptions.UpdateDateTimeFormatting.pdf"); + } + + /// <summary> + /// Provides a CultureInfo object that should be used during the update of a particular field. + /// </summary> + private static class FieldUpdateCultureProvider implements IFieldUpdateCultureProvider { + /// <summary> + /// Returns a CultureInfo object to be used during the field's update. + /// </summary> + public CultureInfo getCulture(String name, Field field) { + switch (name) { + case "ru-RU": + CultureInfo culture = new CultureInfo(new Locale(name)); + DateTimeFormatInfo format = culture.getDateTimeFormat(); + + format.setMonthNames(new String[]{"месяц 1", "месяц 2", "месяц 3", "месяц 4", "месяц 5", "месяц 6", "месяц 7", "месяц 8", "месяц 9", "месяц 10", "месяц 11", "месяц 12", ""}); + format.setMonthGenitiveNames(format.getMonthNames()); + format.setAbbreviatedMonthNames(new String[]{"мес 1", "мес 2", "мес 3", "мес 4", "мес 5", "мес 6", "мес 7", "мес 8", "мес 9", "мес 10", "мес 11", "мес 12", ""}); + format.setAbbreviatedMonthGenitiveNames(format.getAbbreviatedMonthNames()); + + format.setDayNames(new String[]{"день недели 7", "день недели 1", "день недели 2", "день недели 3", "день недели 4", "день недели 5", "день недели 6"}); + format.setAbbreviatedDayNames(new String[]{"день 7", "день 1", "день 2", "день 3", "день 4", "день 5", "день 6"}); + format.setShortestDayNames(new String[]{"д7", "д1", "д2", "д3", "д4", "д5", "д6"}); + + format.setAMDesignator("До полудня"); + format.setPMDesignator("После полудня"); + + final String PATTERN = "yyyy MM (MMMM) dd (dddd) hh:mm:ss tt"; + format.setLongDatePattern(PATTERN); + format.setLongTimePattern(PATTERN); + format.setShortDatePattern(PATTERN); + format.setShortTimePattern(PATTERN); + + return culture; + case "en-US": + return new CultureInfo(new Locale(name)); + default: + return null; + } + } + } + //ExEnd + + @Test + public void barcodeGenerator() throws Exception { + //ExStart + //ExFor:BarcodeParameters + //ExFor:BarcodeParameters.AddStartStopChar + //ExFor:BarcodeParameters.BackgroundColor + //ExFor:BarcodeParameters.BarcodeType + //ExFor:BarcodeParameters.BarcodeValue + //ExFor:BarcodeParameters.CaseCodeStyle + //ExFor:BarcodeParameters.DisplayText + //ExFor:BarcodeParameters.ErrorCorrectionLevel + //ExFor:BarcodeParameters.FacingIdentificationMark + //ExFor:BarcodeParameters.FixCheckDigit + //ExFor:BarcodeParameters.ForegroundColor + //ExFor:BarcodeParameters.IsBookmark + //ExFor:BarcodeParameters.IsUSPostalAddress + //ExFor:BarcodeParameters.PosCodeStyle + //ExFor:BarcodeParameters.PostalAddress + //ExFor:BarcodeParameters.ScalingFactor + //ExFor:BarcodeParameters.SymbolHeight + //ExFor:BarcodeParameters.SymbolRotation + //ExFor:IBarcodeGenerator + //ExFor:IBarcodeGenerator.GetBarcodeImage(BarcodeParameters) + //ExFor:IBarcodeGenerator.GetOldBarcodeImage(BarcodeParameters) + //ExFor:FieldOptions.BarcodeGenerator + //ExSummary:Shows how to use a barcode generator. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + Assert.assertNull(doc.getFieldOptions().getBarcodeGenerator()); //ExSkip + + // We can use a custom IBarcodeGenerator implementation to generate barcodes, + // and then insert them into the document as images. + doc.getFieldOptions().setBarcodeGenerator(new CustomBarcodeGenerator()); + + // Below are four examples of different barcode types that we can create using our generator. + // For each barcode, we specify a new set of barcode parameters, and then generate the image. + // Afterwards, we can insert the image into the document, or save it to the local file system. + // 1 - QR code: + BarcodeParameters barcodeParameters = new BarcodeParameters(); + { + barcodeParameters.setBarcodeType("QR"); + barcodeParameters.setBarcodeValue("ABC123"); + barcodeParameters.setBackgroundColor("0xF8BD69"); + barcodeParameters.setForegroundColor("0xB5413B"); + barcodeParameters.setErrorCorrectionLevel("3"); + barcodeParameters.setScalingFactor("250"); + barcodeParameters.setSymbolHeight("1000"); + barcodeParameters.setSymbolRotation("0"); + } + + BufferedImage img = doc.getFieldOptions().getBarcodeGenerator().getBarcodeImage(barcodeParameters); + ImageIO.write(img, "jpg", new File(getArtifactsDir() + "FieldOptions.BarcodeGenerator.QR.jpg")); + + builder.insertImage(img); + + // 2 - EAN13 barcode: + barcodeParameters = new BarcodeParameters(); + { + barcodeParameters.setBarcodeType("EAN13"); + barcodeParameters.setBarcodeValue("501234567890"); + barcodeParameters.setDisplayText(true); + barcodeParameters.setPosCodeStyle("CASE"); + barcodeParameters.setFixCheckDigit(true); + } + + img = doc.getFieldOptions().getBarcodeGenerator().getBarcodeImage(barcodeParameters); + ImageIO.write(img, "jpg", new File(getArtifactsDir() + "FieldOptions.BarcodeGenerator.EAN13.jpg")); + builder.insertImage(img); + + // 3 - CODE39 barcode: + barcodeParameters = new BarcodeParameters(); + { + barcodeParameters.setBarcodeType("CODE39"); + barcodeParameters.setBarcodeValue("12345ABCDE"); + barcodeParameters.setAddStartStopChar(true); + } + + img = doc.getFieldOptions().getBarcodeGenerator().getBarcodeImage(barcodeParameters); + ImageIO.write(img, "jpg", new File(getArtifactsDir() + "FieldOptions.BarcodeGenerator.CODE39.jpg")); + builder.insertImage(img); + + // 4 - ITF14 barcode: + barcodeParameters = new BarcodeParameters(); + { + barcodeParameters.setBarcodeType("ITF14"); + barcodeParameters.setBarcodeValue("09312345678907"); + barcodeParameters.setCaseCodeStyle("STD"); + } + + img = doc.getFieldOptions().getBarcodeGenerator().getBarcodeImage(barcodeParameters); + ImageIO.write(img, "jpg", new File(getArtifactsDir() + "FieldOptions.BarcodeGenerator.ITF14.jpg")); + builder.insertImage(img); + + doc.save(getArtifactsDir() + "FieldOptions.BarcodeGenerator.docx"); + //ExEnd + + TestUtil.verifyImage(223, 223, getArtifactsDir() + "FieldOptions.BarcodeGenerator.QR.jpg"); + TestUtil.verifyImage(127, 118, getArtifactsDir() + "FieldOptions.BarcodeGenerator.EAN13.jpg"); + TestUtil.verifyImage(204, 70, getArtifactsDir() + "FieldOptions.BarcodeGenerator.CODE39.jpg"); + TestUtil.verifyImage(168, 134, getArtifactsDir() + "FieldOptions.BarcodeGenerator.ITF14.jpg"); + + doc = new Document(getArtifactsDir() + "FieldOptions.BarcodeGenerator.docx"); + Shape barcode = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertTrue(barcode.hasImage()); + } +} + diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExFile.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExFile.java new file mode 100644 index 00000000..b33ebec1 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExFile.java @@ -0,0 +1,246 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.io.FileInputStream; +import java.text.MessageFormat; +import java.util.ArrayList; + +@Test +public class ExFile extends ApiExampleBase { + + @Test + public void catchFileCorruptedException() throws Exception { + //ExStart + //ExFor:FileCorruptedException + //ExSummary:Shows how to catch a FileCorruptedException. + try { + // If we get an "Unreadable content" error message when trying to open a document using Microsoft Word, + // chances are that we will get an exception thrown when trying to load that document using Aspose.Words. + Document doc = new Document(getMyDir() + "Corrupted document.docx"); + } catch (FileCorruptedException e) { + System.out.println(e.getMessage()); + } + //ExEnd + } + + @Test + public void detectEncoding() throws Exception { + //ExStart + //ExFor:FileFormatInfo.Encoding + //ExFor:FileFormatUtil + //ExSummary:Shows how to detect encoding in an html file. + FileFormatInfo info = FileFormatUtil.detectFileFormat(getMyDir() + "Document.html"); + + Assert.assertEquals(LoadFormat.HTML, info.getLoadFormat()); + + // The Encoding property is used only when we create a FileFormatInfo object for an html document. + Assert.assertEquals("windows-1252", info.getEncoding().name()); + //ExEnd + + info = FileFormatUtil.detectFileFormat(getMyDir() + "Document.docx"); + + Assert.assertEquals(LoadFormat.DOCX, info.getLoadFormat()); + Assert.assertNull(info.getEncoding()); + } + + @Test + public void fileFormatToString() { + //ExStart + //ExFor:FileFormatUtil.ContentTypeToLoadFormat(String) + //ExFor:FileFormatUtil.ContentTypeToSaveFormat(String) + //ExSummary:Shows how to find the corresponding Aspose load/save format from each media type string. + // The ContentTypeToSaveFormat/ContentTypeToLoadFormat methods only accept official IANA media type names, also known as MIME types. + // All valid media types are listed here: https://www.iana.org/assignments/media-types/media-types.xhtml. + + // Trying to associate a SaveFormat with a partial media type string will not work. + Assert.assertThrows(IllegalArgumentException.class, () -> FileFormatUtil.contentTypeToSaveFormat("jpeg")); + + // If Aspose.Words does not have a corresponding save/load format for a content type, an exception will also be thrown. + Assert.assertThrows(IllegalArgumentException.class, () -> FileFormatUtil.contentTypeToSaveFormat("application/zip")); + + // Files of the types listed below can be saved, but not loaded using Aspose.Words. + Assert.assertThrows(IllegalArgumentException.class, () -> FileFormatUtil.contentTypeToLoadFormat("image/jpeg")); + + Assert.assertEquals(FileFormatUtil.contentTypeToSaveFormat("image/jpeg"), SaveFormat.JPEG); + Assert.assertEquals(FileFormatUtil.contentTypeToSaveFormat("image/png"), SaveFormat.PNG); + Assert.assertEquals(FileFormatUtil.contentTypeToSaveFormat("image/tiff"), SaveFormat.TIFF); + Assert.assertEquals(FileFormatUtil.contentTypeToSaveFormat("image/gif"), SaveFormat.GIF); + Assert.assertEquals(FileFormatUtil.contentTypeToSaveFormat("image/x-emf"), SaveFormat.EMF); + Assert.assertEquals(FileFormatUtil.contentTypeToSaveFormat("application/vnd.ms-xpsdocument"), SaveFormat.XPS); + Assert.assertEquals(FileFormatUtil.contentTypeToSaveFormat("application/pdf"), SaveFormat.PDF); + Assert.assertEquals(FileFormatUtil.contentTypeToSaveFormat("image/svg+xml"), SaveFormat.SVG); + Assert.assertEquals(FileFormatUtil.contentTypeToSaveFormat("application/epub+zip"), SaveFormat.EPUB); + + // For file types that can be saved and loaded, we can match a media type to both a load format and a save format. + Assert.assertEquals(FileFormatUtil.contentTypeToLoadFormat("application/msword"), LoadFormat.DOC); + Assert.assertEquals(FileFormatUtil.contentTypeToSaveFormat("application/msword"), SaveFormat.DOC); + + Assert.assertEquals(FileFormatUtil.contentTypeToLoadFormat("application/vnd.openxmlformats-officedocument.wordprocessingml.document"), LoadFormat.DOCX); + Assert.assertEquals(FileFormatUtil.contentTypeToSaveFormat("application/vnd.openxmlformats-officedocument.wordprocessingml.document"), SaveFormat.DOCX); + + Assert.assertEquals(FileFormatUtil.contentTypeToLoadFormat("text/plain"), LoadFormat.TEXT); + Assert.assertEquals(FileFormatUtil.contentTypeToSaveFormat("text/plain"), SaveFormat.TEXT); + + Assert.assertEquals(FileFormatUtil.contentTypeToLoadFormat("application/rtf"), LoadFormat.RTF); + Assert.assertEquals(FileFormatUtil.contentTypeToSaveFormat("application/rtf"), SaveFormat.RTF); + + Assert.assertEquals(FileFormatUtil.contentTypeToLoadFormat("text/html"), LoadFormat.HTML); + Assert.assertEquals(FileFormatUtil.contentTypeToSaveFormat("text/html"), SaveFormat.HTML); + + Assert.assertEquals(FileFormatUtil.contentTypeToLoadFormat("multipart/related"), LoadFormat.MHTML); + Assert.assertEquals(FileFormatUtil.contentTypeToSaveFormat("multipart/related"), SaveFormat.MHTML); + //ExEnd + } + + @Test + public void detectDocumentEncryption() throws Exception { + //ExStart + //ExFor:FileFormatUtil.DetectFileFormat(String) + //ExFor:FileFormatInfo + //ExFor:FileFormatInfo.LoadFormat + //ExFor:FileFormatInfo.IsEncrypted + //ExSummary:Shows how to use the FileFormatUtil class to detect the document format and encryption. + Document doc = new Document(); + + // Configure a SaveOptions object to encrypt the document + // with a password when we save it, and then save the document. + OdtSaveOptions saveOptions = new OdtSaveOptions(SaveFormat.ODT); + saveOptions.setPassword("MyPassword"); + + doc.save(getArtifactsDir() + "File.DetectDocumentEncryption.odt", saveOptions); + + // Verify the file type of our document, and its encryption status. + FileFormatInfo info = FileFormatUtil.detectFileFormat(getArtifactsDir() + "File.DetectDocumentEncryption.odt"); + + Assert.assertEquals(".odt", FileFormatUtil.loadFormatToExtension(info.getLoadFormat())); + Assert.assertTrue(info.isEncrypted()); + //ExEnd + } + + @Test + public void detectDigitalSignatures() throws Exception { + //ExStart + //ExFor:FileFormatUtil.DetectFileFormat(String) + //ExFor:FileFormatInfo + //ExFor:FileFormatInfo.LoadFormat + //ExFor:FileFormatInfo.HasDigitalSignature + //ExSummary:Shows how to use the FileFormatUtil class to detect the document format and presence of digital signatures. + // Use a FileFormatInfo instance to verify that a document is not digitally signed. + FileFormatInfo info = FileFormatUtil.detectFileFormat(getMyDir() + "Document.docx"); + + Assert.assertEquals(".docx", FileFormatUtil.loadFormatToExtension(info.getLoadFormat())); + Assert.assertFalse(info.hasDigitalSignature()); + + CertificateHolder certificateHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw", null); + DigitalSignatureUtil.sign(getMyDir() + "Document.docx", getArtifactsDir() + "File.DetectDigitalSignatures.docx", + certificateHolder); + + // Use a new FileFormatInstance to confirm that it is signed. + info = FileFormatUtil.detectFileFormat(getArtifactsDir() + "File.DetectDigitalSignatures.docx"); + + Assert.assertTrue(info.hasDigitalSignature()); + + // We can load and access the signatures of a signed document in a collection like this. + Assert.assertEquals(1, DigitalSignatureUtil.loadSignatures(getArtifactsDir() + "File.DetectDigitalSignatures.docx").getCount()); + //ExEnd + } + + @Test + public void saveToDetectedFileFormat() throws Exception { + //ExStart + //ExFor:FileFormatUtil.DetectFileFormat(Stream) + //ExFor:FileFormatUtil.LoadFormatToExtension(LoadFormat) + //ExFor:FileFormatUtil.ExtensionToSaveFormat(String) + //ExFor:FileFormatUtil.SaveFormatToExtension(SaveFormat) + //ExFor:FileFormatUtil.LoadFormatToSaveFormat(LoadFormat) + //ExFor:Document.OriginalFileName + //ExFor:FileFormatInfo.LoadFormat + //ExFor:LoadFormat + //ExSummary:Shows how to use the FileFormatUtil methods to detect the format of a document. + // Load a document from a file that is missing a file extension, and then detect its file format. + FileInputStream docStream = new FileInputStream(getMyDir() + "Word document with missing file extension"); + + FileFormatInfo info = FileFormatUtil.detectFileFormat(docStream); + /*LoadFormat*/ + int loadFormat = info.getLoadFormat(); + + Assert.assertEquals(LoadFormat.DOC, loadFormat); + + // Below are two methods of converting a LoadFormat to its corresponding SaveFormat. + // 1 - Get the file extension string for the LoadFormat, then get the corresponding SaveFormat from that string: + String fileExtension = FileFormatUtil.loadFormatToExtension(loadFormat); + /*SaveFormat*/ + int saveFormat = FileFormatUtil.extensionToSaveFormat(fileExtension); + + // 2 - Convert the LoadFormat directly to its SaveFormat: + saveFormat = FileFormatUtil.loadFormatToSaveFormat(loadFormat); + + // Load a document from the stream, and then save it to the automatically detected file extension. + Document doc = new Document(docStream); + + Assert.assertEquals(".doc", FileFormatUtil.saveFormatToExtension(saveFormat)); + + doc.save(getArtifactsDir() + "File.SaveToDetectedFileFormat" + FileFormatUtil.saveFormatToExtension(saveFormat)); + //ExEnd + } + + @Test + public void detectFileFormat_SaveFormatToLoadFormat() { + //ExStart + //ExFor:FileFormatUtil.SaveFormatToLoadFormat(SaveFormat) + //ExSummary:Shows how to convert a save format to its corresponding load format. + Assert.assertEquals(LoadFormat.HTML, FileFormatUtil.saveFormatToLoadFormat(SaveFormat.HTML)); + + // Some file types can have documents saved to, but not loaded from using Aspose.Words. + // If we attempt to convert a save format of such a type to a load format, an exception will be thrown. + Assert.assertThrows(IllegalArgumentException.class, () -> FileFormatUtil.saveFormatToLoadFormat(SaveFormat.JPEG)); + //ExEnd + } + + @Test + public void extractImages() throws Exception { + //ExStart + //ExFor:Shape + //ExFor:Shape.ImageData + //ExFor:Shape.HasImage + //ExFor:ImageData + //ExFor:FileFormatUtil.ImageTypeToExtension(ImageType) + //ExFor:ImageData.ImageType + //ExFor:ImageData.Save(String) + //ExFor:CompositeNode.GetChildNodes(NodeType, bool) + //ExSummary:Shows how to extract images from a document, and save them to the local file system as individual files. + Document doc = new Document(getMyDir() + "Images.docx"); + + // Get the collection of shapes from the document, + // and save the image data of every shape with an image as a file to the local file system. + NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); + + int imageIndex = 0; + for (Shape shape : (Iterable<Shape>) shapes) { + if (shape.hasImage()) { + // The image data of shapes may contain images of many possible image formats. + // We can determine a file extension for each image automatically, based on its format. + String imageFileName = MessageFormat.format("File.ExtractImages.{0}{1}", imageIndex, FileFormatUtil.imageTypeToExtension(shape.getImageData().getImageType())); + shape.getImageData().save(getArtifactsDir() + imageFileName); + imageIndex++; + } + } + //ExEnd + + ArrayList<String> dirFiles = DocumentHelper.directoryGetFiles(getArtifactsDir(), "^.+\\.(jpeg|png|emf|wmf)$"); + long imagesCount = dirFiles.stream().filter(s -> s.startsWith(getArtifactsDir() + "File.ExtractImages")).count(); + + Assert.assertEquals(9, imagesCount); + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExFont.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExFont.java new file mode 100644 index 00000000..9227674c --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExFont.java @@ -0,0 +1,1697 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + + +import com.aspose.words.Font; +import com.aspose.words.Shape; +import com.aspose.words.*; +import org.apache.commons.io.FileUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.awt.*; +import java.io.File; +import java.nio.file.Paths; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Iterator; + +public class ExFont extends ApiExampleBase { + @Test + public void createFormattedRun() throws Exception { + //ExStart + //ExFor:Document.#ctor + //ExFor:Font + //ExFor:Font.Name + //ExFor:Font.Size + //ExFor:Font.HighlightColor + //ExFor:Run + //ExFor:Run.#ctor(DocumentBase,String) + //ExFor:Story.FirstParagraph + //ExSummary:Shows how to format a run of text using its font property. + Document doc = new Document(); + Run run = new Run(doc, "Hello world!"); + + Font font = run.getFont(); + font.setName("Courier New"); + font.setSize(36.0); + font.setHighlightColor(Color.YELLOW); + + doc.getFirstSection().getBody().getFirstParagraph().appendChild(run); + doc.save(getArtifactsDir() + "Font.CreateFormattedRun.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.CreateFormattedRun.docx"); + run = doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0); + + Assert.assertEquals("Hello world!", run.getText().trim()); + Assert.assertEquals("Courier New", run.getFont().getName()); + Assert.assertEquals(36.0, run.getFont().getSize()); + Assert.assertEquals(Color.YELLOW.getRGB(), run.getFont().getHighlightColor().getRGB()); + } + + @Test + public void caps() throws Exception { + //ExStart + //ExFor:Font.AllCaps + //ExFor:Font.SmallCaps + //ExSummary:Shows how to format a run to display its contents in capitals. + Document doc = new Document(); + Paragraph para = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 0, true); + + // There are two ways of getting a run to display its lowercase text in uppercase without changing the contents. + // 1 - Set the AllCaps flag to display all characters in regular capitals: + Run run = new Run(doc, "all capitals"); + run.getFont().setAllCaps(true); + para.appendChild(run); + + para = (Paragraph) para.getParentNode().appendChild(new Paragraph(doc)); + + // 2 - Set the SmallCaps flag to display all characters in small capitals: + // If a character is lower case, it will appear in its upper case form + // but will have the same height as the lower case (the font's x-height). + // Characters that were in upper case originally will look the same. + run = new Run(doc, "Small Capitals"); + run.getFont().setSmallCaps(true); + para.appendChild(run); + + doc.save(getArtifactsDir() + "Font.Caps.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.Caps.docx"); + run = doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0); + + Assert.assertEquals("all capitals", run.getText().trim()); + Assert.assertTrue(run.getFont().getAllCaps()); + + run = doc.getFirstSection().getBody().getParagraphs().get(1).getRuns().get(0); + + Assert.assertEquals("Small Capitals", run.getText().trim()); + Assert.assertTrue(run.getFont().getSmallCaps()); + } + + @Test + public void getDocumentFonts() throws Exception { + //ExStart + //ExFor:FontInfoCollection + //ExFor:DocumentBase.FontInfos + //ExFor:FontInfo + //ExFor:FontInfo.Name + //ExFor:FontInfo.IsTrueType + //ExSummary:Shows how to print the details of what fonts are present in a document. + Document doc = new Document(getMyDir() + "Embedded font.docx"); + + FontInfoCollection allFonts = doc.getFontInfos(); + Assert.assertEquals(5, allFonts.getCount()); //ExSkip + + // Print all the used and unused fonts in the document. + for (int i = 0; i < allFonts.getCount(); i++) { + System.out.println("Font index #{i}"); + System.out.println("\tName: {allFonts[i].Name}"); + System.out.println("\tIs {(allFonts[i].IsTrueType ? "); //ExSkip + } + //ExEnd + } + + @Test(description = "WORDSNET-16234") + public void defaultValuesEmbeddedFontsParameters() throws Exception { + Document doc = new Document(); + + Assert.assertFalse(doc.getFontInfos().getEmbedTrueTypeFonts()); + Assert.assertFalse(doc.getFontInfos().getEmbedSystemFonts()); + Assert.assertFalse(doc.getFontInfos().getSaveSubsetFonts()); + } + + @Test(dataProvider = "fontInfoCollectionDataProvider") + public void fontInfoCollection(boolean embedAllFonts) throws Exception { + //ExStart + //ExFor:FontInfoCollection + //ExFor:DocumentBase.FontInfos + //ExFor:FontInfoCollection.EmbedTrueTypeFonts + //ExFor:FontInfoCollection.EmbedSystemFonts + //ExFor:FontInfoCollection.SaveSubsetFonts + //ExSummary:Shows how to save a document with embedded TrueType fonts. + Document doc = new Document(getMyDir() + "Document.docx"); + + FontInfoCollection fontInfos = doc.getFontInfos(); + fontInfos.setEmbedTrueTypeFonts(embedAllFonts); + fontInfos.setEmbedSystemFonts(embedAllFonts); + fontInfos.setSaveSubsetFonts(embedAllFonts); + + doc.save(getArtifactsDir() + "Font.FontInfoCollection.docx"); + //ExEnd + + long testedFileLength = new File(getArtifactsDir() + "Font.FontInfoCollection.docx").length(); + + if (embedAllFonts) + Assert.assertTrue(testedFileLength > 25000); + else + Assert.assertTrue(testedFileLength <= 15000); + + } + + @DataProvider(name = "fontInfoCollectionDataProvider") + public static Object[][] fontInfoCollectionDataProvider() throws Exception { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "workWithEmbeddedFontsDataProvider") + public void workWithEmbeddedFonts(final boolean embedTrueTypeFonts, final boolean embedSystemFonts, final boolean saveSubsetFonts) throws Exception { + Document doc = new Document(getMyDir() + "Document.docx"); + + FontInfoCollection fontInfos = doc.getFontInfos(); + fontInfos.setEmbedTrueTypeFonts(embedTrueTypeFonts); + fontInfos.setEmbedSystemFonts(embedSystemFonts); + fontInfos.setSaveSubsetFonts(saveSubsetFonts); + + doc.save(getArtifactsDir() + "Font.WorkWithEmbeddedFonts.docx"); + } + + @DataProvider(name = "workWithEmbeddedFontsDataProvider") + public static Object[][] workWithEmbeddedFontsDataProvider() { + return new Object[][] + { + {true, false, false}, + {true, true, false}, + {true, true, true}, + {true, false, true}, + {false, false, false}, + }; + } + + @Test + public void strikeThrough() throws Exception { + //ExStart + //ExFor:Font.StrikeThrough + //ExFor:Font.DoubleStrikeThrough + //ExSummary:Shows how to add a line strikethrough to text. + Document doc = new Document(); + Paragraph para = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 0, true); + + Run run = new Run(doc, "Text with a single-line strikethrough."); + run.getFont().setStrikeThrough(true); + para.appendChild(run); + + para = (Paragraph) para.getParentNode().appendChild(new Paragraph(doc)); + + run = new Run(doc, "Text with a double-line strikethrough."); + run.getFont().setDoubleStrikeThrough(true); + para.appendChild(run); + + doc.save(getArtifactsDir() + "Font.StrikeThrough.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.StrikeThrough.docx"); + + run = doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0); + + Assert.assertEquals("Text with a single-line strikethrough.", run.getText().trim()); + Assert.assertTrue(run.getFont().getStrikeThrough()); + + run = doc.getFirstSection().getBody().getParagraphs().get(1).getRuns().get(0); + + Assert.assertEquals("Text with a double-line strikethrough.", run.getText().trim()); + Assert.assertTrue(run.getFont().getDoubleStrikeThrough()); + } + + @Test + public void positionSubscript() throws Exception { + //ExStart + //ExFor:Font.Position + //ExFor:Font.Subscript + //ExFor:Font.Superscript + //ExSummary:Shows how to format text to offset its position. + Document doc = new Document(); + Paragraph para = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 0, true); + + // Raise this run of text 5 points above the baseline. + Run run = new Run(doc, "Raised text. "); + run.getFont().setPosition(5.0); + para.appendChild(run); + + // Lower this run of text 10 points below the baseline. + run = new Run(doc, "Lowered text. "); + run.getFont().setPosition(-10); + para.appendChild(run); + + // Add a run of normal text. + run = new Run(doc, "Text in its default position. "); + para.appendChild(run); + + // Add a run of text that appears as subscript. + run = new Run(doc, "Subscript. "); + run.getFont().setSubscript(true); + para.appendChild(run); + + // Add a run of text that appears as superscript. + run = new Run(doc, "Superscript."); + run.getFont().setSuperscript(true); + para.appendChild(run); + + doc.save(getArtifactsDir() + "Font.PositionSubscript.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.PositionSubscript.docx"); + run = doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0); + + Assert.assertEquals("Raised text.", run.getText().trim()); + Assert.assertEquals(5.0, run.getFont().getPosition()); + + doc = new Document(getArtifactsDir() + "Font.PositionSubscript.docx"); + run = doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(1); + + Assert.assertEquals("Lowered text.", run.getText().trim()); + Assert.assertEquals(-10.0, run.getFont().getPosition()); + + run = doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(3); + + Assert.assertEquals("Subscript.", run.getText().trim()); + Assert.assertTrue(run.getFont().getSubscript()); + + run = doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(4); + + Assert.assertEquals("Superscript.", run.getText().trim()); + Assert.assertTrue(run.getFont().getSuperscript()); + } + + @Test + public void scalingSpacing() throws Exception { + //ExStart + //ExFor:Font.Scaling + //ExFor:Font.Spacing + //ExSummary:Shows how to set horizontal scaling and spacing for characters. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Add run of text and increase character width to 150%. + builder.getFont().setScaling(150); + builder.writeln("Wide characters"); + + // Add run of text and add 1pt of extra horizontal spacing between each character. + builder.getFont().setSpacing(1.0); + builder.writeln("Expanded by 1pt"); + + // Add run of text and bring characters closer together by 1pt. + builder.getFont().setSpacing(-1); + builder.writeln("Condensed by 1pt"); + + doc.save(getArtifactsDir() + "Font.ScalingSpacing.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.ScalingSpacing.docx"); + Run run = doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0); + + Assert.assertEquals("Wide characters", run.getText().trim()); + Assert.assertEquals(150, run.getFont().getScaling()); + + run = doc.getFirstSection().getBody().getParagraphs().get(1).getRuns().get(0); + + Assert.assertEquals("Expanded by 1pt", run.getText().trim()); + Assert.assertEquals(1.0, run.getFont().getSpacing()); + + run = doc.getFirstSection().getBody().getParagraphs().get(2).getRuns().get(0); + + Assert.assertEquals("Condensed by 1pt", run.getText().trim()); + Assert.assertEquals(-1.0, run.getFont().getSpacing()); + } + + @Test + public void italic() throws Exception { + //ExStart + //ExFor:Font.Italic + //ExSummary:Shows how to write italicized text using a document builder. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setSize(36.0); + builder.getFont().setItalic(true); + builder.writeln("Hello world!"); + + doc.save(getArtifactsDir() + "Font.Italic.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.Italic.docx"); + Run run = doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0); + + Assert.assertEquals("Hello world!", run.getText().trim()); + Assert.assertTrue(run.getFont().getItalic()); + } + + @Test + public void engraveEmboss() throws Exception { + //ExStart + //ExFor:Font.Emboss + //ExFor:Font.Engrave + //ExSummary:Shows how to apply engraving/embossing effects to text. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setSize(36.0); + builder.getFont().setColor(Color.WHITE); + + // Below are two ways of using shadows to apply a 3D-like effect to the text. + // 1 - Engrave text to make it look like the letters are sunken into the page: + builder.getFont().setEngrave(true); + + builder.writeln("This text is engraved."); + + // 2 - Emboss text to make it look like the letters pop out of the page: + builder.getFont().setEngrave(false); + builder.getFont().setEmboss(true); + + builder.writeln("This text is embossed."); + + doc.save(getArtifactsDir() + "Font.EngraveEmboss.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.EngraveEmboss.docx"); + Run run = doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0); + + Assert.assertEquals("This text is engraved.", run.getText().trim()); + Assert.assertTrue(run.getFont().getEngrave()); + Assert.assertFalse(run.getFont().getEmboss()); + + run = doc.getFirstSection().getBody().getParagraphs().get(1).getRuns().get(0); + + Assert.assertEquals("This text is embossed.", run.getText().trim()); + Assert.assertFalse(run.getFont().getEngrave()); + Assert.assertTrue(run.getFont().getEmboss()); + } + + @Test + public void shadow() throws Exception { + //ExStart + //ExFor:Font.Shadow + //ExSummary:Shows how to create a run of text formatted with a shadow. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Set the Shadow flag to apply an offset shadow effect, + // making it look like the letters are floating above the page. + builder.getFont().setShadow(true); + builder.getFont().setSize(36.0); + + builder.writeln("This text has a shadow."); + + doc.save(getArtifactsDir() + "Font.Shadow.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.Shadow.docx"); + Run run = doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0); + + Assert.assertEquals("This text has a shadow.", run.getText().trim()); + Assert.assertTrue(run.getFont().getShadow()); + } + + @Test + public void outline() throws Exception { + //ExStart + //ExFor:Font.Outline + //ExSummary:Shows how to create a run of text formatted as outline. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Set the Outline flag to change the text's fill color to white and + // leave a thin outline around each character in the original color of the text. + builder.getFont().setOutline(true); + builder.getFont().setColor(Color.BLUE); + builder.getFont().setSize(36.0); + + builder.writeln("This text has an outline."); + + doc.save(getArtifactsDir() + "Font.Outline.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.Outline.docx"); + Run run = doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0); + + Assert.assertEquals("This text has an outline.", run.getText().trim()); + Assert.assertTrue(run.getFont().getOutline()); + } + + @Test + public void hidden() throws Exception { + //ExStart + //ExFor:Font.Hidden + //ExSummary:Shows how to create a run of hidden text. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // With the Hidden flag set to true, any text that we create using this Font object will be invisible in the document. + // We will not see or highlight hidden text unless we enable the "Hidden text" option + // found in Microsoft Word via "File" -> "Options" -> "Display". The text will still be there, + // and we will be able to access this text programmatically. + // It is not advised to use this method to hide sensitive information. + builder.getFont().setHidden(true); + builder.getFont().setSize(36.0); + + builder.writeln("This text will not be visible in the document."); + + doc.save(getArtifactsDir() + "Font.Hidden.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.Hidden.docx"); + Run run = doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0); + + Assert.assertEquals("This text will not be visible in the document.", run.getText().trim()); + Assert.assertTrue(run.getFont().getHidden()); + } + + @Test + public void kerning() throws Exception { + //ExStart + //ExFor:Font.Kerning + //ExSummary:Shows how to specify the font size at which kerning begins to take effect. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.getFont().setName("Arial Black"); + + // Set the builder's font size, and minimum size at which kerning will take effect. + // The font size falls below the kerning threshold, so the run bellow will not have kerning. + builder.getFont().setSize(18.0); + builder.getFont().setKerning(24.0); + + builder.writeln("TALLY. (Kerning not applied)"); + + // Set the kerning threshold so that the builder's current font size is above it. + // Any text we add from this point will have kerning applied. The spaces between characters + // will be adjusted, normally resulting in a slightly more aesthetically pleasing text run. + builder.getFont().setKerning(12.0); + + builder.writeln("TALLY. (Kerning applied)"); + + doc.save(getArtifactsDir() + "Font.Kerning.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.Kerning.docx"); + Run run = doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0); + + Assert.assertEquals("TALLY. (Kerning not applied)", run.getText().trim()); + Assert.assertEquals(24.0, run.getFont().getKerning()); + Assert.assertEquals(18.0, run.getFont().getSize()); + + run = doc.getFirstSection().getBody().getParagraphs().get(1).getRuns().get(0); + + Assert.assertEquals("TALLY. (Kerning applied)", run.getText().trim()); + Assert.assertEquals(12.0, run.getFont().getKerning()); + Assert.assertEquals(18.0, run.getFont().getSize()); + } + + @Test + public void noProofing() throws Exception { + //ExStart + //ExFor:Font.NoProofing + //ExSummary:Shows how to prevent text from being spell checked by Microsoft Word. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Normally, Microsoft Word emphasizes spelling errors with a jagged red underline. + // We can un-set the "NoProofing" flag to create a portion of text that + // bypasses the spell checker while completely disabling it. + builder.getFont().setNoProofing(true); + + builder.writeln("Proofing has been disabled, so these spelking errrs will not display red lines underneath."); + + doc.save(getArtifactsDir() + "Font.NoProofing.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.NoProofing.docx"); + Run run = doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0); + + Assert.assertEquals("Proofing has been disabled, so these spelking errrs will not display red lines underneath.", run.getText().trim()); + Assert.assertTrue(run.getFont().getNoProofing()); + } + + @Test + public void localeId() throws Exception { + //ExStart + //ExFor:Font.LocaleId + //ExSummary:Shows how to set the locale of the text that we are adding with a document builder. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // If we set the font's locale to English and insert some Russian text, + // the English locale spell checker will not recognize the text and detect it as a spelling error. + builder.getFont().setLocaleId(1033); + builder.writeln("Привет!"); + + // Set a matching locale for the text that we are about to add to apply the appropriate spell checker. + builder.getFont().setLocaleId(1049); + builder.writeln("Привет!"); + + doc.save(getArtifactsDir() + "Font.LocaleId.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.LocaleId.docx"); + Run run = doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0); + + Assert.assertEquals("Привет!", run.getText().trim()); + Assert.assertEquals(1033, run.getFont().getLocaleId()); + + run = doc.getFirstSection().getBody().getParagraphs().get(1).getRuns().get(0); + + Assert.assertEquals("Привет!", run.getText().trim()); + Assert.assertEquals(1049, run.getFont().getLocaleId()); + } + + @Test + public void underlines() throws Exception { + //ExStart + //ExFor:Font.Underline + //ExFor:Font.UnderlineColor + //ExSummary:Shows how to configure the style and color of a text underline. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setUnderline(Underline.DOTTED); + builder.getFont().setUnderlineColor(Color.RED); + + builder.writeln("Underlined text."); + + doc.save(getArtifactsDir() + "Font.Underlines.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.Underlines.docx"); + Run run = doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0); + + Assert.assertEquals("Underlined text.", run.getText().trim()); + Assert.assertEquals(Underline.DOTTED, run.getFont().getUnderline()); + Assert.assertEquals(Color.RED.getRGB(), run.getFont().getUnderlineColor().getRGB()); + } + + @Test + public void complexScript() throws Exception { + //ExStart + //ExFor:Font.ComplexScript + //ExSummary:Shows how to add text that is always treated as complex script. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setComplexScript(true); + + builder.writeln("Text treated as complex script."); + + doc.save(getArtifactsDir() + "Font.ComplexScript.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.ComplexScript.docx"); + Run run = doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0); + + Assert.assertEquals("Text treated as complex script.", run.getText().trim()); + Assert.assertTrue(run.getFont().getComplexScript()); + } + + @Test + public void sparklingText() throws Exception { + //ExStart + //ExFor:TextEffect + //ExFor:Font.TextEffect + //ExSummary:Shows how to apply a visual effect to a run. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setSize(36.0); + builder.getFont().setTextEffect(TextEffect.SPARKLE_TEXT); + + builder.writeln("Text with a sparkle effect."); + + // Older versions of Microsoft Word only support font animation effects. + doc.save(getArtifactsDir() + "Font.SparklingText.doc"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.SparklingText.doc"); + Run run = doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0); + + Assert.assertEquals("Text with a sparkle effect.", run.getText().trim()); + Assert.assertEquals(TextEffect.SPARKLE_TEXT, run.getFont().getTextEffect()); + } + + @Test + public void foregroundAndBackground() throws Exception + { + //ExStart + //ExFor:Shading.ForegroundPatternThemeColor + //ExFor:Shading.BackgroundPatternThemeColor + //ExFor:Shading.ForegroundTintAndShade + //ExFor:Shading.BackgroundTintAndShade + //ExSummary:Shows how to set foreground and background colors for shading texture. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shading shading = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat().getShading(); + shading.setTexture(TextureIndex.TEXTURE_12_PT_5_PERCENT); + shading.setForegroundPatternThemeColor(ThemeColor.DARK_1); + shading.setBackgroundPatternThemeColor(ThemeColor.DARK_2); + + shading.setForegroundTintAndShade(0.5); + shading.setBackgroundTintAndShade(-0.2); + + builder.getFont().getBorder().setColor(Color.GREEN); + builder.getFont().getBorder().setLineWidth(2.5d); + builder.getFont().getBorder().setLineStyle(LineStyle.DASH_DOT_STROKER); + + builder.writeln("Foreground and background pattern colors for shading texture."); + + doc.save(getArtifactsDir() + "Font.ForegroundAndBackground.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.ForegroundAndBackground.docx"); + Run run = doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0); + + Assert.assertEquals("Foreground and background pattern colors for shading texture.", run.getText().trim()); + Assert.assertEquals(ThemeColor.DARK_1, doc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat().getShading().getForegroundPatternThemeColor()); + Assert.assertEquals(ThemeColor.DARK_2, doc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat().getShading().getBackgroundPatternThemeColor()); + + Assert.assertEquals(0.5, doc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat().getShading().getForegroundTintAndShade(), 0.1); + Assert.assertEquals(-0.2, doc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat().getShading().getBackgroundTintAndShade(), 0.1); + } + + @Test + public void shading() throws Exception { + //ExStart + //ExFor:Font.Shading + //ExSummary:Shows how to apply shading to text created by a document builder. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setColor(Color.WHITE); + + // One way to make the text created using our white font color visible + // is to apply a background shading effect. + Shading shading = builder.getFont().getShading(); + shading.setTexture(TextureIndex.TEXTURE_DIAGONAL_UP); + shading.setBackgroundPatternColor(Color.RED); + shading.setForegroundPatternColor(Color.BLUE); + + builder.writeln("White text on an orange background with a two-tone texture."); + + doc.save(getArtifactsDir() + "Font.Shading.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.Shading.docx"); + Run run = doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0); + + Assert.assertEquals("White text on an orange background with a two-tone texture.", run.getText().trim()); + Assert.assertEquals(Color.WHITE.getRGB(), run.getFont().getColor().getRGB()); + + Assert.assertEquals(TextureIndex.TEXTURE_DIAGONAL_UP, run.getFont().getShading().getTexture()); + Assert.assertEquals(Color.RED.getRGB(), run.getFont().getShading().getBackgroundPatternColor().getRGB()); + Assert.assertEquals(Color.BLUE.getRGB(), run.getFont().getShading().getForegroundPatternColor().getRGB()); + } + + @Test + public void bidi() throws Exception { + //ExStart + //ExFor:Font.Bidi + //ExFor:Font.NameBi + //ExFor:Font.SizeBi + //ExFor:Font.ItalicBi + //ExFor:Font.BoldBi + //ExFor:Font.LocaleIdBi + //ExSummary:Shows how to define separate sets of font settings for right-to-left, and right-to-left text. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Define a set of font settings for left-to-right text. + builder.getFont().setName("Courier New"); + builder.getFont().setSize(16.0); + builder.getFont().setItalic(false); + builder.getFont().setBold(false); + builder.getFont().setLocaleId(1033); + + // Define another set of font settings for right-to-left text. + builder.getFont().setNameBi("Andalus"); + builder.getFont().setSizeBi(24.0); + builder.getFont().setItalicBi(true); + builder.getFont().setBoldBi(true); + builder.getFont().setLocaleIdBi(1025); + + // We can use the Bidi flag to indicate whether the text we are about to add + // with the document builder is right-to-left. When we add text with this flag set to true, + // it will be formatted using the right-to-left set of font settings. + builder.getFont().setBidi(true); + builder.write("مرحبًا"); + + // Set the flag to false, and then add left-to-right text. + // The document builder will format these using the left-to-right set of font settings. + builder.getFont().setBidi(false); + builder.write(" Hello world!"); + + doc.save(getArtifactsDir() + "Font.Bidi.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.Bidi.docx"); + + for (Run run : doc.getFirstSection().getBody().getParagraphs().get(0).getRuns()) { + switch (doc.getFirstSection().getBody().getParagraphs().get(0).indexOf(run)) { + case 0: + Assert.assertEquals("مرحبًا", run.getText().trim()); + Assert.assertTrue(run.getFont().getBidi()); + break; + case 1: + Assert.assertEquals("Hello world!", run.getText().trim()); + Assert.assertFalse(run.getFont().getBidi()); + break; + } + + Assert.assertEquals(1033, run.getFont().getLocaleId()); + Assert.assertEquals(16, run.getFont().getSize()); + Assert.assertFalse(run.getFont().getItalic()); + Assert.assertFalse(run.getFont().getBold()); + Assert.assertEquals(1025, run.getFont().getLocaleIdBi()); + Assert.assertEquals(24, run.getFont().getSizeBi()); + Assert.assertEquals("Andalus", run.getFont().getNameBi()); + Assert.assertTrue(run.getFont().getItalicBi()); + Assert.assertTrue(run.getFont().getBoldBi()); + } + } + + @Test + public void farEast() throws Exception { + //ExStart + //ExFor:Font.NameFarEast + //ExFor:Font.LocaleIdFarEast + //ExSummary:Shows how to insert and format text in a Far East language. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Specify font settings that the document builder will apply to any text that it inserts. + builder.getFont().setName("Courier New"); + builder.getFont().setLocaleId(1033); + + // Name "FarEast" equivalents for our font and locale. + // If the builder inserts Asian characters with this Font configuration, then each run that contains + // these characters will display them using the "FarEast" font/locale instead of the default. + // This could be useful when a western font does not have ideal representations for Asian characters. + builder.getFont().setNameFarEast("SimSun"); + builder.getFont().setLocaleIdFarEast(2052); + + // This text will be displayed in the default font/locale. + builder.writeln("Hello world!"); + + // Since these are Asian characters, this run will apply our "FarEast" font/locale equivalents. + builder.writeln("你好世界"); + + doc.save(getArtifactsDir() + "Font.FarEast.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.FarEast.docx"); + Run run = doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0); + + Assert.assertEquals("Hello world!", run.getText().trim()); + Assert.assertEquals(1033, run.getFont().getLocaleId()); + Assert.assertEquals("Courier New", run.getFont().getName()); + Assert.assertEquals(2052, run.getFont().getLocaleIdFarEast()); + Assert.assertEquals("SimSun", run.getFont().getNameFarEast()); + + run = doc.getFirstSection().getBody().getParagraphs().get(1).getRuns().get(0); + + Assert.assertEquals("你好世界", run.getText().trim()); + Assert.assertEquals(1033, run.getFont().getLocaleId()); + Assert.assertEquals("SimSun", run.getFont().getName()); + Assert.assertEquals(2052, run.getFont().getLocaleIdFarEast()); + Assert.assertEquals("SimSun", run.getFont().getNameFarEast()); + } + + @Test + public void nameAscii() throws Exception { + //ExStart + //ExFor:Font.NameAscii + //ExFor:Font.NameOther + //ExSummary:Shows how Microsoft Word can combine two different fonts in one run. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Suppose a run that we use the builder to insert while using this font configuration + // contains characters within the ASCII characters' range. In that case, + // it will display those characters using this font. + builder.getFont().setNameAscii("Calibri"); + + // With no other font specified, the builder will also apply this font to all characters that it inserts. + Assert.assertEquals("Calibri", builder.getFont().getName()); + + // Specify a font to use for all characters outside of the ASCII range. + // Ideally, this font should have a glyph for each required non-ASCII character code. + builder.getFont().setNameOther("Courier New"); + + // Insert a run with one word consisting of ASCII characters, and one word with all characters outside that range. + // Each character will be displayed using either of the fonts, depending on. + builder.writeln("Hello, Привет"); + + doc.save(getArtifactsDir() + "Font.NameAscii.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.NameAscii.docx"); + Run run = doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0); + + Assert.assertEquals("Hello, Привет", run.getText().trim()); + Assert.assertEquals("Calibri", run.getFont().getName()); + Assert.assertEquals("Calibri", run.getFont().getNameAscii()); + Assert.assertEquals("Courier New", run.getFont().getNameOther()); + } + + @Test + public void changeStyle() throws Exception { + //ExStart + //ExFor:Font.StyleName + //ExFor:Font.StyleIdentifier + //ExFor:StyleIdentifier + //ExSummary:Shows how to change the style of existing text. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are two ways of referencing styles. + // 1 - Using the style name: + builder.getFont().setStyleName("Emphasis"); + builder.writeln("Text originally in \"Emphasis\" style"); + + // 2 - Using a built-in style identifier: + builder.getFont().setStyleIdentifier(StyleIdentifier.INTENSE_EMPHASIS); + builder.writeln("Text originally in \"Intense Emphasis\" style"); + + // Convert all uses of one style to another, + // using the above methods to reference old and new styles. + for (Run run : (Iterable<Run>) doc.getChildNodes(NodeType.RUN, true)) { + if (run.getFont().getStyleName().equals("Emphasis")) + run.getFont().setStyleName("Strong"); + + if (((run.getFont().getStyleIdentifier()) == (StyleIdentifier.INTENSE_EMPHASIS))) + run.getFont().setStyleIdentifier(StyleIdentifier.STRONG); + } + + doc.save(getArtifactsDir() + "Font.ChangeStyle.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.ChangeStyle.docx"); + Run docRun = doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0); + + Assert.assertEquals("Text originally in \"Emphasis\" style", docRun.getText().trim()); + Assert.assertEquals(StyleIdentifier.STRONG, docRun.getFont().getStyleIdentifier()); + Assert.assertEquals("Strong", docRun.getFont().getStyleName()); + + docRun = doc.getFirstSection().getBody().getParagraphs().get(1).getRuns().get(0); + + Assert.assertEquals("Text originally in \"Intense Emphasis\" style", docRun.getText().trim()); + Assert.assertEquals(StyleIdentifier.STRONG, docRun.getFont().getStyleIdentifier()); + Assert.assertEquals("Strong", docRun.getFont().getStyleName()); + } + + @Test + public void builtIn() throws Exception { + //ExStart + //ExFor:Style.BuiltIn + //ExSummary:Shows how to differentiate custom styles from built-in styles. + Document doc = new Document(); + + // When we create a document using Microsoft Word, or programmatically using Aspose.Words, + // the document will come with a collection of styles to apply to its text to modify its appearance. + // We can access these built-in styles via the document's "Styles" collection. + // These styles will all have the "BuiltIn" flag set to "true". + Style style = doc.getStyles().get("Emphasis"); + + Assert.assertTrue(style.getBuiltIn()); + + // Create a custom style and add it to the collection. + // Custom styles such as this will have the "BuiltIn" flag set to "false". + style = doc.getStyles().add(StyleType.CHARACTER, "MyStyle"); + style.getFont().setColor(Color.RED); + style.getFont().setName("Courier New"); + + Assert.assertFalse(style.getBuiltIn()); + //ExEnd + } + + @Test + public void style() throws Exception { + //ExStart + //ExFor:Font.Style + //ExSummary:Applies a double underline to all runs in a document that are formatted with custom character styles. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a custom style and apply it to text created using a document builder. + Style style = doc.getStyles().add(StyleType.CHARACTER, "MyStyle"); + style.getFont().setColor(Color.RED); + style.getFont().setName("Courier New"); + + builder.getFont().setStyleName("MyStyle"); + builder.write("This text is in a custom style."); + + // Iterate over every run and add a double underline to every custom style. + for (Run run : (Iterable<Run>) doc.getChildNodes(NodeType.RUN, true)) { + Style charStyle = run.getFont().getStyle(); + + if (!charStyle.getBuiltIn()) + run.getFont().setUnderline(Underline.DOUBLE); + } + + doc.save(getArtifactsDir() + "Font.Style.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.Style.docx"); + Run docRun = doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0); + + Assert.assertEquals("This text is in a custom style.", docRun.getText().trim()); + Assert.assertEquals("MyStyle", docRun.getFont().getStyleName()); + Assert.assertFalse(docRun.getFont().getStyle().getBuiltIn()); + Assert.assertEquals(Underline.DOUBLE, docRun.getFont().getUnderline()); + } + + @Test + public void getAvailableFonts() throws Exception { + //ExStart + //ExFor:PhysicalFontInfo + //ExFor:FontSourceBase.GetAvailableFonts + //ExFor:PhysicalFontInfo.FontFamilyName + //ExFor:PhysicalFontInfo.FullFontName + //ExFor:PhysicalFontInfo.Version + //ExFor:PhysicalFontInfo.FilePath + //ExSummary:Shows how to list available fonts. + // Configure Aspose.Words to source fonts from a custom folder, and then print every available font. + FontSourceBase[] folderFontSource = {new FolderFontSource(getFontsDir(), true)}; + + for (PhysicalFontInfo fontInfo : folderFontSource[0].getAvailableFonts()) { + System.out.println(MessageFormat.format("FontFamilyName : {0}", fontInfo.getFontFamilyName())); + System.out.println(MessageFormat.format("FullFontName : {0}", fontInfo.getFullFontName())); + System.out.println(MessageFormat.format("Version : {0}", fontInfo.getVersion())); + System.out.println(MessageFormat.format("FilePath : {0}\n", fontInfo.getFilePath())); + } + //ExEnd + + Assert.assertEquals(folderFontSource[0].getAvailableFonts().size(), + DocumentHelper.directoryGetFiles(getFontsDir(), "*.*").stream().filter(f -> f.endsWith(".ttf") || f.endsWith(".otf")).count() + 5); + } + + @Test + public void setFontAutoColor() throws Exception { + //ExStart + //ExFor:Font.AutoColor + //ExSummary:Shows how to improve readability by automatically selecting text color based on the brightness of its background. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // If a run's Font object does not specify text color, it will automatically + // select either black or white depending on the background color's color. + Assert.assertEquals(0, builder.getFont().getColor().getRGB()); + + // The default color for text is black. If the color of the background is dark, black text will be difficult to see. + // To solve this problem, the AutoColor property will display this text in white. + builder.getFont().getShading().setBackgroundPatternColor(Color.BLUE); + + builder.writeln("The text color automatically chosen for this run is white."); + + Assert.assertEquals(Color.WHITE.getRGB(), doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0).getFont().getAutoColor().getRGB()); + + // If we change the background to a light color, black will be a more + // suitable text color than white so that the auto color will display it in black. + builder.getFont().getShading().setBackgroundPatternColor(Color.RED); + + builder.writeln("The text color automatically chosen for this run is black."); + + Assert.assertEquals(Color.BLACK.getRGB(), doc.getFirstSection().getBody().getParagraphs().get(1).getRuns().get(0).getFont().getAutoColor().getRGB()); + + doc.save(getArtifactsDir() + "Font.SetFontAutoColor.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Font.SetFontAutoColor.docx"); + Run run = doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0); + + Assert.assertEquals("The text color automatically chosen for this run is white.", run.getText().trim()); + Assert.assertEquals(0, run.getFont().getColor().getRGB()); + Assert.assertEquals(Color.BLUE.getRGB(), run.getFont().getShading().getBackgroundPatternColor().getRGB()); + + run = doc.getFirstSection().getBody().getParagraphs().get(1).getRuns().get(0); + + Assert.assertEquals("The text color automatically chosen for this run is black.", run.getText().trim()); + Assert.assertEquals(0, run.getFont().getColor().getRGB()); + Assert.assertEquals(Color.RED.getRGB(), run.getFont().getShading().getBackgroundPatternColor().getRGB()); + } + + //ExStart + //ExFor:Font.Hidden + //ExFor:Paragraph.Accept(DocumentVisitor) + //ExFor:Paragraph.AcceptStart(DocumentVisitor) + //ExFor:Paragraph.AcceptEnd(DocumentVisitor) + //ExFor:DocumentVisitor.VisitParagraphStart(Paragraph) + //ExFor:DocumentVisitor.VisitFormField(FormField) + //ExFor:DocumentVisitor.VisitTableEnd(Table) + //ExFor:DocumentVisitor.VisitCellEnd(Cell) + //ExFor:DocumentVisitor.VisitRowEnd(Row) + //ExFor:DocumentVisitor.VisitSpecialChar(SpecialChar) + //ExFor:DocumentVisitor.VisitGroupShapeStart(GroupShape) + //ExFor:DocumentVisitor.VisitShapeStart(Shape) + //ExFor:DocumentVisitor.VisitCommentStart(Comment) + //ExFor:DocumentVisitor.VisitFootnoteStart(Footnote) + //ExFor:SpecialChar + //ExFor:SpecialChar.Accept(DocumentVisitor) + //ExFor:SpecialChar.GetText + //ExFor:Node.Accept(DocumentVisitor) + //ExFor:Paragraph.ParagraphBreakFont + //ExFor:Table.Accept(DocumentVisitor) + //ExFor:Table.AcceptStart(DocumentVisitor) + //ExFor:Table.AcceptEnd(DocumentVisitor) + //ExSummary:Shows how to use a DocumentVisitor implementation to remove all hidden content from a document. + @Test //ExSkip + public void removeHiddenContentFromDocument() throws Exception { + Document doc = new Document(getMyDir() + "Hidden content.docx"); + Assert.assertEquals(26, doc.getChildNodes(NodeType.PARAGRAPH, true).getCount()); //ExSkip + Assert.assertEquals(2, doc.getChildNodes(NodeType.TABLE, true).getCount()); //ExSkip + + RemoveHiddenContentVisitor hiddenContentRemover = new RemoveHiddenContentVisitor(); + + // Below are three types of fields which can accept a document visitor, + // which will allow it to visit the accepting node, and then traverse its child nodes in a depth-first manner. + // 1 - Paragraph node: + Paragraph para = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 4, true); + para.accept(hiddenContentRemover); + + // 2 - Table node: + Table table = doc.getFirstSection().getBody().getTables().get(0); + table.accept(hiddenContentRemover); + + // 3 - Document node: + doc.accept(hiddenContentRemover); + + doc.save(getArtifactsDir() + "Font.RemoveHiddenContentFromDocument.docx"); + testRemoveHiddenContent(new Document(getArtifactsDir() + "Font.RemoveHiddenContentFromDocument.docx")); //ExSkip + } + + /// <summary> + /// Removes all visited nodes marked as "hidden content". + /// </summary> + public static class RemoveHiddenContentVisitor extends DocumentVisitor { + /// <summary> + /// Called when a FieldStart node is encountered in the document. + /// </summary> + public int visitFieldStart(FieldStart fieldStart) { + if (fieldStart.getFont().getHidden()) + fieldStart.remove(); + + return VisitorAction.CONTINUE; + } + + /// <summary> + /// Called when a FieldEnd node is encountered in the document. + /// </summary> + public int visitFieldEnd(FieldEnd fieldEnd) { + if (fieldEnd.getFont().getHidden()) + fieldEnd.remove(); + + return VisitorAction.CONTINUE; + } + + /// <summary> + /// Called when a FieldSeparator node is encountered in the document. + /// </summary> + public int visitFieldSeparator(FieldSeparator fieldSeparator) { + if (fieldSeparator.getFont().getHidden()) + fieldSeparator.remove(); + + return VisitorAction.CONTINUE; + } + + /// <summary> + /// Called when a Run node is encountered in the document. + /// </summary> + public int visitRun(Run run) { + if (run.getFont().getHidden()) + run.remove(); + + return VisitorAction.CONTINUE; + } + + /// <summary> + /// Called when a Paragraph node is encountered in the document. + /// </summary> + public int visitParagraphStart(Paragraph paragraph) { + if (paragraph.getParagraphBreakFont().getHidden()) + paragraph.remove(); + + return VisitorAction.CONTINUE; + } + + /// <summary> + /// Called when a FormField is encountered in the document. + /// </summary> + public int visitFormField(FormField formField) { + if (formField.getFont().getHidden()) + formField.remove(); + + return VisitorAction.CONTINUE; + } + + /// <summary> + /// Called when a GroupShape is encountered in the document. + /// </summary> + public int visitGroupShapeStart(GroupShape groupShape) { + if (groupShape.getFont().getHidden()) + groupShape.remove(); + + return VisitorAction.CONTINUE; + } + + /// <summary> + /// Called when a Shape is encountered in the document. + /// </summary> + public int visitShapeStart(Shape shape) { + if (shape.getFont().getHidden()) + shape.remove(); + + return VisitorAction.CONTINUE; + } + + /// <summary> + /// Called when a Comment is encountered in the document. + /// </summary> + public int visitCommentStart(Comment comment) { + if (comment.getFont().getHidden()) + comment.remove(); + + return VisitorAction.CONTINUE; + } + + /// <summary> + /// Called when a Footnote is encountered in the document. + /// </summary> + public int visitFootnoteStart(Footnote footnote) { + if (footnote.getFont().getHidden()) + footnote.remove(); + + return VisitorAction.CONTINUE; + } + + /// <summary> + /// Called when a SpecialCharacter is encountered in the document. + /// </summary> + public int visitSpecialChar(SpecialChar specialChar) { + if (specialChar.getFont().getHidden()) + specialChar.remove(); + + return VisitorAction.CONTINUE; + } + + /// <summary> + /// Called when visiting of a Table node is ended in the document. + /// </summary> + public int visitTableEnd(Table table) { + // The content inside table cells may have the hidden content flag, but the tables themselves cannot. + // If this table had nothing but hidden content, this visitor would have removed all of it, + // and there would be no child nodes left. + // Thus, we can also treat the table itself as hidden content and remove it. + // Tables which are empty but do not have hidden content will have cells with empty paragraphs inside, + // which this visitor will not remove. + if (!table.hasChildNodes()) + table.remove(); + + return VisitorAction.CONTINUE; + } + + /// <summary> + /// Called when visiting of a Cell node is ended in the document. + /// </summary> + public int visitCellEnd(Cell cell) { + if (!cell.hasChildNodes() && cell.getParentNode() != null) + cell.remove(); + + return VisitorAction.CONTINUE; + } + + /// <summary> + /// Called when visiting of a Row node is ended in the document. + /// </summary> + public int visitRowEnd(Row row) { + if (!row.hasChildNodes() && row.getParentNode() != null) + row.remove(); + + return VisitorAction.CONTINUE; + } + } + //ExEnd + + private void testRemoveHiddenContent(Document doc) { + Assert.assertEquals(20, doc.getChildNodes(NodeType.PARAGRAPH, true).getCount()); //ExSkip + Assert.assertEquals(1, doc.getChildNodes(NodeType.TABLE, true).getCount()); //ExSkip + + for (Node node : (Iterable<Node>) doc.getChildNodes(NodeType.ANY, true)) { + switch (node.getNodeType()) { + case NodeType.FIELD_START: + FieldStart fieldStart = (FieldStart) node; + Assert.assertFalse(fieldStart.getFont().getHidden()); + break; + case NodeType.FIELD_END: + FieldEnd fieldEnd = (FieldEnd) node; + Assert.assertFalse(fieldEnd.getFont().getHidden()); + break; + case NodeType.FIELD_SEPARATOR: + FieldSeparator fieldSeparator = (FieldSeparator) node; + Assert.assertFalse(fieldSeparator.getFont().getHidden()); + break; + case NodeType.RUN: + Run run = (Run) node; + Assert.assertFalse(run.getFont().getHidden()); + break; + case NodeType.PARAGRAPH: + Paragraph paragraph = (Paragraph) node; + Assert.assertFalse(paragraph.getParagraphBreakFont().getHidden()); + break; + case NodeType.FORM_FIELD: + FormField formField = (FormField) node; + Assert.assertFalse(formField.getFont().getHidden()); + break; + case NodeType.GROUP_SHAPE: + GroupShape groupShape = (GroupShape) node; + Assert.assertFalse(groupShape.getFont().getHidden()); + break; + case NodeType.SHAPE: + Shape shape = (Shape) node; + Assert.assertFalse(shape.getFont().getHidden()); + break; + case NodeType.COMMENT: + Comment comment = (Comment) node; + Assert.assertFalse(comment.getFont().getHidden()); + break; + case NodeType.FOOTNOTE: + Footnote footnote = (Footnote) node; + Assert.assertFalse(footnote.getFont().getHidden()); + break; + case NodeType.SPECIAL_CHAR: + SpecialChar specialChar = (SpecialChar) node; + Assert.assertFalse(specialChar.getFont().getHidden()); + break; + } + } + } + + @Test + public void defaultFonts() throws Exception { + //ExStart + //ExFor:FontInfoCollection.Contains(String) + //ExFor:FontInfoCollection.Count + //ExSummary:Shows info about the fonts that are present in the blank document. + Document doc = new Document(); + + // A blank document contains 3 default fonts. Each font in the document + // will have a corresponding FontInfo object which contains details about that font. + Assert.assertEquals(3, doc.getFontInfos().getCount()); + + Assert.assertTrue(doc.getFontInfos().contains("Times New Roman")); + Assert.assertEquals(204, doc.getFontInfos().get("Times New Roman").getCharset()); + + Assert.assertTrue(doc.getFontInfos().contains("Symbol")); + Assert.assertTrue(doc.getFontInfos().contains("Arial")); + //ExEnd + } + + @Test + public void extractEmbeddedFont() throws Exception { + //ExStart + //ExFor:EmbeddedFontFormat + //ExFor:EmbeddedFontStyle + //ExFor:FontInfo.GetEmbeddedFont(EmbeddedFontFormat,EmbeddedFontStyle) + //ExFor:FontInfo.GetEmbeddedFontAsOpenType(EmbeddedFontStyle) + //ExFor:FontInfoCollection.Item(Int32) + //ExFor:FontInfoCollection.Item(String) + //ExSummary:Shows how to extract an embedded font from a document, and save it to the local file system. + Document doc = new Document(getMyDir() + "Embedded font.docx"); + + FontInfo embeddedFont = doc.getFontInfos().get("Alte DIN 1451 Mittelschrift"); + byte[] embeddedFontBytes = embeddedFont.getEmbeddedFont(EmbeddedFontFormat.OPEN_TYPE, EmbeddedFontStyle.REGULAR); + Assert.assertNotNull(embeddedFontBytes); //ExSkip + + FileUtils.writeByteArrayToFile(new File(getArtifactsDir() + "Alte DIN 1451 Mittelschrift.ttf"), embeddedFontBytes); + + // Embedded font formats may be different in other formats such as .doc. + // We need to know the correct format before we can extract the font. + doc = new Document(getMyDir() + "Embedded font.doc"); + + Assert.assertNull(doc.getFontInfos().get("Alte DIN 1451 Mittelschrift").getEmbeddedFont(EmbeddedFontFormat.OPEN_TYPE, EmbeddedFontStyle.REGULAR)); + Assert.assertNotNull(doc.getFontInfos().get("Alte DIN 1451 Mittelschrift").getEmbeddedFont(EmbeddedFontFormat.EMBEDDED_OPEN_TYPE, EmbeddedFontStyle.REGULAR)); + + // Also, we can convert embedded OpenType format, which comes from .doc documents, to OpenType. + embeddedFontBytes = doc.getFontInfos().get("Alte DIN 1451 Mittelschrift").getEmbeddedFontAsOpenType(EmbeddedFontStyle.REGULAR); + + FileUtils.writeByteArrayToFile(new File(getArtifactsDir() + "Alte DIN 1451 Mittelschrift.otf"), embeddedFontBytes); + //ExEnd + } + + @Test + public void getFontInfoFromFile() throws Exception { + //ExStart + //ExFor:FontFamily + //ExFor:FontPitch + //ExFor:FontInfo.AltName + //ExFor:FontInfo.Charset + //ExFor:FontInfo.Family + //ExFor:FontInfo.Panose + //ExFor:FontInfo.Pitch + //ExFor:FontInfoCollection.GetEnumerator + //ExSummary:Shows how to access and print details of each font in a document. + Document doc = new Document(getMyDir() + "Document.docx"); + + Iterator<FontInfo> fontCollectionEnumerator = doc.getFontInfos().iterator(); + while (fontCollectionEnumerator.hasNext()) { + FontInfo fontInfo = fontCollectionEnumerator.next(); + if (fontInfo != null) { + System.out.println("Font name: " + fontInfo.getName()); + + // Alt names are usually blank. + System.out.println("Alt name: " + fontInfo.getAltName()); + System.out.println("\t- Family: " + fontInfo.getFamily()); + System.out.println("\t- " + (fontInfo.isTrueType() ? "Is TrueType" : "Is not TrueType")); + System.out.println("\t- Pitch: " + fontInfo.getPitch()); + System.out.println("\t- Charset: " + fontInfo.getCharset()); + System.out.println("\t- Panose:"); + System.out.println("\t\tFamily Kind: " + (fontInfo.getPanose()[0] & 0xFF)); + System.out.println("\t\tSerif Style: " + (fontInfo.getPanose()[1] & 0xFF)); + System.out.println("\t\tWeight: " + (fontInfo.getPanose()[2] & 0xFF)); + System.out.println("\t\tProportion: " + (fontInfo.getPanose()[3] & 0xFF)); + System.out.println("\t\tContrast: " + (fontInfo.getPanose()[4] & 0xFF)); + System.out.println("\t\tStroke Variation: " + (fontInfo.getPanose()[5] & 0xFF)); + System.out.println("\t\tArm Style: " + (fontInfo.getPanose()[6] & 0xFF)); + System.out.println("\t\tLetterform: " + (fontInfo.getPanose()[7] & 0xFF)); + System.out.println("\t\tMidline: " + (fontInfo.getPanose()[8] & 0xFF)); + System.out.println("\t\tX-Height: " + (fontInfo.getPanose()[9] & 0xFF)); + } + } + //ExEnd + + Assert.assertEquals(new byte[] { 2, 15, 5, 2, 2, 2, 4, 3, 2, 4 }, doc.getFontInfos().get("Calibri").getPanose()); + Assert.assertEquals(new byte[] { 2, 15, 3, 2, 2, 2, 4, 3, 2, 4 }, doc.getFontInfos().get("Calibri Light").getPanose()); + Assert.assertEquals(new byte[] { 2, 2, 6, 3, 5, 4, 5, 2, 3, 4 }, doc.getFontInfos().get("Times New Roman").getPanose()); + } + + @Test + public void lineSpacing() throws Exception { + //ExStart + //ExFor:Font.LineSpacing + //ExSummary:Shows how to get a font's line spacing, in points. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Set different fonts for the DocumentBuilder, and verify their line spacing. + builder.getFont().setName("Calibri"); + Assert.assertEquals(13.7d, builder.getFont().getLineSpacing(), 1); + + builder.getFont().setName("Times New Roman"); + Assert.assertEquals(13.7d, builder.getFont().getLineSpacing(), 1); + //ExEnd + } + + @Test + public void hasDmlEffect() throws Exception { + //ExStart + //ExFor:Font.HasDmlEffect(TextDmlEffect) + //ExFor:TextDmlEffect + //ExSummary:Shows how to check if a run displays a DrawingML text effect. + Document doc = new Document(getMyDir() + "DrawingML text effects.docx"); + + RunCollection runs = doc.getFirstSection().getBody().getFirstParagraph().getRuns(); + + Assert.assertTrue(runs.get(0).getFont().hasDmlEffect(TextDmlEffect.SHADOW)); + Assert.assertTrue(runs.get(1).getFont().hasDmlEffect(TextDmlEffect.SHADOW)); + Assert.assertTrue(runs.get(2).getFont().hasDmlEffect(TextDmlEffect.REFLECTION)); + Assert.assertTrue(runs.get(3).getFont().hasDmlEffect(TextDmlEffect.EFFECT_3_D)); + Assert.assertTrue(runs.get(4).getFont().hasDmlEffect(TextDmlEffect.FILL)); + //ExEnd + } + + @Test + public void checkScanUserFontsFolder() { + String userProfile = System.getenv("USERPROFILE"); + String currentUserFontsFolder = Paths.get(userProfile, "AppData\\Local\\Microsoft\\Windows\\Fonts").toString(); + ArrayList<String> currentUserFonts = DocumentHelper.directoryGetFiles(currentUserFontsFolder, "*.ttf"); + if (currentUserFonts.size() != 0) { + // On Windows 10 fonts may be installed either into system folder "%windir%\fonts" for all users + // or into user folder "%userprofile%\AppData\Local\Microsoft\Windows\Fonts" for current user. + SystemFontSource systemFontSource = new SystemFontSource(); + Assert.assertNotNull(systemFontSource.getAvailableFonts().stream(). + filter((x) -> x.getFilePath().contains("\\AppData\\Local\\Microsoft\\Windows\\Fonts")).findFirst(), + "Fonts did not install to the user font folder"); + } + } + + @Test(dataProvider = "setEmphasisMarkDataProvider") + public void setEmphasisMark(int emphasisMark) throws Exception { + //ExStart + //ExFor:EmphasisMark + //ExFor:Font.EmphasisMark + //ExSummary:Shows how to add additional character rendered above/below the glyph-character. + DocumentBuilder builder = new DocumentBuilder(); + + // Possible types of emphasis mark: + // https://apireference.aspose.com/words/net/aspose.words/emphasismark + builder.getFont().setEmphasisMark(emphasisMark); + + builder.write("Emphasis text"); + builder.writeln(); + builder.getFont().clearFormatting(); + builder.write("Simple text"); + + builder.getDocument().save(getArtifactsDir() + "Fonts.SetEmphasisMark.docx"); + //ExEnd + } + + @DataProvider(name = "setEmphasisMarkDataProvider") + public static Object[][] setEmphasisMarkDataProvider() { + return new Object[][] + { + {EmphasisMark.NONE}, + {EmphasisMark.OVER_COMMA}, + {EmphasisMark.OVER_SOLID_CIRCLE}, + {EmphasisMark.OVER_WHITE_CIRCLE}, + {EmphasisMark.UNDER_SOLID_CIRCLE}, + }; + } + + @Test + public void themeFontsColors() throws Exception + { + //ExStart + //ExFor:Font.ThemeFont + //ExFor:Font.ThemeFontAscii + //ExFor:Font.ThemeFontBi + //ExFor:Font.ThemeFontFarEast + //ExFor:Font.ThemeFontOther + //ExFor:Font.ThemeColor + //ExFor:ThemeFont + //ExFor:ThemeColor + //ExSummary:Shows how to work with theme fonts and colors. + Document doc = new Document(); + + // Define fonts for languages uses by default. + doc.getTheme().getMinorFonts().setLatin("Algerian"); + doc.getTheme().getMinorFonts().setEastAsian("Aharoni"); + doc.getTheme().getMinorFonts().setComplexScript("Andalus"); + + Font font = doc.getStyles().get("Normal").getFont(); + System.out.println(MessageFormat.format("Originally the Normal style theme color is: {0} and RGB color is: {1}\n", font.getThemeColor(), font.getColor())); + + // We can use theme font and color instead of default values. + font.setThemeFont(ThemeFont.MINOR); + font.setThemeColor(ThemeColor.ACCENT_2); + + Assert.assertEquals(ThemeFont.MINOR, font.getThemeFont()); + Assert.assertEquals("Algerian", font.getName()); + + Assert.assertEquals(ThemeFont.MINOR, font.getThemeFontAscii()); + Assert.assertEquals("Algerian", font.getNameAscii()); + + Assert.assertEquals(ThemeFont.MINOR, font.getThemeFontBi()); + Assert.assertEquals("Andalus", font.getNameBi()); + + Assert.assertEquals(ThemeFont.MINOR, font.getThemeFontFarEast()); + Assert.assertEquals("Aharoni", font.getNameFarEast()); + + Assert.assertEquals(ThemeFont.MINOR, font.getThemeFontOther()); + Assert.assertEquals("Algerian", font.getNameOther()); + + Assert.assertEquals(ThemeColor.ACCENT_2, font.getThemeColor()); + Assert.assertEquals(0, font.getColor().getRGB()); + + // There are several ways of reset them font and color. + // 1 - By setting ThemeFont.None/ThemeColor.None: + font.setThemeFont(ThemeFont.NONE); + font.setThemeColor(ThemeColor.NONE); + + Assert.assertEquals(ThemeFont.NONE, font.getThemeFont()); + Assert.assertEquals("Algerian", font.getName()); + + Assert.assertEquals(ThemeFont.NONE, font.getThemeFontAscii()); + Assert.assertEquals("Algerian", font.getNameAscii()); + + Assert.assertEquals(ThemeFont.NONE, font.getThemeFontBi()); + Assert.assertEquals("Andalus", font.getNameBi()); + + Assert.assertEquals(ThemeFont.NONE, font.getThemeFontFarEast()); + Assert.assertEquals("Aharoni", font.getNameFarEast()); + + Assert.assertEquals(ThemeFont.NONE, font.getThemeFontOther()); + Assert.assertEquals("Algerian", font.getNameOther()); + + Assert.assertEquals(ThemeColor.NONE, font.getThemeColor()); + Assert.assertEquals(0, font.getColor().getRGB()); + + // 2 - By setting non-theme font/color names: + font.setName("Arial"); + font.setColor(Color.BLUE); + + Assert.assertEquals(ThemeFont.NONE, font.getThemeFont()); + Assert.assertEquals("Arial", font.getName()); + + Assert.assertEquals(ThemeFont.NONE, font.getThemeFontAscii()); + Assert.assertEquals("Arial", font.getNameAscii()); + + Assert.assertEquals(ThemeFont.NONE, font.getThemeFontBi()); + Assert.assertEquals("Arial", font.getNameBi()); + + Assert.assertEquals(ThemeFont.NONE, font.getThemeFontFarEast()); + Assert.assertEquals("Arial", font.getNameFarEast()); + + Assert.assertEquals(ThemeFont.NONE, font.getThemeFontOther()); + Assert.assertEquals("Arial", font.getNameOther()); + + Assert.assertEquals(ThemeColor.NONE, font.getThemeColor()); + Assert.assertEquals(Color.BLUE.getRGB(), font.getColor().getRGB()); + //ExEnd + } + + @Test + public void createThemedStyle() throws Exception + { + //ExStart + //ExFor:Font.ThemeFont + //ExFor:Font.ThemeColor + //ExFor:Font.TintAndShade + //ExFor:ThemeFont + //ExFor:ThemeColor + //ExSummary:Shows how to create and use themed style. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln(); + + // Create some style with theme font properties. + Style style = doc.getStyles().add(StyleType.PARAGRAPH, "ThemedStyle"); + style.getFont().setThemeFont(ThemeFont.MAJOR); + style.getFont().setThemeColor(ThemeColor.ACCENT_5); + style.getFont().setTintAndShade(0.3); + + builder.getParagraphFormat().setStyleName("ThemedStyle"); + builder.writeln("Text with themed style"); + //ExEnd + + Run run = (Run)((Paragraph)builder.getCurrentParagraph().getPreviousSibling()).getFirstChild(); + + Assert.assertEquals(ThemeFont.MAJOR, run.getFont().getThemeFont()); + Assert.assertEquals("Times New Roman", run.getFont().getName()); + + Assert.assertEquals(ThemeFont.MAJOR, run.getFont().getThemeFontAscii()); + Assert.assertEquals("Times New Roman", run.getFont().getNameAscii()); + + Assert.assertEquals(ThemeFont.MAJOR, run.getFont().getThemeFontBi()); + Assert.assertEquals("Times New Roman", run.getFont().getNameBi()); + + Assert.assertEquals(ThemeFont.MAJOR, run.getFont().getThemeFontFarEast()); + Assert.assertEquals("Times New Roman", run.getFont().getNameFarEast()); + + Assert.assertEquals(ThemeFont.MAJOR, run.getFont().getThemeFontOther()); + Assert.assertEquals("Times New Roman", run.getFont().getNameOther()); + + Assert.assertEquals(ThemeColor.ACCENT_5, run.getFont().getThemeColor()); + Assert.assertEquals(0, run.getFont().getColor().getRGB()); + } + + @Test + public void fontInfoEmbeddingLicensingRights() throws Exception + { + //ExStart:FontInfoEmbeddingLicensingRights + //GistId:0ede368e82d1e97d02e615a76923846b + //ExFor:FontInfo.EmbeddingLicensingRights + //ExFor:FontEmbeddingUsagePermissions + //ExFor:FontEmbeddingLicensingRights + //ExFor:FontEmbeddingLicensingRights.EmbeddingUsagePermissions + //ExFor:FontEmbeddingLicensingRights.BitmapEmbeddingOnly + //ExFor:FontEmbeddingLicensingRights.NoSubsetting + //ExSummary:Shows how to get license rights information for embedded fonts (FontInfo). + Document doc = new Document(getMyDir() + "Embedded font rights.docx"); + + // Get the list of document fonts. + FontInfoCollection fontInfos = doc.getFontInfos(); + for (FontInfo fontInfo : fontInfos) + { + if (fontInfo.getEmbeddingLicensingRights() != null) + { + System.out.println(fontInfo.getEmbeddingLicensingRights().getEmbeddingUsagePermissions()); + System.out.println(fontInfo.getEmbeddingLicensingRights().getBitmapEmbeddingOnly()); + System.out.println(fontInfo.getEmbeddingLicensingRights().getNoSubsetting()); + } + } + //ExEnd:FontInfoEmbeddingLicensingRights + } + + @Test + public void physicalFontInfoEmbeddingLicensingRights() + { + //ExStart:PhysicalFontInfoEmbeddingLicensingRights + //GistId:0ede368e82d1e97d02e615a76923846b + //ExFor:PhysicalFontInfo.EmbeddingLicensingRights + //ExSummary:Shows how to get license rights information for embedded fonts (PhysicalFontInfo). + FontSettings settings = FontSettings.getDefaultInstance(); + FontSourceBase source = settings.getFontsSources()[0]; + + // Get the list of available fonts. + ArrayList<PhysicalFontInfo> fontInfos = source.getAvailableFonts(); + for (PhysicalFontInfo fontInfo : fontInfos) + { + if (fontInfo.getEmbeddingLicensingRights() != null) + { + System.out.println(fontInfo.getEmbeddingLicensingRights().getEmbeddingUsagePermissions()); + System.out.println(fontInfo.getEmbeddingLicensingRights().getBitmapEmbeddingOnly()); + System.out.println(fontInfo.getEmbeddingLicensingRights().getNoSubsetting()); + } + } + //ExEnd:PhysicalFontInfoEmbeddingLicensingRights + } + + @Test + public void numberSpacing() throws Exception + { + //ExStart:NumberSpacing + //GistId:8c0f38c5965151e1cdf79c1c8f9e4640 + //ExFor:Font.NumberSpacing + //ExFor:NumSpacing + //ExSummary:Shows how to set the spacing type of the numeral. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // This effect is only supported in newer versions of MS Word. + doc.getCompatibilityOptions().optimizeFor(MsWordVersion.WORD_2019); + + builder.write("1 "); + builder.write("This is an example"); + + Run run = doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0); + if (run.getFont().getNumberSpacing() == NumSpacing.DEFAULT) + run.getFont().setNumberSpacing(NumSpacing.PROPORTIONAL); + + doc.save(getArtifactsDir() + "Fonts.NumberSpacing.docx"); + //ExEnd:NumberSpacing + + doc = new Document(getArtifactsDir() + "Fonts.NumberSpacing.docx"); + + run = doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0); + Assert.assertEquals(NumSpacing.PROPORTIONAL, run.getFont().getNumberSpacing()); + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExFontSettings.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExFontSettings.java new file mode 100644 index 00000000..0839baba --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExFontSettings.java @@ -0,0 +1,1184 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.apache.commons.collections4.IterableUtils; +import org.apache.commons.lang.SystemUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.io.*; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Stream; + +public class ExFontSettings extends ApiExampleBase { + @Test + public void defaultFontInstance() throws Exception { + //ExStart + //ExFor:FontSettings.DefaultInstance + //ExSummary:Shows how to configure the default font settings instance. + // Configure the default font settings instance to use the "Courier New" font + // as a backup substitute when we attempt to use an unknown font. + FontSettings.getDefaultInstance().getSubstitutionSettings().getDefaultFontSubstitution().setDefaultFontName("Courier New"); + + Assert.assertTrue(FontSettings.getDefaultInstance().getSubstitutionSettings().getDefaultFontSubstitution().getEnabled()); + + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Non-existent font"); + builder.write("Hello world!"); + + // This document does not have a FontSettings configuration. When we render the document, + // the default FontSettings instance will resolve the missing font. + // Aspose.Words will use "Courier New" to render text that uses the unknown font. + Assert.assertNull(doc.getFontSettings()); + + doc.save(getArtifactsDir() + "FontSettings.DefaultFontInstance.pdf"); + //ExEnd + } + + @Test + public void defaultFontName() throws Exception { + //ExStart + //ExFor:DefaultFontSubstitutionRule.DefaultFontName + //ExSummary:Shows how to specify a default font. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Arial"); + builder.writeln("Hello world!"); + builder.getFont().setName("Arvo"); + builder.writeln("The quick brown fox jumps over the lazy dog."); + + FontSourceBase[] fontSources = FontSettings.getDefaultInstance().getFontsSources(); + + // The font sources that the document uses contain the font "Arial", but not "Arvo". + Assert.assertEquals(1, fontSources.length); + Assert.assertTrue(IterableUtils.matchesAny(fontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Arial"))); + Assert.assertFalse(IterableUtils.matchesAny(fontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Arvo"))); + + // Set the "DefaultFontName" property to "Courier New" to, + // while rendering the document, apply that font in all cases when another font is not available. + FontSettings.getDefaultInstance().getSubstitutionSettings().getDefaultFontSubstitution().setDefaultFontName("Courier New"); + + Assert.assertTrue(IterableUtils.matchesAny(fontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Courier New"))); + + // Aspose.Words will now use the default font in place of any missing fonts during any rendering calls. + doc.save(getArtifactsDir() + "FontSettings.DefaultFontName.pdf"); + //ExEnd + } + + @Test + public void updatePageLayoutWarnings() throws Exception { + // Store the font sources currently used so we can restore them later. + FontSourceBase[] originalFontSources = FontSettings.getDefaultInstance().getFontsSources(); + + // Load the document to render. + Document doc = new Document(getMyDir() + "Document.docx"); + + // Create a new class implementing IWarningCallback and assign it to the PdfSaveOptions class. + HandleDocumentWarnings callback = new HandleDocumentWarnings(); + doc.setWarningCallback(callback); + + // We can choose the default font to use in the case of any missing fonts. + FontSettings.getDefaultInstance().getSubstitutionSettings().getDefaultFontSubstitution().setDefaultFontName("Arial"); + + // For testing we will set Aspose.Words to look for fonts only in a folder which does not exist. Since Aspose.Words won't + // find any fonts in the specified directory, then during rendering the fonts in the document will be substituted with the default + // font specified under FontSettings.DefaultFontName. We can pick up on this substitution using our callback. + FontSettings.getDefaultInstance().setFontsFolder("", false); + + // When you call UpdatePageLayout the document is rendered in memory. Any warnings that occurred during rendering + // are stored until the document save and then sent to the appropriate WarningCallback. + doc.updatePageLayout(); + + // Even though the document was rendered previously, any save warnings are notified to the user during document save. + doc.save(getArtifactsDir() + "FontSettings.UpdatePageLayoutWarnings.pdf"); + + Assert.assertTrue(callback.FontWarnings.getCount() > 0); + Assert.assertTrue(callback.FontWarnings.get(0).getWarningType() == WarningType.FONT_SUBSTITUTION); + Assert.assertTrue(callback.FontWarnings.get(0).getDescription().contains("has not been found")); + + // Restore default fonts. + FontSettings.getDefaultInstance().setFontsSources(originalFontSources); + } + + public static class HandleDocumentWarnings implements IWarningCallback { + /// <summary> + /// Our callback only needs to implement the "Warning" method. This method is called whenever there is a + /// potential issue during document processing. The callback can be set to listen for warnings generated during document + /// load and/or document save. + /// </summary> + public void warning(WarningInfo info) { + // We are only interested in fonts being substituted. + if (info.getWarningType() == WarningType.FONT_SUBSTITUTION) { + System.out.println("Font substitution: " + info.getDescription()); + FontWarnings.warning(info); + } + } + + public WarningInfoCollection FontWarnings = new WarningInfoCollection(); + } + + //ExStart + //ExFor:IWarningCallback + //ExFor:DocumentBase.WarningCallback + //ExFor:FontSettings.DefaultInstance + //ExSummary:Shows how to use the IWarningCallback interface to monitor font substitution warnings. + @Test //ExSkip + public void substitutionWarning() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Times New Roman"); + builder.writeln("Hello world!"); + + FontSubstitutionWarningCollector callback = new FontSubstitutionWarningCollector(); + doc.setWarningCallback(callback); + + // Store the current collection of font sources, which will be the default font source for every document + // for which we do not specify a different font source. + FontSourceBase[] originalFontSources = FontSettings.getDefaultInstance().getFontsSources(); + + // For testing purposes, we will set Aspose.Words to look for fonts only in a folder that does not exist. + FontSettings.getDefaultInstance().setFontsFolder("", false); + + // When rendering the document, there will be no place to find the "Times New Roman" font. + // This will cause a font substitution warning, which our callback will detect. + doc.save(getArtifactsDir() + "FontSettings.SubstitutionWarning.pdf"); + + FontSettings.getDefaultInstance().setFontsSources(originalFontSources); + + Assert.assertEquals(1, callback.FontSubstitutionWarnings.getCount()); //ExSkip + Assert.assertTrue(callback.FontSubstitutionWarnings.get(0).getWarningType() == WarningType.FONT_SUBSTITUTION); + Assert.assertTrue(callback.FontSubstitutionWarnings.get(0).getDescription() + .equals("Font 'Times New Roman' has not been found. Using 'Fanwood' font instead. Reason: first available font.")); + } + + private static class FontSubstitutionWarningCollector implements IWarningCallback { + /// <summary> + /// Called every time a warning occurs during loading/saving. + /// </summary> + public void warning(WarningInfo info) { + if (info.getWarningType() == WarningType.FONT_SUBSTITUTION) + FontSubstitutionWarnings.warning(info); + } + + public WarningInfoCollection FontSubstitutionWarnings = new WarningInfoCollection(); + } + //ExEnd + + //ExStart + //ExFor:FontSourceBase.WarningCallback + //ExSummary:Shows how to call warning callback when the font sources working with. + @Test//ExSkip + public void fontSourceWarning() + { + FontSettings settings = new FontSettings(); + settings.setFontsFolder("bad folder?", false); + + FontSourceBase source = settings.getFontsSources()[0]; + FontSourceWarningCollector callback = new FontSourceWarningCollector(); + source.setWarningCallback(callback); + + // Get the list of fonts to call warning callback. + ArrayList<PhysicalFontInfo> fontInfos = source.getAvailableFonts(); + + Assert.assertEquals("Error loading font from the folder \"bad folder?\": ", + callback.FontSubstitutionWarnings.get(0).getDescription()); + } + + private static class FontSourceWarningCollector implements IWarningCallback + { + /// <summary> + /// Called every time a warning occurs during processing of font source. + /// </summary> + public void warning(WarningInfo info) + { + FontSubstitutionWarnings.warning(info); + } + + public WarningInfoCollection FontSubstitutionWarnings = new WarningInfoCollection(); + } + //ExEnd + + + @Test + public void enableFontSubstitution() throws Exception + { + //ExStart + //ExFor:FontInfoSubstitutionRule + //ExFor:FontSubstitutionSettings.FontInfoSubstitution + //ExFor:LayoutOptions.KeepOriginalFontMetrics + //ExFor:IWarningCallback + //ExFor:IWarningCallback.Warning(WarningInfo) + //ExFor:WarningInfo + //ExFor:WarningInfo.Description + //ExFor:WarningInfo.WarningType + //ExFor:WarningInfoCollection + //ExFor:WarningInfoCollection.Warning(WarningInfo) + //ExFor:WarningInfoCollection.Clear + //ExFor:WarningType + //ExFor:DocumentBase.WarningCallback + //ExSummary:Shows how to set the property for finding the closest match for a missing font from the available font sources. + // Open a document that contains text formatted with a font that does not exist in any of our font sources. + Document doc = new Document(getMyDir() + "Missing font.docx"); + + // Assign a callback for handling font substitution warnings. + WarningInfoCollection warningCollector = new WarningInfoCollection(); + doc.setWarningCallback(warningCollector); + + // Set a default font name and enable font substitution. + FontSettings fontSettings = new FontSettings(); + fontSettings.getSubstitutionSettings().getDefaultFontSubstitution().setDefaultFontName("Arial"); + fontSettings.getSubstitutionSettings().getFontInfoSubstitution().setEnabled(true); + + // Original font metrics should be used after font substitution. + doc.getLayoutOptions().setKeepOriginalFontMetrics(true); + + // We will get a font substitution warning if we save a document with a missing font. + doc.setFontSettings(fontSettings); + doc.save(getArtifactsDir() + "FontSettings.EnableFontSubstitution.pdf"); + + for (WarningInfo info : warningCollector) + { + if (info.getWarningType() == WarningType.FONT_SUBSTITUTION) + System.out.println(info.getDescription()); + } + //ExEnd + + // We can also verify warnings in the collection and clear them. + Assert.assertEquals(WarningSource.LAYOUT, warningCollector.get(0).getSource()); + Assert.assertEquals("Font '28 Days Later' has not been found. Using 'Calibri' font instead. Reason: alternative name from document.", warningCollector.get(0).getDescription()); + + warningCollector.clear(); + + Assert.assertEquals(0, warningCollector.getCount()); + } + + + @Test + public void substitutionWarningsClosestMatch() throws Exception { + Document doc = new Document(getMyDir() + "Bullet points with alternative font.docx"); + + WarningInfoCollection callback = new WarningInfoCollection(); + doc.setWarningCallback(callback); + + doc.save(getArtifactsDir() + "FontSettings.SubstitutionWarningsClosestMatch.pdf"); + + Assert.assertTrue(callback.get(0).getDescription() + .equals("Font \'SymbolPS\' has not been found. Using \'Wingdings\' font instead. Reason: font info substitution.")); + } + + @Test + public void disableFontSubstitution() throws Exception { + Document doc = new Document(getMyDir() + "Missing font.docx"); + + WarningInfoCollection callback = new WarningInfoCollection(); + doc.setWarningCallback(callback); + + FontSettings fontSettings = new FontSettings(); + fontSettings.getSubstitutionSettings().getDefaultFontSubstitution().setDefaultFontName("Arial"); + fontSettings.getSubstitutionSettings().getFontInfoSubstitution().setEnabled(false); + + doc.setFontSettings(fontSettings); + doc.save(getArtifactsDir() + "FontSettings.DisableFontSubstitution.pdf"); + + Pattern pattern = Pattern.compile("Font '28 Days Later' has not been found. Using (.*) font instead. Reason: alternative name from document."); + + for (WarningInfo fontWarning : callback) { + Matcher match = pattern.matcher(fontWarning.getDescription()); + if (match.find() == false) { + Assert.fail(); + break; + } + } + } + + @Test + public void substitutionWarnings() throws Exception + { + //ExStart:SubstitutionWarnings + //GistId:045648ef22da6b384ebcf0344717bfb5 + //ExFor:FontSubstitutionWarningInfo + //ExFor:FontSubstitutionWarningInfo.Reason + //ExFor:FontSubstitutionWarningInfo.RequestedBold + //ExFor:FontSubstitutionWarningInfo.RequestedItalic + //ExFor:FontSubstitutionWarningInfo.RequestedFamilyName + //ExFor:WarningInfo.Source + //ExFor:WarningInfo.WarningType + //ExFor:WarningInfo.Description + //ExFor:WarningSource + //ExFor:FontSubstitutionReason + //ExSummary:Shows how to get additional information about font substitution. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + WarningInfoCollection callback = new WarningInfoCollection(); + doc.setWarningCallback(callback); + + FontSettings fontSettings = new FontSettings(); + fontSettings.getSubstitutionSettings().getDefaultFontSubstitution().setDefaultFontName("Arial"); + fontSettings.setFontsFolder(getFontsDir(), false); + fontSettings.getSubstitutionSettings().getTableSubstitution().addSubstitutes("Arial", "Arvo", "Slab"); + + doc.setFontSettings(fontSettings); + doc.save(getArtifactsDir() + "FontSettings.SubstitutionWarnings.pdf"); + + FontSubstitutionWarningInfo warningInfo = (FontSubstitutionWarningInfo)callback.get(0); + Assert.assertEquals(WarningSource.LAYOUT, warningInfo.getSource()); + Assert.assertEquals(WarningType.FONT_SUBSTITUTION, warningInfo.getWarningType()); + Assert.assertEquals(FontSubstitutionReason.TABLE_SUBSTITUTION_RULE, warningInfo.getReason()); + Assert.assertEquals("Font \'Arial\' has not been found. Using \'Arvo\' font instead. Reason: table substitution.", warningInfo.getDescription()); + Assert.assertTrue(warningInfo.getRequestedBold()); + Assert.assertFalse(warningInfo.getRequestedItalic()); + Assert.assertEquals("Arial", warningInfo.getRequestedFamilyName()); + //ExEnd:SubstitutionWarnings + } + + @Test + public void fontSourceFile() throws Exception + { + //ExStart + //ExFor:FileFontSource + //ExFor:FileFontSource.#ctor(String) + //ExFor:FileFontSource.#ctor(String, Int32) + //ExFor:FileFontSource.FilePath + //ExFor:FileFontSource.Type + //ExFor:FontSourceBase + //ExFor:FontSourceBase.Priority + //ExFor:FontSourceBase.Type + //ExFor:FontSourceType + //ExSummary:Shows how to use a font file in the local file system as a font source. + FileFontSource fileFontSource = new FileFontSource(getMyDir() + "Alte DIN 1451 Mittelschrift.ttf", 0); + + Document doc = new Document(); + doc.setFontSettings(new FontSettings()); + doc.getFontSettings().setFontsSources(new FontSourceBase[]{fileFontSource}); + + Assert.assertEquals(getMyDir() + "Alte DIN 1451 Mittelschrift.ttf", fileFontSource.getFilePath()); + Assert.assertEquals(FontSourceType.FONT_FILE, fileFontSource.getType()); + Assert.assertEquals(0, fileFontSource.getPriority()); + //ExEnd + } + + @Test + public void fontSourceFolder() throws Exception { + //ExStart + //ExFor:FolderFontSource + //ExFor:FolderFontSource.#ctor(String, Boolean) + //ExFor:FolderFontSource.#ctor(String, Boolean, Int32) + //ExFor:FolderFontSource.FolderPath + //ExFor:FolderFontSource.ScanSubfolders + //ExFor:FolderFontSource.Type + //ExSummary:Shows how to use a local system folder which contains fonts as a font source. + + // Create a font source from a folder that contains font files. + FolderFontSource folderFontSource = new FolderFontSource(getFontsDir(), false, 1); + + Document doc = new Document(); + doc.setFontSettings(new FontSettings()); + doc.getFontSettings().setFontsSources(new FontSourceBase[]{folderFontSource}); + + Assert.assertEquals(getFontsDir(), folderFontSource.getFolderPath()); + Assert.assertEquals(false, folderFontSource.getScanSubfolders()); + Assert.assertEquals(FontSourceType.FONTS_FOLDER, folderFontSource.getType()); + Assert.assertEquals(1, folderFontSource.getPriority()); + //ExEnd + } + + @Test(dataProvider = "setFontsFolderDataProvider") + public void setFontsFolder(boolean recursive) throws Exception { + //ExStart + //ExFor:FontSettings + //ExFor:FontSettings.SetFontsFolder(String, Boolean) + //ExSummary:Shows how to set a font source directory. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Arvo"); + builder.writeln("Hello world!"); + builder.getFont().setName("Amethysta"); + builder.writeln("The quick brown fox jumps over the lazy dog."); + + // Our font sources do not contain the font that we have used for text in this document. + // If we use these font settings while rendering this document, + // Aspose.Words will apply a fallback font to text which has a font that Aspose.Words cannot locate. + FontSourceBase[] originalFontSources = FontSettings.getDefaultInstance().getFontsSources(); + + Assert.assertEquals(1, originalFontSources.length); + Assert.assertTrue(IterableUtils.matchesAny(originalFontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Arial"))); + + // The default font sources are missing the two fonts that we are using in this document. + Assert.assertFalse(IterableUtils.matchesAny(originalFontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Arvo"))); + Assert.assertFalse(IterableUtils.matchesAny(originalFontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Amethysta"))); + + // Use the "SetFontsFolder" method to set a directory which will act as a new font source. + // Pass "false" as the "recursive" argument to include fonts from all the font files that are in the directory + // that we are passing in the first argument, but not include any fonts in any of that directory's subfolders. + // Pass "true" as the "recursive" argument to include all font files in the directory that we are passing + // in the first argument, as well as all the fonts in its subdirectories. + FontSettings.getDefaultInstance().setFontsFolder(getFontsDir(), recursive); + + FontSourceBase[] newFontSources = FontSettings.getDefaultInstance().getFontsSources(); + + Assert.assertEquals(1, newFontSources.length); + Assert.assertFalse(IterableUtils.matchesAny(newFontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Arial"))); + Assert.assertTrue(IterableUtils.matchesAny(newFontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Arvo"))); + + // The "Amethysta" font is in a subfolder of the font directory. + if (recursive) { + Assert.assertEquals(30, newFontSources[0].getAvailableFonts().size()); + Assert.assertTrue(IterableUtils.matchesAny(newFontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Amethysta"))); + } else { + Assert.assertEquals(18, newFontSources[0].getAvailableFonts().size()); + Assert.assertFalse(IterableUtils.matchesAny(newFontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Amethysta"))); + } + + doc.save(getArtifactsDir() + "FontSettings.SetFontsFolder.pdf"); + + // Restore the original font sources. + FontSettings.getDefaultInstance().setFontsSources(originalFontSources); + //ExEnd + } + + @DataProvider(name = "setFontsFolderDataProvider") + public static Object[][] setFontsFolderDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "setFontsFoldersDataProvider") + public void setFontsFolders(boolean recursive) throws Exception { + //ExStart + //ExFor:FontSettings + //ExFor:FontSettings.SetFontsFolders(String[], Boolean) + //ExSummary:Shows how to set multiple font source directories. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Amethysta"); + builder.writeln("The quick brown fox jumps over the lazy dog."); + builder.getFont().setName("Junction Light"); + builder.writeln("The quick brown fox jumps over the lazy dog."); + + // Our font sources do not contain the font that we have used for text in this document. + // If we use these font settings while rendering this document, + // Aspose.Words will apply a fallback font to text which has a font that Aspose.Words cannot locate. + FontSourceBase[] originalFontSources = FontSettings.getDefaultInstance().getFontsSources(); + + Assert.assertEquals(1, originalFontSources.length); + Assert.assertTrue(IterableUtils.matchesAny(originalFontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Arial"))); + + // The default font sources are missing the two fonts that we are using in this document. + Assert.assertFalse(IterableUtils.matchesAny(originalFontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Amethysta"))); + Assert.assertFalse(IterableUtils.matchesAny(originalFontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Junction Light"))); + + // Use the "SetFontsFolders" method to create a font source from each font directory that we pass as the first argument. + // Pass "false" as the "recursive" argument to include fonts from all the font files that are in the directories + // that we are passing in the first argument, but not include any fonts from any of the directories' subfolders. + // Pass "true" as the "recursive" argument to include all font files in the directories that we are passing + // in the first argument, as well as all the fonts in their subdirectories. + FontSettings.getDefaultInstance().setFontsFolders(new String[]{getFontsDir() + "/Amethysta", getFontsDir() + "/Junction"}, recursive); + + FontSourceBase[] newFontSources = FontSettings.getDefaultInstance().getFontsSources(); + + Assert.assertEquals(2, newFontSources.length); + Assert.assertFalse(IterableUtils.matchesAny(newFontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Arial"))); + Assert.assertEquals(1, newFontSources[0].getAvailableFonts().size()); + Assert.assertTrue(IterableUtils.matchesAny(newFontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Amethysta"))); + + // The "Junction" folder itself contains no font files, but has subfolders that do. + if (recursive) { + Assert.assertEquals(11, newFontSources[1].getAvailableFonts().size()); + Assert.assertTrue(IterableUtils.matchesAny(newFontSources[1].getAvailableFonts(), f -> f.getFullFontName().contains("Junction Light"))); + } else { + Assert.assertEquals(0, newFontSources[1].getAvailableFonts().size()); + } + + doc.save(getArtifactsDir() + "FontSettings.SetFontsFolders.pdf"); + + // Restore the original font sources. + FontSettings.getDefaultInstance().setFontsSources(originalFontSources); + //ExEnd + } + + @DataProvider(name = "setFontsFoldersDataProvider") + public static Object[][] setFontsFoldersDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void addFontSource() throws Exception { + //ExStart + //ExFor:FontSettings + //ExFor:FontSettings.GetFontsSources() + //ExFor:FontSettings.SetFontsSources(FontSourceBase[]) + //ExSummary:Shows how to add a font source to our existing font sources. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Arial"); + builder.writeln("Hello world!"); + builder.getFont().setName("Amethysta"); + builder.writeln("The quick brown fox jumps over the lazy dog."); + builder.getFont().setName("Junction Light"); + builder.writeln("The quick brown fox jumps over the lazy dog."); + + FontSourceBase[] originalFontSources = FontSettings.getDefaultInstance().getFontsSources(); + + Assert.assertEquals(1, originalFontSources.length); + + Assert.assertTrue(IterableUtils.matchesAny(originalFontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Arial"))); + + // The default font source is missing two of the fonts that we are using in our document. + // When we save this document, Aspose.Words will apply fallback fonts to all text formatted with inaccessible fonts. + Assert.assertFalse(IterableUtils.matchesAny(originalFontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Amethysta"))); + Assert.assertFalse(IterableUtils.matchesAny(originalFontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Junction Light"))); + + // Create a font source from a folder that contains fonts. + FolderFontSource folderFontSource = new FolderFontSource(getFontsDir(), true); + + // Apply a new array of font sources that contains the original font sources, as well as our custom fonts. + FontSourceBase[] updatedFontSources = {originalFontSources[0], folderFontSource}; + FontSettings.getDefaultInstance().setFontsSources(updatedFontSources); + + // Verify that Aspose.Words has access to all required fonts before we render the document to PDF. + updatedFontSources = FontSettings.getDefaultInstance().getFontsSources(); + + Assert.assertTrue(IterableUtils.matchesAny(updatedFontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Arial"))); + Assert.assertTrue(IterableUtils.matchesAny(updatedFontSources[1].getAvailableFonts(), f -> f.getFullFontName().contains("Amethysta"))); + Assert.assertTrue(IterableUtils.matchesAny(updatedFontSources[1].getAvailableFonts(), f -> f.getFullFontName().contains("Junction Light"))); + + doc.save(getArtifactsDir() + "FontSettings.AddFontSource.pdf"); + + // Restore the original font sources. + FontSettings.getDefaultInstance().setFontsSources(originalFontSources); + //ExEnd + } + + @Test + public void setSpecifyFontFolder() throws Exception { + FontSettings fontSettings = new FontSettings(); + fontSettings.setFontsFolder(getFontsDir(), false); + + // Using load options + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setFontSettings(fontSettings); + + Document doc = new Document(getMyDir() + "Rendering.docx", loadOptions); + + FolderFontSource folderSource = ((FolderFontSource) doc.getFontSettings().getFontsSources()[0]); + + Assert.assertEquals(getFontsDir(), folderSource.getFolderPath()); + Assert.assertFalse(folderSource.getScanSubfolders()); + } + + @Test + public void tableSubstitution() throws Exception { + //ExStart + //ExFor:Document.FontSettings + //ExFor:TableSubstitutionRule.SetSubstitutes(String, String[]) + //ExSummary:Shows how set font substitution rules. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Arial"); + builder.writeln("Hello world!"); + builder.getFont().setName("Amethysta"); + builder.writeln("The quick brown fox jumps over the lazy dog."); + + FontSourceBase[] fontSources = FontSettings.getDefaultInstance().getFontsSources(); + + // The default font sources contain the first font that the document uses. + Assert.assertEquals(1, fontSources.length); + Assert.assertTrue(IterableUtils.matchesAny(fontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Arial"))); + + // The second font, "Amethysta", is unavailable. + Assert.assertFalse(IterableUtils.matchesAny(fontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Amethysta"))); + + // We can configure a font substitution table which determines + // which fonts Aspose.Words will use as substitutes for unavailable fonts. + // Set two substitution fonts for "Amethysta": "Arvo", and "Courier New". + // If the first substitute is unavailable, Aspose.Words attempts to use the second substitute, and so on. + doc.setFontSettings(new FontSettings()); + doc.getFontSettings().getSubstitutionSettings().getTableSubstitution().setSubstitutes( + "Amethysta", "Arvo", "Courier New"); + + // "Amethysta" is unavailable, and the substitution rule states that the first font to use as a substitute is "Arvo". + Assert.assertFalse(IterableUtils.matchesAny(fontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Arvo"))); + + // "Arvo" is also unavailable, but "Courier New" is. + Assert.assertTrue(IterableUtils.matchesAny(fontSources[0].getAvailableFonts(), f -> f.getFullFontName().contains("Courier New"))); + + // The output document will display the text that uses the "Amethysta" font formatted with "Courier New". + doc.save(getArtifactsDir() + "FontSettings.TableSubstitution.pdf"); + //ExEnd + } + + @Test + public void setSpecifyFontFolders() throws Exception { + FontSettings fontSettings = new FontSettings(); + fontSettings.setFontsFolders(new String[]{getFontsDir(), "C:\\Windows\\Fonts\\"}, true); + + // Using load options + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setFontSettings(fontSettings); + Document doc = new Document(getMyDir() + "Rendering.docx", loadOptions); + + FolderFontSource folderSource = ((FolderFontSource) doc.getFontSettings().getFontsSources()[0]); + Assert.assertEquals(getFontsDir(), folderSource.getFolderPath()); + Assert.assertTrue(folderSource.getScanSubfolders()); + + folderSource = ((FolderFontSource) doc.getFontSettings().getFontsSources()[1]); + Assert.assertEquals("C:\\Windows\\Fonts\\", folderSource.getFolderPath()); + Assert.assertTrue(folderSource.getScanSubfolders()); + } + + @Test + public void addFontSubstitutes() throws Exception { + FontSettings fontSettings = new FontSettings(); + fontSettings.getSubstitutionSettings().getTableSubstitution().setSubstitutes("Slab", "Times New Roman", "Arial"); + fontSettings.getSubstitutionSettings().getTableSubstitution().addSubstitutes("Arvo", "Open Sans", "Arial"); + + Document doc = new Document(getMyDir() + "Rendering.docx"); + doc.setFontSettings(fontSettings); + + Iterable<String> alternativeFonts = doc.getFontSettings().getSubstitutionSettings().getTableSubstitution().getSubstitutes("Slab"); + Assert.assertEquals(new String[]{"Times New Roman", "Arial"}, IterableUtils.toList(alternativeFonts).toArray()); + + alternativeFonts = doc.getFontSettings().getSubstitutionSettings().getTableSubstitution().getSubstitutes("Arvo"); + Assert.assertEquals(new String[]{"Open Sans", "Arial"}, IterableUtils.toList(alternativeFonts).toArray()); + } + + @Test + public void fontSourceMemory() throws Exception { + //ExStart + //ExFor:MemoryFontSource + //ExFor:MemoryFontSource.#ctor(Byte[]) + //ExFor:MemoryFontSource.#ctor(Byte[], Int32) + //ExFor:MemoryFontSource.FontData + //ExFor:MemoryFontSource.Type + //ExSummary:Shows how to use a byte array with data from a font file as a font source. + + byte[] fontBytes = DocumentHelper.getBytesFromStream(new FileInputStream(getMyDir() + "Alte DIN 1451 Mittelschrift.ttf")); + MemoryFontSource memoryFontSource = new MemoryFontSource(fontBytes, 0); + + Document doc = new Document(); + doc.setFontSettings(new FontSettings()); + doc.getFontSettings().setFontsSources(new FontSourceBase[]{memoryFontSource}); + + Assert.assertEquals(FontSourceType.MEMORY_FONT, memoryFontSource.getType()); + Assert.assertEquals(0, memoryFontSource.getPriority()); + //ExEnd + } + + @Test + public void fontSourceSystem() throws Exception { + //ExStart + //ExFor:TableSubstitutionRule.AddSubstitutes(String, String[]) + //ExFor:FontSubstitutionRule.Enabled + //ExFor:TableSubstitutionRule.GetSubstitutes(String) + //ExFor:FontSettings.ResetFontSources + //ExFor:FontSettings.SubstitutionSettings + //ExFor:FontSubstitutionSettings + //ExFor:FontSubstitutionSettings.FontNameSubstitution + //ExFor:SystemFontSource + //ExFor:SystemFontSource.#ctor + //ExFor:SystemFontSource.#ctor(Int32) + //ExFor:SystemFontSource.GetSystemFontFolders + //ExFor:SystemFontSource.Type + //ExSummary:Shows how to access a document's system font source and set font substitutes. + Document doc = new Document(); + doc.setFontSettings(new FontSettings()); + + // By default, a blank document always contains a system font source. + Assert.assertEquals(1, doc.getFontSettings().getFontsSources().length); + + SystemFontSource systemFontSource = (SystemFontSource) doc.getFontSettings().getFontsSources()[0]; + Assert.assertEquals(FontSourceType.SYSTEM_FONTS, systemFontSource.getType()); + Assert.assertEquals(0, systemFontSource.getPriority()); + + if (SystemUtils.IS_OS_WINDOWS) { + final String FONTS_PATH = "C:\\WINDOWS\\Fonts"; + Assert.assertEquals(FONTS_PATH.toLowerCase(), SystemFontSource.getSystemFontFolders()[0].toLowerCase()); + } + + for (String systemFontFolder : SystemFontSource.getSystemFontFolders()) { + System.out.println(systemFontFolder); + } + + // Set a font that exists in the Windows Fonts directory as a substitute for one that does not. + doc.getFontSettings().getSubstitutionSettings().getFontInfoSubstitution().setEnabled(true); + doc.getFontSettings().getSubstitutionSettings().getTableSubstitution().addSubstitutes("Kreon-Regular", "Calibri"); + + Assert.assertEquals(1, IterableUtils.size(doc.getFontSettings().getSubstitutionSettings().getTableSubstitution().getSubstitutes("Kreon-Regular"))); + Assert.assertTrue(IterableUtils.toString(doc.getFontSettings().getSubstitutionSettings().getTableSubstitution().getSubstitutes("Kreon-Regular")).contains("Calibri")); + + // Alternatively, we could add a folder font source in which the corresponding folder contains the font. + FolderFontSource folderFontSource = new FolderFontSource(getFontsDir(), false); + doc.getFontSettings().setFontsSources(new FontSourceBase[]{systemFontSource, folderFontSource}); + Assert.assertEquals(2, doc.getFontSettings().getFontsSources().length); + + // Resetting the font sources still leaves us with the system font source as well as our substitutes. + doc.getFontSettings().resetFontSources(); + + Assert.assertEquals(1, doc.getFontSettings().getFontsSources().length); + Assert.assertEquals(FontSourceType.SYSTEM_FONTS, doc.getFontSettings().getFontsSources()[0].getType()); + Assert.assertEquals(1, IterableUtils.size(doc.getFontSettings().getSubstitutionSettings().getTableSubstitution().getSubstitutes("Kreon-Regular"))); + Assert.assertTrue(doc.getFontSettings().getSubstitutionSettings().getFontNameSubstitution().getEnabled()); + //ExEnd + } + + @Test + public void loadFontFallbackSettingsFromFile() throws Exception { + //ExStart + //ExFor:FontFallbackSettings.Load(String) + //ExFor:FontFallbackSettings.Save(String) + //ExSummary:Shows how to load and save font fallback settings to/from an XML document in the local file system. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // Load an XML document that defines a set of font fallback settings. + FontSettings fontSettings = new FontSettings(); + fontSettings.getFallbackSettings().load(getMyDir() + "Font fallback rules.xml"); + + doc.setFontSettings(fontSettings); + doc.save(getArtifactsDir() + "FontSettings.LoadFontFallbackSettingsFromFile.pdf"); + + // Save our document's current font fallback settings as an XML document. + doc.getFontSettings().getFallbackSettings().save(getArtifactsDir() + "FallbackSettings.xml"); + //ExEnd + } + + @Test + public void loadFontFallbackSettingsFromStream() throws Exception { + //ExStart + //ExFor:FontFallbackSettings.Load(Stream) + //ExFor:FontFallbackSettings.Save(Stream) + //ExSummary:Shows how to load and save font fallback settings to/from a stream. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // Load an XML document that defines a set of font fallback settings. + try (FileInputStream fontFallbackRulesStream = new FileInputStream(getMyDir() + "Font fallback rules.xml")) { + FontSettings fontSettings = new FontSettings(); + fontSettings.getFallbackSettings().load(fontFallbackRulesStream); + + doc.setFontSettings(fontSettings); + } + + doc.save(getArtifactsDir() + "FontSettings.LoadFontFallbackSettingsFromStream.pdf"); + + // Use a stream to save our document's current font fallback settings as an XML document. + try (FileOutputStream fontFallbackSettingsStream = new FileOutputStream(getArtifactsDir() + "FallbackSettings.xml")) { + doc.getFontSettings().getFallbackSettings().save(fontFallbackSettingsStream); + } + //ExEnd + } + + @Test + public void loadNotoFontsFallbackSettings() throws Exception { + //ExStart + //ExFor:FontFallbackSettings.LoadNotoFallbackSettings + //ExSummary:Shows how to add predefined font fallback settings for Google Noto fonts. + FontSettings fontSettings = new FontSettings(); + + // These are free fonts licensed under the SIL Open Font License. + // We can download the fonts here: + // https://www.google.com/get/noto/#sans-lgc + fontSettings.setFontsFolder(getFontsDir() + "Noto", false); + + // Note that the predefined settings only use Sans-style Noto fonts with regular weight. + // Some of the Noto fonts use advanced typography features. + // Fonts featuring advanced typography may not be rendered correctly as Aspose.Words currently do not support them. + fontSettings.getFallbackSettings().loadNotoFallbackSettings(); + fontSettings.getSubstitutionSettings().getFontInfoSubstitution().setEnabled(false); + fontSettings.getSubstitutionSettings().getDefaultFontSubstitution().setDefaultFontName("Noto Sans"); + + Document doc = new Document(); + doc.setFontSettings(fontSettings); + //ExEnd + + TestUtil.verifyWebResponseStatusCode(200, new URL("https://www.google.com/get/noto/#sans-lgc")); + } + + @Test + public void defaultFontSubstitutionRule() throws Exception { + //ExStart + //ExFor:DefaultFontSubstitutionRule + //ExFor:DefaultFontSubstitutionRule.DefaultFontName + //ExFor:FontSubstitutionSettings.DefaultFontSubstitution + //ExSummary:Shows how to set the default font substitution rule. + Document doc = new Document(); + FontSettings fontSettings = new FontSettings(); + doc.setFontSettings(fontSettings); + + // Get the default substitution rule within FontSettings. + // This rule will substitute all missing fonts with "Times New Roman". + DefaultFontSubstitutionRule defaultFontSubstitutionRule = fontSettings.getSubstitutionSettings().getDefaultFontSubstitution(); + Assert.assertTrue(defaultFontSubstitutionRule.getEnabled()); + Assert.assertEquals("Times New Roman", defaultFontSubstitutionRule.getDefaultFontName()); + + // Set the default font substitute to "Courier New". + defaultFontSubstitutionRule.setDefaultFontName("Courier New"); + + // Using a document builder, add some text in a font that we do not have to see the substitution take place, + // and then render the result in a PDF. + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Missing Font"); + builder.writeln("Line written in a missing font, which will be substituted with Courier New."); + + doc.save(getArtifactsDir() + "FontSettings.DefaultFontSubstitutionRule.pdf"); + //ExEnd + + Assert.assertEquals("Courier New", defaultFontSubstitutionRule.getDefaultFontName()); + } + + @Test + public void fontConfigSubstitution() { + //ExStart + //ExFor:FontConfigSubstitutionRule + //ExFor:FontConfigSubstitutionRule.Enabled + //ExFor:FontConfigSubstitutionRule.IsFontConfigAvailable + //ExFor:FontConfigSubstitutionRule.ResetCache + //ExFor:FontSubstitutionRule + //ExFor:FontSubstitutionRule.Enabled + //ExFor:FontSubstitutionSettings.FontConfigSubstitution + //ExSummary:Shows operating system-dependent font config substitution. + FontSettings fontSettings = new FontSettings(); + FontConfigSubstitutionRule fontConfigSubstitution = fontSettings.getSubstitutionSettings().getFontConfigSubstitution(); + + // The FontConfigSubstitutionRule object works differently on Windows/non-Windows platforms. + // On Windows, it is unavailable. + if (SystemUtils.IS_OS_WINDOWS) { + Assert.assertFalse(fontConfigSubstitution.getEnabled()); + Assert.assertFalse(fontConfigSubstitution.isFontConfigAvailable()); + } + + // On Linux/Mac, we will have access to it, and will be able to perform operations. + if (SystemUtils.IS_OS_LINUX) { + Assert.assertTrue(fontConfigSubstitution.getEnabled()); + Assert.assertTrue(fontConfigSubstitution.isFontConfigAvailable()); + + fontConfigSubstitution.resetCache(); + } + //ExEnd + } + + @Test + public void fallbackSettings() throws Exception { + //ExStart + //ExFor:FontFallbackSettings.LoadMsOfficeFallbackSettings + //ExFor:FontFallbackSettings.LoadNotoFallbackSettings + //ExSummary:Shows how to load pre-defined fallback font settings. + Document doc = new Document(); + + FontSettings fontSettings = new FontSettings(); + doc.setFontSettings(fontSettings); + FontFallbackSettings fontFallbackSettings = fontSettings.getFallbackSettings(); + + // Save the default fallback font scheme to an XML document. + // For example, one of the elements has a value of "0C00-0C7F" for Range and a corresponding "Vani" value for FallbackFonts. + // This means that if the font some text is using does not have symbols for the 0x0C00-0x0C7F Unicode block, + // the fallback scheme will use symbols from the "Vani" font substitute. + fontFallbackSettings.save(getArtifactsDir() + "FontSettings.FallbackSettings.Default.xml"); + + // Below are two pre-defined font fallback schemes we can choose from. + // 1 - Use the default Microsoft Office scheme, which is the same one as the default: + fontFallbackSettings.loadMsOfficeFallbackSettings(); + fontFallbackSettings.save(getArtifactsDir() + "FontSettings.FallbackSettings.LoadMsOfficeFallbackSettings.xml"); + + // 2 - Use the scheme built from Google Noto fonts: + fontFallbackSettings.loadNotoFallbackSettings(); + fontFallbackSettings.save(getArtifactsDir() + "FontSettings.FallbackSettings.LoadNotoFallbackSettings.xml"); + //ExEnd + } + + @Test + public void fallbackSettingsCustom() throws Exception { + //ExStart + //ExFor:FontSettings.FallbackSettings + //ExFor:FontFallbackSettings + //ExFor:FontFallbackSettings.BuildAutomatic + //ExSummary:Shows how to distribute fallback fonts across Unicode character code ranges. + Document doc = new Document(); + + FontSettings fontSettings = new FontSettings(); + doc.setFontSettings(fontSettings); + FontFallbackSettings fontFallbackSettings = fontSettings.getFallbackSettings(); + + // Configure our font settings to source fonts only from the "MyFonts" folder. + FolderFontSource folderFontSource = new FolderFontSource(getFontsDir(), false); + fontSettings.setFontsSources(new FontSourceBase[]{folderFontSource}); + + // Calling the "BuildAutomatic" method will generate a fallback scheme that + // distributes accessible fonts across as many Unicode character codes as possible. + // In our case, it only has access to the handful of fonts inside the "MyFonts" folder. + fontFallbackSettings.buildAutomatic(); + fontFallbackSettings.save(getArtifactsDir() + "FontSettings.FallbackSettingsCustom.BuildAutomatic.xml"); + + // We can also load a custom substitution scheme from a file like this. + // This scheme applies the "AllegroOpen" font across the "0000-00ff" Unicode blocks, the "AllegroOpen" font across "0100-024f", + // and the "M+ 2m" font in all other ranges that other fonts in the scheme do not cover. + fontFallbackSettings.load(getMyDir() + "Custom font fallback settings.xml"); + + // Create a document builder and set its font to one that does not exist in any of our sources. + // Our font settings will invoke the fallback scheme for characters that we type using the unavailable font. + DocumentBuilder builder = new DocumentBuilder(doc); + builder.getFont().setName("Missing Font"); + + // Use the builder to print every Unicode character from 0x0021 to 0x052F, + // with descriptive lines dividing Unicode blocks we defined in our custom font fallback scheme. + for (int i = 0x0021; i < 0x0530; i++) { + switch (i) { + case 0x0021: + builder.writeln("\n\n0x0021 - 0x00FF: \nBasic Latin/Latin-1 Supplement Unicode blocks in \"AllegroOpen\" font:"); + break; + case 0x0100: + builder.writeln("\n\n0x0100 - 0x024F: \nLatin Extended A/B blocks, mostly in \"AllegroOpen\" font:"); + break; + case 0x0250: + builder.writeln("\n\n0x0250 - 0x052F: \nIPA/Greek/Cyrillic blocks in \"M+ 2m\" font:"); + break; + } + + builder.write(MessageFormat.format("{0}", (char) i)); + } + + doc.save(getArtifactsDir() + "FontSettings.FallbackSettingsCustom.pdf"); + //ExEnd + } + + @Test + public void tableSubstitutionRule() throws Exception { + //ExStart + //ExFor:TableSubstitutionRule + //ExFor:TableSubstitutionRule.LoadLinuxSettings + //ExFor:TableSubstitutionRule.LoadWindowsSettings + //ExFor:TableSubstitutionRule.Save(Stream) + //ExFor:TableSubstitutionRule.Save(String) + //ExSummary:Shows how to access font substitution tables for Windows and Linux. + Document doc = new Document(); + FontSettings fontSettings = new FontSettings(); + doc.setFontSettings(fontSettings); + + // Create a new table substitution rule and load the default Microsoft Windows font substitution table. + TableSubstitutionRule tableSubstitutionRule = fontSettings.getSubstitutionSettings().getTableSubstitution(); + tableSubstitutionRule.loadWindowsSettings(); + + // In Windows, the default substitute for the "Times New Roman CE" font is "Times New Roman". + Assert.assertEquals(new String[]{"Times New Roman"}, + IterableUtils.toList(tableSubstitutionRule.getSubstitutes("Times New Roman CE")).toArray()); + + // We can save the table in the form of an XML document. + tableSubstitutionRule.save(getArtifactsDir() + "FontSettings.TableSubstitutionRule.Windows.xml"); + + // Linux has its own substitution table. + // There are multiple substitute fonts for "Times New Roman CE". + // If the first substitute, "FreeSerif" is also unavailable, + // this rule will cycle through the others in the array until it finds an available one. + tableSubstitutionRule.loadLinuxSettings(); + Assert.assertEquals(new String[]{"FreeSerif", "Liberation Serif", "DejaVu Serif"}, + IterableUtils.toList(tableSubstitutionRule.getSubstitutes("Times New Roman CE")).toArray()); + + // Save the Linux substitution table in the form of an XML document using a stream. + try (FileOutputStream fileStream = new FileOutputStream(getArtifactsDir() + "FontSettings.TableSubstitutionRule.Linux.xml")) { + tableSubstitutionRule.save(fileStream); + } + //ExEnd + } + + @Test + public void tableSubstitutionRuleCustom() throws Exception { + //ExStart + //ExFor:FontSubstitutionSettings.TableSubstitution + //ExFor:TableSubstitutionRule.AddSubstitutes(String,String[]) + //ExFor:TableSubstitutionRule.GetSubstitutes(String) + //ExFor:TableSubstitutionRule.Load(Stream) + //ExFor:TableSubstitutionRule.Load(String) + //ExFor:TableSubstitutionRule.SetSubstitutes(String,String[]) + //ExSummary:Shows how to work with custom font substitution tables. + Document doc = new Document(); + FontSettings fontSettings = new FontSettings(); + doc.setFontSettings(fontSettings); + + // Create a new table substitution rule and load the default Windows font substitution table. + TableSubstitutionRule tableSubstitutionRule = fontSettings.getSubstitutionSettings().getTableSubstitution(); + + // If we select fonts exclusively from our folder, we will need a custom substitution table. + // We will no longer have access to the Microsoft Windows fonts, + // such as "Arial" or "Times New Roman" since they do not exist in our new font folder. + FolderFontSource folderFontSource = new FolderFontSource(getFontsDir(), false); + fontSettings.setFontsSources(new FontSourceBase[]{folderFontSource}); + + // Below are two ways of loading a substitution table from a file in the local file system. + // 1 - From a stream: + try (FileInputStream fileStream = new FileInputStream(getMyDir() + "Font substitution rules.xml")) { + tableSubstitutionRule.load(fileStream); + } + + // 2 - Directly from a file: + tableSubstitutionRule.load(getMyDir() + "Font substitution rules.xml"); + + // Since we no longer have access to "Arial", our font table will first try substitute it with "Nonexistent Font". + // We do not have this font so that it will move onto the next substitute, "Kreon", found in the "MyFonts" folder. + Assert.assertEquals(new String[]{"Missing Font", "Kreon"}, IterableUtils.toList(tableSubstitutionRule.getSubstitutes("Arial")).toArray()); + + // We can expand this table programmatically. We will add an entry that substitutes "Times New Roman" with "Arvo" + Assert.assertNull(tableSubstitutionRule.getSubstitutes("Times New Roman")); + tableSubstitutionRule.addSubstitutes("Times New Roman", "Arvo"); + Assert.assertEquals(new String[]{"Arvo"}, IterableUtils.toList(tableSubstitutionRule.getSubstitutes("Times New Roman")).toArray()); + + // We can add a secondary fallback substitute for an existing font entry with AddSubstitutes(). + // In case "Arvo" is unavailable, our table will look for "M+ 2m" as a second substitute option. + tableSubstitutionRule.addSubstitutes("Times New Roman", "M+ 2m"); + Assert.assertEquals(new String[]{"Arvo", "M+ 2m"}, IterableUtils.toList(tableSubstitutionRule.getSubstitutes("Times New Roman")).toArray()); + + // SetSubstitutes() can set a new list of substitute fonts for a font. + tableSubstitutionRule.setSubstitutes("Times New Roman", "Squarish Sans CT", "M+ 2m"); + Assert.assertEquals(new String[]{"Squarish Sans CT", "M+ 2m"}, IterableUtils.toList(tableSubstitutionRule.getSubstitutes("Times New Roman")).toArray()); + + // Writing text in fonts that we do not have access to will invoke our substitution rules. + DocumentBuilder builder = new DocumentBuilder(doc); + builder.getFont().setName("Arial"); + builder.writeln("Text written in Arial, to be substituted by Kreon."); + + builder.getFont().setName("Times New Roman"); + builder.writeln("Text written in Times New Roman, to be substituted by Squarish Sans CT."); + + doc.save(getArtifactsDir() + "FontSettings.TableSubstitutionRule.Custom.pdf"); + //ExEnd + } + + @Test + public void resolveFontsBeforeLoadingDocument() throws Exception { + //ExStart + //ExFor:LoadOptions.FontSettings + //ExSummary:Shows how to designate font substitutes during loading. + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setFontSettings(new FontSettings()); + + // Set a font substitution rule for a LoadOptions object. + // If the document we are loading uses a font which we do not have, + // this rule will substitute the unavailable font with one that does exist. + // In this case, all uses of the "MissingFont" will convert to "Comic Sans MS". + TableSubstitutionRule substitutionRule = loadOptions.getFontSettings().getSubstitutionSettings().getTableSubstitution(); + substitutionRule.addSubstitutes("MissingFont", "Comic Sans MS"); + + Document doc = new Document(getMyDir() + "Missing font.html", loadOptions); + + // At this point such text will still be in "MissingFont". + // Font substitution will take place when we render the document. + Assert.assertEquals("MissingFont", doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0).getFont().getName()); + + doc.save(getArtifactsDir() + "FontSettings.ResolveFontsBeforeLoadingDocument.pdf"); + //ExEnd + } + + //ExStart + //ExFor:StreamFontSource + //ExFor:StreamFontSource.OpenFontDataStream + //ExSummary:Shows how to load fonts from stream. + @Test //ExSkip + public void streamFontSourceFileRendering() throws Exception { + FontSettings fontSettings = new FontSettings(); + fontSettings.setFontsSources(new FontSourceBase[]{new StreamFontSourceFile()}); + + DocumentBuilder builder = new DocumentBuilder(); + builder.getDocument().setFontSettings(fontSettings); + builder.getFont().setName("Kreon-Regular"); + builder.writeln("Test aspose text when saving to PDF."); + + builder.getDocument().save(getArtifactsDir() + "FontSettings.StreamFontSourceFileRendering.pdf"); + } + + /// <summary> + /// Load the font data only when required instead of storing it in the memory for the entire lifetime of the "FontSettings" object. + /// </summary> + private static class StreamFontSourceFile extends StreamFontSource { + public FileInputStream openFontDataStream() throws Exception { + return new FileInputStream(getFontsDir() + "Kreon-Regular.ttf"); + } + } + //ExEnd + + //ExStart + //ExFor:FileFontSource.#ctor(String, Int32, String) + //ExFor:MemoryFontSource.#ctor(Byte[], Int32, String) + //ExFor:FontSettings.SaveSearchCache(Stream) + //ExFor:FontSettings.SetFontsSources(FontSourceBase[], Stream) + //ExFor:FileFontSource.CacheKey + //ExFor:MemoryFontSource.CacheKey + //ExFor:StreamFontSource.CacheKey + //ExSummary:Shows how to speed up the font cache initialization process. + @Test //ExSkip + public void loadFontSearchCache() throws Exception + { + final String CACHE_KEY_1 = "Arvo"; + final String CACHE_KEY_2 = "Arvo-Bold"; + FontSettings parsedFonts = new FontSettings(); + FontSettings loadedCache = new FontSettings(); + + parsedFonts.setFontsSources(new FontSourceBase[] + { + new FileFontSource(getFontsDir() + "Arvo-Regular.ttf", 0, CACHE_KEY_1), + new FileFontSource(getFontsDir() + "Arvo-Bold.ttf", 0, CACHE_KEY_2) + }); + + + try (ByteArrayOutputStream cacheStream = new ByteArrayOutputStream()) + { + parsedFonts.saveSearchCache(cacheStream); + ByteArrayInputStream inputStream = new ByteArrayInputStream(cacheStream.toByteArray()); + loadedCache.setFontsSources(new FontSourceBase[] + { + new SearchCacheStream(CACHE_KEY_1), + new MemoryFontSource(Files.readAllBytes(Paths.get(getFontsDir() + "Arvo-Bold.ttf")), 0, CACHE_KEY_2) + }, inputStream); + } + + Assert.assertEquals(parsedFonts.getFontsSources().length, loadedCache.getFontsSources().length); + } + + /// <summary> + /// Load the font data only when required instead of storing it in the memory + /// for the entire lifetime of the "FontSettings" object. + /// </summary> + private static class SearchCacheStream extends StreamFontSource + { + public SearchCacheStream(String cacheKey) + { + super(0, cacheKey); + + } + + public FileInputStream openFontDataStream() throws Exception + { + return new FileInputStream(getFontsDir() + "Arvo-Regular.ttf"); + } + } + //ExEnd +} \ No newline at end of file diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExFormFields.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExFormFields.java new file mode 100644 index 00000000..7bd15da4 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExFormFields.java @@ -0,0 +1,411 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.awt.*; +import java.util.Iterator; + +@Test +public class ExFormFields extends ApiExampleBase { + @Test + public void create() throws Exception { + //ExStart + //ExFor:FormField + //ExFor:FormField.Result + //ExFor:FormField.Type + //ExFor:FormField.Name + //ExSummary:Shows how to insert a combo box. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Please select a fruit: "); + + // Insert a combo box which will allow a user to choose an option from a collection of strings. + FormField comboBox = builder.insertComboBox("MyComboBox", new String[]{"Apple", "Banana", "Cherry"}, 0); + + Assert.assertEquals("MyComboBox", comboBox.getName()); + Assert.assertEquals(FieldType.FIELD_FORM_DROP_DOWN, comboBox.getType()); + Assert.assertEquals("Apple", comboBox.getResult()); + + // The form field will appear in the form of a "select" html tag. + doc.save(getArtifactsDir() + "FormFields.Create.html"); + //ExEnd + + doc = new Document(getArtifactsDir() + "FormFields.Create.html"); + comboBox = doc.getRange().getFormFields().get(0); + + Assert.assertEquals("MyComboBox", comboBox.getName()); + Assert.assertEquals(FieldType.FIELD_FORM_DROP_DOWN, comboBox.getType()); + Assert.assertEquals("Apple", comboBox.getResult()); + } + + @Test + public void textInput() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertTextInput + //ExSummary:Shows how to insert a text input form field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Please enter text here: "); + + // Insert a text input field, which will allow the user to click it and enter text. + // Assign some placeholder text that the user may overwrite and pass + // a maximum text length of 0 to apply no limit on the form field's contents. + builder.insertTextInput("TextInput1", TextFormFieldType.REGULAR, "", "Placeholder text", 0); + + // The form field will appear in the form of an "input" html tag, with a type of "text". + doc.save(getArtifactsDir() + "FormFields.TextInput.html"); + //ExEnd + + doc = new Document(getArtifactsDir() + "FormFields.TextInput.html"); + + FormField textInput = doc.getRange().getFormFields().get(0); + + Assert.assertEquals("TextInput1", textInput.getName()); + Assert.assertEquals(TextFormFieldType.REGULAR, textInput.getTextInputType()); + Assert.assertEquals("", textInput.getTextInputFormat()); + Assert.assertEquals("Placeholder text", textInput.getResult()); + Assert.assertEquals(0, textInput.getMaxLength()); + } + + @Test + public void deleteFormField() throws Exception { + //ExStart + //ExFor:FormField.RemoveField + //ExSummary:Shows how to delete a form field. + Document doc = new Document(getMyDir() + "Form fields.docx"); + + FormField formField = doc.getRange().getFormFields().get(3); + formField.removeField(); + //ExEnd + + FormField formFieldAfter = doc.getRange().getFormFields().get(3); + + Assert.assertNull(formFieldAfter); + } + + @Test + public void deleteFormFieldAssociatedWithBookmark() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startBookmark("MyBookmark"); + builder.insertTextInput("TextInput1", TextFormFieldType.REGULAR, "TestFormField", "SomeText", 0); + builder.endBookmark("MyBookmark"); + + doc = DocumentHelper.saveOpen(doc); + + BookmarkCollection bookmarkBeforeDeleteFormField = doc.getRange().getBookmarks(); + Assert.assertEquals("MyBookmark", bookmarkBeforeDeleteFormField.get(0).getName()); + + FormField formField = doc.getRange().getFormFields().get(0); + formField.removeField(); + + BookmarkCollection bookmarkAfterDeleteFormField = doc.getRange().getBookmarks(); + Assert.assertEquals("MyBookmark", bookmarkAfterDeleteFormField.get(0).getName()); + } + + @Test + public void formFieldFontFormatting() throws Exception { + //ExStart + //ExFor:FormField + //ExSummary:Shows how to formatting the entire FormField, including the field value. + Document doc = new Document(getMyDir() + "Form fields.docx"); + + FormField formField = doc.getRange().getFormFields().get(0); + formField.getFont().setBold(true); + formField.getFont().setSize(24.0); + formField.getFont().setColor(Color.RED); + + formField.setResult("Aspose.FormField"); + + doc = DocumentHelper.saveOpen(doc); + + Run formFieldRun = doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(1); + + Assert.assertEquals("Aspose.FormField", formFieldRun.getText()); + Assert.assertEquals(true, formFieldRun.getFont().getBold()); + Assert.assertEquals(24.0, formFieldRun.getFont().getSize()); + Assert.assertEquals(Color.RED.getRGB(), formFieldRun.getFont().getColor().getRGB()); + //ExEnd + } + + //ExStart + //ExFor:FormField.Accept(DocumentVisitor) + //ExFor:FormField.CalculateOnExit + //ExFor:FormField.CheckBoxSize + //ExFor:FormField.Checked + //ExFor:FormField.Default + //ExFor:FormField.DropDownItems + //ExFor:FormField.DropDownSelectedIndex + //ExFor:FormField.Enabled + //ExFor:FormField.EntryMacro + //ExFor:FormField.ExitMacro + //ExFor:FormField.HelpText + //ExFor:FormField.IsCheckBoxExactSize + //ExFor:FormField.MaxLength + //ExFor:FormField.OwnHelp + //ExFor:FormField.OwnStatus + //ExFor:FormField.SetTextInputValue(Object) + //ExFor:FormField.StatusText + //ExFor:FormField.TextInputDefault + //ExFor:FormField.TextInputFormat + //ExFor:FormField.TextInputType + //ExFor:FormFieldCollection + //ExFor:FormFieldCollection.Clear + //ExFor:FormFieldCollection.Count + //ExFor:FormFieldCollection.GetEnumerator + //ExFor:FormFieldCollection.Item(Int32) + //ExFor:FormFieldCollection.Item(String) + //ExFor:FormFieldCollection.Remove(String) + //ExFor:FormFieldCollection.RemoveAt(Int32) + //ExFor:Range.FormFields + //ExSummary:Shows how insert different kinds of form fields into a document, and process them with using a document visitor implementation. + @Test //ExSkip + public void visitor() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Use a document builder to insert a combo box. + builder.write("Choose a value from this combo box: "); + FormField comboBox = builder.insertComboBox("MyComboBox", new String[]{"One", "Two", "Three"}, 0); + comboBox.setCalculateOnExit(true); + Assert.assertEquals(3, comboBox.getDropDownItems().getCount()); + Assert.assertEquals(0, comboBox.getDropDownSelectedIndex()); + Assert.assertTrue(comboBox.getEnabled()); + + builder.insertBreak(BreakType.PARAGRAPH_BREAK); + + // Use a document builder to insert a check box. + builder.write("Click this check box to tick/untick it: "); + FormField checkBox = builder.insertCheckBox("MyCheckBox", false, 50); + checkBox.isCheckBoxExactSize(true); + checkBox.setHelpText("Right click to check this box"); + checkBox.setOwnHelp(true); + checkBox.setStatusText("Checkbox status text"); + checkBox.setOwnStatus(true); + Assert.assertEquals(50.0d, checkBox.getCheckBoxSize()); + Assert.assertFalse(checkBox.getChecked()); + Assert.assertFalse(checkBox.getDefault()); + + builder.insertBreak(BreakType.PARAGRAPH_BREAK); + + // Use a document builder to insert text input form field. + builder.write("Enter text here: "); + FormField textInput = builder.insertTextInput("MyTextInput", TextFormFieldType.REGULAR, "", "Placeholder text", 50); + textInput.setEntryMacro("EntryMacro"); + textInput.setExitMacro("ExitMacro"); + textInput.setTextInputDefault("Regular"); + textInput.setTextInputFormat("FIRST CAPITAL"); + textInput.setTextInputValue("New placeholder text"); + Assert.assertEquals(TextFormFieldType.REGULAR, textInput.getTextInputType()); + Assert.assertEquals(50, textInput.getMaxLength()); + + // This collection contains all our form fields. + FormFieldCollection formFields = doc.getRange().getFormFields(); + Assert.assertEquals(3, formFields.getCount()); + + // Fields display our form fields. We can see their field codes by opening this document + // in Microsoft and pressing Alt + F9. These fields have no switches, + // and members of the FormField object fully govern their form fields' content. + Assert.assertEquals(3, doc.getRange().getFields().getCount()); + Assert.assertEquals(" FORMDROPDOWN \u0001", doc.getRange().getFields().get(0).getFieldCode()); + Assert.assertEquals(" FORMCHECKBOX \u0001", doc.getRange().getFields().get(1).getFieldCode()); + Assert.assertEquals(" FORMTEXT \u0001", doc.getRange().getFields().get(2).getFieldCode()); + + // Allow each form field to accept a document visitor. + FormFieldVisitor formFieldVisitor = new FormFieldVisitor(); + + Iterator<FormField> fieldEnumerator = formFields.iterator(); + while (fieldEnumerator.hasNext()) + fieldEnumerator.next().accept(formFieldVisitor); + + System.out.println(formFieldVisitor.getText()); + + doc.updateFields(); + doc.save(getArtifactsDir() + "FormFields.Visitor.html"); + testFormField(doc); //ExSkip + } + + /// <summary> + /// Visitor implementation that prints details of form fields that it visits. + /// </summary> + public static class FormFieldVisitor extends DocumentVisitor { + public FormFieldVisitor() { + mBuilder = new StringBuilder(); + } + + /// <summary> + /// Called when a FormField node is encountered in the document. + /// </summary> + public /*override*/ /*VisitorAction*/int visitFormField(FormField formField) { + appendLine(formField.getType() + ": \"" + formField.getName() + "\""); + appendLine("\tStatus: " + (formField.getEnabled() ? "Enabled" : "Disabled")); + appendLine("\tHelp Text: " + formField.getHelpText()); + appendLine("\tEntry macro name: " + formField.getEntryMacro()); + appendLine("\tExit macro name: " + formField.getExitMacro()); + + switch (formField.getType()) { + case FieldType.FIELD_FORM_DROP_DOWN: + appendLine("\tDrop down items count: " + formField.getDropDownItems().getCount() + ", default selected item index: " + formField.getDropDownSelectedIndex()); + appendLine("\tDrop down items: " + String.join(", ", formField.getDropDownItems())); + break; + case FieldType.FIELD_FORM_CHECK_BOX: + appendLine("\tCheckbox size: " + formField.getCheckBoxSize()); + appendLine("\t" + "Checkbox is currently: " + (formField.getChecked() ? "checked, " : "unchecked, ") + "by default: " + (formField.getDefault() ? "checked" : "unchecked")); + break; + case FieldType.FIELD_FORM_TEXT_INPUT: + appendLine("\tInput format: " + formField.getTextInputFormat()); + appendLine("\tCurrent contents: " + formField.getResult()); + break; + } + + // Let the visitor continue visiting other nodes. + return VisitorAction.CONTINUE; + } + + /// <summary> + /// Adds newline char-terminated text to the current output. + /// </summary> + private void appendLine(String text) { + mBuilder.append(text + '\n'); + } + + /// <summary> + /// Gets the plain text of the document that was accumulated by the visitor. + /// </summary> + public String getText() { + return mBuilder.toString(); + } + + private final StringBuilder mBuilder; + } + //ExEnd + + private void testFormField(Document doc) throws Exception { + doc = DocumentHelper.saveOpen(doc); + FieldCollection fields = doc.getRange().getFields(); + Assert.assertEquals(3, fields.getCount()); + + TestUtil.verifyField(FieldType.FIELD_FORM_DROP_DOWN, " FORMDROPDOWN \u0001", "", doc.getRange().getFields().get(0)); + TestUtil.verifyField(FieldType.FIELD_FORM_CHECK_BOX, " FORMCHECKBOX \u0001", "", doc.getRange().getFields().get(1)); + TestUtil.verifyField(FieldType.FIELD_FORM_TEXT_INPUT, " FORMTEXT \u0001", "Regular", doc.getRange().getFields().get(2)); + + FormFieldCollection formFields = doc.getRange().getFormFields(); + Assert.assertEquals(3, formFields.getCount()); + + Assert.assertEquals(FieldType.FIELD_FORM_DROP_DOWN, formFields.get(0).getType()); + Assert.assertEquals("One, Two, Three", String.join(", ", formFields.get(0).getDropDownItems())); + Assert.assertTrue(formFields.get(0).getCalculateOnExit()); + Assert.assertEquals(0, formFields.get(0).getDropDownSelectedIndex()); + Assert.assertTrue(formFields.get(0).getEnabled()); + Assert.assertEquals("One", formFields.get(0).getResult()); + + Assert.assertEquals(FieldType.FIELD_FORM_CHECK_BOX, formFields.get(1).getType()); + Assert.assertTrue(formFields.get(1).isCheckBoxExactSize()); + Assert.assertEquals("Right click to check this box", formFields.get(1).getHelpText()); + Assert.assertTrue(formFields.get(1).getOwnHelp()); + Assert.assertEquals("Checkbox status text", formFields.get(1).getStatusText()); + Assert.assertTrue(formFields.get(1).getOwnStatus()); + Assert.assertEquals(50.0d, formFields.get(1).getCheckBoxSize()); + Assert.assertFalse(formFields.get(1).getChecked()); + Assert.assertFalse(formFields.get(1).getDefault()); + Assert.assertEquals("0", formFields.get(1).getResult()); + + Assert.assertEquals(FieldType.FIELD_FORM_TEXT_INPUT, formFields.get(2).getType()); + Assert.assertEquals("EntryMacro", formFields.get(2).getEntryMacro()); + Assert.assertEquals("ExitMacro", formFields.get(2).getExitMacro()); + Assert.assertEquals("Regular", formFields.get(2).getTextInputDefault()); + Assert.assertEquals("FIRST CAPITAL", formFields.get(2).getTextInputFormat()); + Assert.assertEquals(TextFormFieldType.REGULAR, formFields.get(2).getTextInputType()); + Assert.assertEquals(50, formFields.get(2).getMaxLength()); + Assert.assertEquals("Regular", formFields.get(2).getResult()); + } + + @Test + public void dropDownItemCollection() throws Exception { + //ExStart + //ExFor:DropDownItemCollection + //ExFor:DropDownItemCollection.Add(String) + //ExFor:DropDownItemCollection.Clear + //ExFor:DropDownItemCollection.Contains(String) + //ExFor:DropDownItemCollection.Count + //ExFor:DropDownItemCollection.GetEnumerator + //ExFor:DropDownItemCollection.IndexOf(String) + //ExFor:DropDownItemCollection.Insert(Int32, String) + //ExFor:DropDownItemCollection.Item(Int32) + //ExFor:DropDownItemCollection.Remove(String) + //ExFor:DropDownItemCollection.RemoveAt(Int32) + //ExSummary:Shows how to insert a combo box field, and edit the elements in its item collection. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a combo box, and then verify its collection of drop-down items. + // In Microsoft Word, the user will click the combo box, + // and then choose one of the items of text in the collection to display. + String[] items = {"One", "Two", "Three"}; + FormField comboBoxField = builder.insertComboBox("DropDown", items, 0); + DropDownItemCollection dropDownItems = comboBoxField.getDropDownItems(); + + Assert.assertEquals(3, dropDownItems.getCount()); + Assert.assertEquals("One", dropDownItems.get(0)); + Assert.assertEquals(1, dropDownItems.indexOf("Two")); + Assert.assertTrue(dropDownItems.contains("Three")); + + // There are two ways of adding a new item to an existing collection of drop-down box items. + // 1 - Append an item to the end of the collection: + dropDownItems.add("Four"); + + // 2 - Insert an item before another item at a specified index: + dropDownItems.insert(3, "Three and a half"); + + Assert.assertEquals(5, dropDownItems.getCount()); + + // Iterate over the collection and print every element. + Iterator<String> dropDownCollectionEnumerator = dropDownItems.iterator(); + + while (dropDownCollectionEnumerator.hasNext()) + System.out.println(dropDownCollectionEnumerator.next()); + + // There are two ways of removing elements from a collection of drop-down items. + // 1 - Remove an item with contents equal to the passed string: + dropDownItems.remove("Four"); + + // 2 - Remove an item at an index: + dropDownItems.removeAt(3); + + Assert.assertEquals(3, dropDownItems.getCount()); + Assert.assertFalse(dropDownItems.contains("Three and a half")); + Assert.assertFalse(dropDownItems.contains("Four")); + + doc.save(getArtifactsDir() + "FormFields.DropDownItemCollection.html"); + + // Empty the whole collection of drop-down items. + dropDownItems.clear(); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + dropDownItems = doc.getRange().getFormFields().get(0).getDropDownItems(); + + Assert.assertEquals(0, dropDownItems.getCount()); + + doc = new Document(getArtifactsDir() + "FormFields.DropDownItemCollection.html"); + dropDownItems = doc.getRange().getFormFields().get(0).getDropDownItems(); + + Assert.assertEquals(3, dropDownItems.getCount()); + Assert.assertEquals("One", dropDownItems.get(0)); + Assert.assertEquals("Two", dropDownItems.get(1)); + Assert.assertEquals("Three", dropDownItems.get(2)); + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExHeaderFooter.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExHeaderFooter.java new file mode 100644 index 00000000..2811e4d5 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExHeaderFooter.java @@ -0,0 +1,427 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.apache.commons.collections4.IterableUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.text.MessageFormat; +import java.util.Calendar; +import java.util.regex.Pattern; + +public class ExHeaderFooter extends ApiExampleBase { + @Test + public void create() throws Exception { + //ExStart + //ExFor:HeaderFooter + //ExFor:HeaderFooter.#ctor(DocumentBase, HeaderFooterType) + //ExFor:HeaderFooter.HeaderFooterType + //ExFor:HeaderFooter.IsHeader + //ExFor:HeaderFooterCollection + //ExFor:Paragraph.IsEndOfHeaderFooter + //ExFor:Paragraph.ParentSection + //ExFor:Paragraph.ParentStory + //ExFor:Story.AppendParagraph + //ExSummary:Shows how to create a header and a footer. + Document doc = new Document(); + + // Create a header and append a paragraph to it. The text in that paragraph + // will appear at the top of every page of this section, above the main body text. + HeaderFooter header = new HeaderFooter(doc, HeaderFooterType.HEADER_PRIMARY); + doc.getFirstSection().getHeadersFooters().add(header); + + Paragraph para = header.appendParagraph("My header."); + + Assert.assertTrue(header.isHeader()); + Assert.assertTrue(para.isEndOfHeaderFooter()); + + // Create a footer and append a paragraph to it. The text in that paragraph + // will appear at the bottom of every page of this section, below the main body text. + HeaderFooter footer = new HeaderFooter(doc, HeaderFooterType.FOOTER_PRIMARY); + doc.getFirstSection().getHeadersFooters().add(footer); + + para = footer.appendParagraph("My footer."); + + Assert.assertFalse(footer.isHeader()); + Assert.assertTrue(para.isEndOfHeaderFooter()); + + Assert.assertEquals(para.getParentStory(), footer); + Assert.assertEquals(para.getParentSection(), footer.getParentSection()); + Assert.assertEquals(header.getParentSection(), footer.getParentSection()); + + doc.save(getArtifactsDir() + "HeaderFooter.Create.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "HeaderFooter.Create.docx"); + + Assert.assertTrue(doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.HEADER_PRIMARY).getRange().getText().contains("My header")); + Assert.assertTrue(doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY).getRange().getText().contains("My footer")); + } + + @Test + public void link() throws Exception { + //ExStart + //ExFor:HeaderFooter.IsLinkedToPrevious + //ExFor:HeaderFooterCollection.Item(Int32) + //ExFor:HeaderFooterCollection.LinkToPrevious(HeaderFooterType,Boolean) + //ExFor:HeaderFooterCollection.LinkToPrevious(Boolean) + //ExFor:HeaderFooter.ParentSection + //ExSummary:Shows how to link headers and footers between sections. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Section 1"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.write("Section 2"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.write("Section 3"); + + // Move to the first section and create a header and a footer. By default, + // the header and the footer will only appear on pages in the section that contains them. + builder.moveToSection(0); + + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.write("This is the header, which will be displayed in sections 1 and 2."); + + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + builder.write("This is the footer, which will be displayed in sections 1, 2 and 3."); + + // We can link a section's headers/footers to the previous section's headers/footers + // to allow the linking section to display the linked section's headers/footers. + doc.getSections().get(1).getHeadersFooters().linkToPrevious(true); + + // Each section will still have its own header/footer objects. When we link sections, + // the linking section will display the linked section's header/footers while keeping its own. + Assert.assertNotEquals(doc.getSections().get(0).getHeadersFooters().get(0), doc.getSections().get(1).getHeadersFooters().get(0)); + Assert.assertNotEquals(doc.getSections().get(0).getHeadersFooters().get(0).getParentSection(), doc.getSections().get(1).getHeadersFooters().get(0).getParentSection()); + + // Link the headers/footers of the third section to the headers/footers of the second section. + // The second section already links to the first section's header/footers, + // so linking to the second section will create a link chain. + // The first, second, and now the third sections will all display the first section's headers. + doc.getSections().get(2).getHeadersFooters().linkToPrevious(true); + + // We can un-link a previous section's header/footers by passing "false" when calling the LinkToPrevious method. + doc.getSections().get(2).getHeadersFooters().linkToPrevious(false); + + // We can also select only a specific type of header/footer to link using this method. + // The third section now will have the same footer as the second and first sections, but not the header. + doc.getSections().get(2).getHeadersFooters().linkToPrevious(HeaderFooterType.FOOTER_PRIMARY, true); + + // The first section's header/footers cannot link themselves to anything because there is no previous section. + Assert.assertEquals(2, doc.getSections().get(0).getHeadersFooters().getCount()); + Assert.assertEquals(0, IterableUtils.countMatches(doc.getSections().get(0).getHeadersFooters(), s -> s.isLinkedToPrevious())); + + // All the second section's header/footers are linked to the first section's headers/footers. + Assert.assertEquals(6, doc.getSections().get(1).getHeadersFooters().getCount()); + Assert.assertEquals(6, IterableUtils.countMatches(doc.getSections().get(1).getHeadersFooters(), s -> s.isLinkedToPrevious())); + + // In the third section, only the footer is linked to the first section's footer via the second section. + Assert.assertEquals(6, doc.getSections().get(2).getHeadersFooters().getCount()); + Assert.assertEquals(1, IterableUtils.countMatches(doc.getSections().get(2).getHeadersFooters(), s -> s.isLinkedToPrevious())); + Assert.assertTrue(doc.getSections().get(2).getHeadersFooters().get(3).isLinkedToPrevious()); + + doc.save(getArtifactsDir() + "HeaderFooter.Link.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "HeaderFooter.Link.docx"); + + Assert.assertEquals(2, doc.getSections().get(0).getHeadersFooters().getCount()); + Assert.assertEquals(0, IterableUtils.countMatches(doc.getSections().get(0).getHeadersFooters(), s -> s.isLinkedToPrevious())); + + Assert.assertEquals(0, doc.getSections().get(1).getHeadersFooters().getCount()); + Assert.assertEquals(0, IterableUtils.countMatches(doc.getSections().get(1).getHeadersFooters(), s -> s.isLinkedToPrevious())); + + Assert.assertEquals(5, doc.getSections().get(2).getHeadersFooters().getCount()); + Assert.assertEquals(0, IterableUtils.countMatches(doc.getSections().get(2).getHeadersFooters(), s -> s.isLinkedToPrevious())); + } + + @Test + public void removeFooters() throws Exception { + //ExStart + //ExFor:Section.HeadersFooters + //ExFor:HeaderFooterCollection + //ExFor:HeaderFooterCollection.Item(HeaderFooterType) + //ExFor:HeaderFooter + //ExSummary:Shows how to delete all footers from a document. + Document doc = new Document(getMyDir() + "Header and footer types.docx"); + + // Iterate through each section and remove footers of every kind. + for (Section section : doc.getSections()) { + // There are three kinds of footer and header types. + // 1 - The "First" header/footer, which only appears on the first page of a section. + HeaderFooter footer = section.getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_FIRST); + if (footer != null) { + footer.remove(); + } + + // 2 - The "Primary" header/footer, which appears on odd pages. + footer = section.getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY); + if (footer != null) { + footer.remove(); + } + + // 3 - The "Even" header/footer, which appears on even pages. + footer = section.getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_EVEN); + if (footer != null) { + footer.remove(); + } + + Assert.assertEquals(0, IterableUtils.countMatches(section.getHeadersFooters(), s -> !s.isHeader())); + } + + doc.save(getArtifactsDir() + "HeaderFooter.RemoveFooters.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "HeaderFooter.RemoveFooters.docx"); + + Assert.assertEquals(1, doc.getSections().getCount()); + Assert.assertEquals(0, IterableUtils.countMatches(doc.getFirstSection().getHeadersFooters(), s -> !s.isHeader())); + Assert.assertEquals(3, IterableUtils.countMatches(doc.getFirstSection().getHeadersFooters(), s -> s.isHeader())); + } + + @Test + public void exportMode() throws Exception { + //ExStart + //ExFor:HtmlSaveOptions.ExportHeadersFootersMode + //ExFor:ExportHeadersFootersMode + //ExSummary:Shows how to omit headers/footers when saving a document to HTML. + Document doc = new Document(getMyDir() + "Header and footer types.docx"); + + // This document contains headers and footers. We can access them via the "HeadersFooters" collection. + Assert.assertEquals("First header", doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.HEADER_FIRST).getText().trim()); + + // Formats such as .html do not split the document into pages, so headers/footers will not function the same way + // they would when we open the document as a .docx using Microsoft Word. + // If we convert a document with headers/footers to html, the conversion will assimilate the headers/footers into body text. + // We can use a SaveOptions object to omit headers/footers while converting to html. + HtmlSaveOptions saveOptions = + new HtmlSaveOptions(SaveFormat.HTML); + { + saveOptions.setExportHeadersFootersMode(ExportHeadersFootersMode.NONE); + } + + doc.save(getArtifactsDir() + "HeaderFooter.ExportMode.html", saveOptions); + + // Open our saved document and verify that it does not contain the header's text. + doc = new Document(getArtifactsDir() + "HeaderFooter.ExportMode.html"); + + Assert.assertFalse(doc.getRange().getText().contains("First header")); + //ExEnd + } + + @Test + public void replaceText() throws Exception { + //ExStart + //ExFor:Document.FirstSection + //ExFor:Section.HeadersFooters + //ExFor:HeaderFooterCollection.Item(HeaderFooterType) + //ExFor:HeaderFooter + //ExFor:Range.Replace(String, String, FindReplaceOptions) + //ExSummary:Shows how to replace text in a document's footer. + Document doc = new Document(getMyDir() + "Footer.docx"); + + HeaderFooterCollection headersFooters = doc.getFirstSection().getHeadersFooters(); + HeaderFooter footer = headersFooters.getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setMatchCase(false); + options.setFindWholeWordsOnly(false); + + int currentYear = Calendar.YEAR; + footer.getRange().replace("(C) 2006 Aspose Pty Ltd.", MessageFormat.format("Copyright (C) {0} by Aspose Pty Ltd.", currentYear), options); + + doc.save(getArtifactsDir() + "HeaderFooter.ReplaceText.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "HeaderFooter.ReplaceText.docx"); + Assert.assertTrue(doc.getRange().getText().contains(MessageFormat.format("Copyright (C) {0} by Aspose Pty Ltd.", currentYear))); + } + + //ExStart + //ExFor:IReplacingCallback + //ExFor:PageSetup.DifferentFirstPageHeaderFooter + //ExFor:FindReplaceOptions.#ctor(IReplacingCallback) + //ExSummary:Shows how to track the order in which a text replacement operation traverses nodes. + @Test(dataProvider = "orderDataProvider") //ExSkip + public void order(boolean differentFirstPageHeaderFooter) throws Exception { + Document doc = new Document(getMyDir() + "Header and footer types.docx"); + + Section firstPageSection = doc.getFirstSection(); + + ReplaceLog logger = new ReplaceLog(); + FindReplaceOptions options = new FindReplaceOptions(); + { + options.setReplacingCallback(logger); + } + + // Using a different header/footer for the first page will affect the search order. + firstPageSection.getPageSetup().setDifferentFirstPageHeaderFooter(differentFirstPageHeaderFooter); + doc.getRange().replace(Pattern.compile("(header|footer)"), "", options); + + if (differentFirstPageHeaderFooter) + Assert.assertEquals("First headerFirst footerSecond headerSecond footerThird headerThird footer", + logger.Text().replace("\r", "")); + else + Assert.assertEquals("Third headerFirst headerThird footerFirst footerSecond headerSecond footer", + logger.Text().replace("\r", "")); + } + + @DataProvider(name = "orderDataProvider") //ExSkip + public static Object[][] orderDataProvider() throws Exception { + return new Object[][] + { + {false}, + {true}, + }; + } + + /// <summary> + /// During a find-and-replace operation, records the contents of every node that has text that the operation 'finds', + /// in the state it is in before the replacement takes place. + /// This will display the order in which the text replacement operation traverses nodes. + /// </summary> + private static class ReplaceLog implements IReplacingCallback { + public int replacing(ReplacingArgs args) { + mTextBuilder.append(args.getMatchNode().getText()); + return ReplaceAction.SKIP; + } + + public String Text() { + return mTextBuilder.toString(); + } + + private final StringBuilder mTextBuilder = new StringBuilder(); + } + //ExEnd + + @Test + public void primer() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Section currentSection = builder.getCurrentSection(); + PageSetup pageSetup = currentSection.getPageSetup(); + + // Specify if we want headers/footers of the first page to be different from other pages. + // You can also use PageSetup.OddAndEvenPagesHeaderFooter property to specify + // different headers/footers for odd and even pages. + pageSetup.setDifferentFirstPageHeaderFooter(true); + + // Create header for the first page. + pageSetup.setHeaderDistance(20.0); + builder.moveToHeaderFooter(HeaderFooterType.HEADER_FIRST); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + + builder.getFont().setName("Arial"); + builder.getFont().setBold(true); + builder.getFont().setSize(14.0); + builder.write("Aspose.Words Header/Footer Creation Primer - Title Page."); + + // Create header for pages other than first. + pageSetup.setHeaderDistance(20.0); + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + + // Insert an absolutely positioned image into the top/left corner of the header. + // Distance from the top/left edges of the page is set to 10 points. + String imageFileName = getImageDir() + "Logo.jpg"; + builder.insertImage(imageFileName, RelativeHorizontalPosition.PAGE, 10.0, RelativeVerticalPosition.PAGE, 10.0, + 50.0, 50.0, WrapType.THROUGH); + + builder.getParagraphFormat().setAlignment(ParagraphAlignment.RIGHT); + builder.write("Aspose.Words Header/Footer Creation Primer."); + + // Create footer for pages other than first. + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + + // We use a table with two cells to make one part of the text on the line (with page numbering) + // to be aligned left, and the other part of the text (with copyright) to be aligned right. + builder.startTable(); + + builder.getCellFormat().clearFormatting(); + + builder.insertCell(); + + builder.getCellFormat().setPreferredWidth(PreferredWidth.fromPercent(100.0F / 3f)); + + // Insert page numbering text here. + // It uses PAGE and NUMPAGES fields to auto calculate the current page number and a total number of pages. + builder.write("Page "); + builder.insertField("PAGE", ""); + builder.write(" of "); + builder.insertField("NUMPAGES", ""); + + builder.getCurrentParagraph().getParagraphFormat().setAlignment(ParagraphAlignment.LEFT); + + builder.insertCell(); + builder.getCellFormat().setPreferredWidth(PreferredWidth.fromPercent(100.0F * 2f / 3f)); + + builder.write("(C) 2001 Aspose Pty Ltd. All rights reserved."); + + builder.getCurrentParagraph().getParagraphFormat().setAlignment(ParagraphAlignment.RIGHT); + + builder.endRow(); + builder.endTable(); + + builder.moveToDocumentEnd(); + builder.insertBreak(BreakType.PAGE_BREAK); + + // Make section break to create a third page with a different page orientation. + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + + currentSection = builder.getCurrentSection(); + pageSetup = currentSection.getPageSetup(); + + pageSetup.setOrientation(Orientation.LANDSCAPE); + + // This section does not need different first page header/footer. + // We need only one title page in the document and the header/footer for this page + // has already been defined in the previous section. + pageSetup.setDifferentFirstPageHeaderFooter(false); + + // This section displays headers/footers from the previous section by default. + // Call currentSection.HeadersFooters.LinkToPrevious(false) to cancel this. + // Page width is different for the new section and therefore we need to set + // a different cell widths for a footer table. + currentSection.getHeadersFooters().linkToPrevious(false); + + // If we want to use the already existing header/footer set for this section + // but with some minor modifications then it may be expedient to copy headers/footers + // from the previous section and apply the necessary modifications where we want them. + copyHeadersFootersFromPreviousSection(currentSection); + + HeaderFooter primaryFooter = currentSection.getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY); + + Row row = primaryFooter.getTables().get(0).getFirstRow(); + row.getFirstCell().getCellFormat().setPreferredWidth(PreferredWidth.fromPercent(100.0F / 3f)); + row.getLastCell().getCellFormat().setPreferredWidth(PreferredWidth.fromPercent(100.0F * 2f / 3f)); + + doc.save(getArtifactsDir() + "HeaderFooter.Primer.docx"); + } + + /** + * Clones and copies headers/footers form the previous section to the specified section. + */ + private static void copyHeadersFootersFromPreviousSection(final Section section) { + Section previousSection = (Section) section.getPreviousSibling(); + + if (previousSection == null) { + return; + } + + section.getHeadersFooters().clear(); + + for (HeaderFooter headerFooter : previousSection.getHeadersFooters()) { + section.getHeadersFooters().add(headerFooter.deepClone(true)); + } + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExHtmlFixedSaveOptions.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExHtmlFixedSaveOptions.java new file mode 100644 index 00000000..65212979 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExHtmlFixedSaveOptions.java @@ -0,0 +1,630 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.apache.commons.collections4.IterableUtils; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.FileOutputStream; +import java.nio.charset.StandardCharsets; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ExHtmlFixedSaveOptions extends ApiExampleBase { + @Test + public void useEncoding() throws Exception { + //ExStart + //ExFor:HtmlFixedSaveOptions.Encoding + //ExSummary:Shows how to set which encoding to use while exporting a document to HTML. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello World!"); + + // The default encoding is UTF-8. If we want to represent our document using a different encoding, + // we can use a SaveOptions object to set a specific encoding. + HtmlFixedSaveOptions htmlFixedSaveOptions = new HtmlFixedSaveOptions(); + htmlFixedSaveOptions.setEncoding(StandardCharsets.US_ASCII); + + Assert.assertEquals("US-ASCII", htmlFixedSaveOptions.getEncoding().name()); + + doc.save(getArtifactsDir() + "HtmlFixedSaveOptions.UseEncoding.html", htmlFixedSaveOptions); + //ExEnd + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlFixedSaveOptions.UseEncoding.html"), "US-ASCII"); + + Assert.assertTrue(outDocContents.contains("content=\"text/html; charset=US-ASCII\"")); + } + + @Test + public void getEncoding() throws Exception { + Document doc = DocumentHelper.createDocumentFillWithDummyText(); + + HtmlFixedSaveOptions htmlFixedSaveOptions = new HtmlFixedSaveOptions(); + htmlFixedSaveOptions.setEncoding(StandardCharsets.UTF_16); + + doc.save(getArtifactsDir() + "HtmlFixedSaveOptions.GetEncoding.html", htmlFixedSaveOptions); + } + + @Test(dataProvider = "exportEmbeddedCssDataProvider") + public void exportEmbeddedCss(boolean exportEmbeddedCss) throws Exception { + //ExStart + //ExFor:HtmlFixedSaveOptions.ExportEmbeddedCss + //ExSummary:Shows how to determine where to store CSS stylesheets when exporting a document to Html. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // When we export a document to html, Aspose.Words will also create a CSS stylesheet to format the document with. + // Setting the "ExportEmbeddedCss" flag to "true" save the CSS stylesheet to a .css file, + // and link to the file from the html document using a <link> element. + // Setting the flag to "false" will embed the CSS stylesheet within the Html document, + // which will create only one file instead of two. + HtmlFixedSaveOptions htmlFixedSaveOptions = new HtmlFixedSaveOptions(); + { + htmlFixedSaveOptions.setExportEmbeddedCss(exportEmbeddedCss); + } + + doc.save(getArtifactsDir() + "HtmlFixedSaveOptions.ExportEmbeddedCss.html", htmlFixedSaveOptions); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlFixedSaveOptions.ExportEmbeddedCss.html"), "utf-8"); + + if (exportEmbeddedCss) { + Assert.assertTrue(outDocContents.contains("<style type=\"text/css\">")); + Assert.assertFalse(new File(getArtifactsDir() + "HtmlFixedSaveOptions.ExportEmbeddedCss/styles.css").exists()); + } else { + Assert.assertTrue(outDocContents.contains("<link rel=\"stylesheet\" type=\"text/css\" href=\"HtmlFixedSaveOptions.ExportEmbeddedCss/styles.css\" media=\"all\" />")); + Assert.assertTrue(new File(getArtifactsDir() + "HtmlFixedSaveOptions.ExportEmbeddedCss/styles.css").exists()); + } + //ExEnd + } + + @DataProvider(name = "exportEmbeddedCssDataProvider") + public static Object[][] exportEmbeddedCssDataProvider() throws Exception { + return new Object[][] + { + {true}, + {false} + }; + } + + @Test(dataProvider = "exportEmbeddedFontsDataProvider") + public void exportEmbeddedFonts(boolean exportEmbeddedFonts) throws Exception { + //ExStart + //ExFor:HtmlFixedSaveOptions.ExportEmbeddedFonts + //ExSummary:Shows how to determine where to store embedded fonts when exporting a document to Html. + Document doc = new Document(getMyDir() + "Embedded font.docx"); + + // When we export a document with embedded fonts to .html, + // Aspose.Words can place the fonts in two possible locations. + // Setting the "ExportEmbeddedFonts" flag to "true" will store the raw data for embedded fonts within the CSS stylesheet, + // in the "url" property of the "@font-face" rule. This may create a huge CSS stylesheet file + // and reduce the number of external files that this HTML conversion will create. + // Setting this flag to "false" will create a file for each font. + // The CSS stylesheet will link to each font file using the "url" property of the "@font-face" rule. + HtmlFixedSaveOptions htmlFixedSaveOptions = new HtmlFixedSaveOptions(); + { + htmlFixedSaveOptions.setExportEmbeddedFonts(exportEmbeddedFonts); + } + + doc.save(getArtifactsDir() + "HtmlFixedSaveOptions.ExportEmbeddedFonts.html", htmlFixedSaveOptions); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlFixedSaveOptions.ExportEmbeddedFonts/styles.css"), StandardCharsets.UTF_8); + + if (exportEmbeddedFonts) + { + Assert.assertTrue(Pattern.compile("@font-face [{] font-family:'Arial'; font-style:normal; font-weight:normal; src:local[(]'☺'[)], url[(].+[)] format[(]'woff'[)]; [}]").matcher(outDocContents).find()); + Assert.assertEquals(0, DocumentHelper.directoryGetFiles(getArtifactsDir() + "HtmlFixedSaveOptions.ExportEmbeddedFonts", "*.woff").size()); + } + else + { + Assert.assertTrue(Pattern.compile("@font-face [{] font-family:'Arial'; font-style:normal; font-weight:normal; src:local[(]'☺'[)], url[(]'font001[.]woff'[)] format[(]'woff'[)]; [}]").matcher(outDocContents).find()); + Assert.assertEquals(2, DocumentHelper.directoryGetFiles(getArtifactsDir() + "HtmlFixedSaveOptions.ExportEmbeddedFonts", "*.woff").size()); + } + //ExEnd + } + + @DataProvider(name = "exportEmbeddedFontsDataProvider") + public static Object[][] exportEmbeddedFontsDataProvider() { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test(dataProvider = "exportEmbeddedImagesDataProvider") + public void exportEmbeddedImages(boolean exportImages) throws Exception { + //ExStart + //ExFor:HtmlFixedSaveOptions.ExportEmbeddedImages + //ExSummary:Shows how to determine where to store images when exporting a document to Html. + Document doc = new Document(getMyDir() + "Images.docx"); + + // When we export a document with embedded images to .html, + // Aspose.Words can place the images in two possible locations. + // Setting the "ExportEmbeddedImages" flag to "true" will store the raw data + // for all images within the output HTML document, in the "src" attribute of <image> tags. + // Setting this flag to "false" will create an image file in the local file system for every image, + // and store all these files in a separate folder. + HtmlFixedSaveOptions htmlFixedSaveOptions = new HtmlFixedSaveOptions(); + { + htmlFixedSaveOptions.setExportEmbeddedImages(exportImages); + } + + doc.save(getArtifactsDir() + "HtmlFixedSaveOptions.ExportEmbeddedImages.html", htmlFixedSaveOptions); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlFixedSaveOptions.ExportEmbeddedImages.html"), StandardCharsets.UTF_8); + + if (exportImages) + { + Assert.assertFalse(new File(getArtifactsDir() + "HtmlFixedSaveOptions.ExportEmbeddedImages/image001.jpeg").exists()); + Assert.assertTrue(Pattern.compile("<img class=\"awimg\" style=\"left:0pt; top:0pt; width:493.1pt; height:300.55pt;\" src=\".+\" />").matcher(outDocContents).find()); + } + else + { + Assert.assertTrue(new File(getArtifactsDir() + "HtmlFixedSaveOptions.ExportEmbeddedImages/image001.jpeg").exists()); + Assert.assertTrue(Pattern.compile("<img class=\"awimg\" style=\"left:0pt; top:0pt; width:493.1pt; height:300.55pt;\" " + + "src=\"HtmlFixedSaveOptions[.]ExportEmbeddedImages/image001[.]jpeg\" />").matcher(outDocContents).find()); + } + //ExEnd + } + + @DataProvider(name = "exportEmbeddedImagesDataProvider") + public static Object[][] exportEmbeddedImagesDataProvider() { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test(dataProvider = "exportEmbeddedSvgsDataProvider") + public void exportEmbeddedSvgs(boolean exportSvgs) throws Exception { + //ExStart + //ExFor:HtmlFixedSaveOptions.ExportEmbeddedSvg + //ExSummary:Shows how to determine where to store SVG objects when exporting a document to Html. + Document doc = new Document(getMyDir() + "Images.docx"); + + // When we export a document with SVG objects to .html, + // Aspose.Words can place these objects in two possible locations. + // Setting the "ExportEmbeddedSvg" flag to "true" will embed all SVG object raw data + // within the output HTML, inside <image> tags. + // Setting this flag to "false" will create a file in the local file system for each SVG object. + // The HTML will link to each file using the "data" attribute of an <object> tag. + HtmlFixedSaveOptions htmlFixedSaveOptions = new HtmlFixedSaveOptions(); + { + htmlFixedSaveOptions.setExportEmbeddedSvg(exportSvgs); + } + + doc.save(getArtifactsDir() + "HtmlFixedSaveOptions.ExportEmbeddedSvgs.html", htmlFixedSaveOptions); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlFixedSaveOptions.ExportEmbeddedSvgs.html"), StandardCharsets.UTF_8); + + if (exportSvgs) { + Assert.assertFalse(new File(getArtifactsDir() + "HtmlFixedSaveOptions.ExportEmbeddedSvgs/svg001.svg").exists()); + Assert.assertTrue(Pattern.compile("<image id=\"image004\" xlink:href=.+/>").matcher(outDocContents).find()); + } else { + Assert.assertTrue(new File(getArtifactsDir() + "HtmlFixedSaveOptions.ExportEmbeddedSvgs/svg001.svg").exists()); + Assert.assertTrue(Pattern.compile("<object type=\"image/svg[+]xml\" data=\"HtmlFixedSaveOptions.ExportEmbeddedSvgs/svg001[.]svg\"></object>").matcher(outDocContents).find()); + } + //ExEnd + } + + @DataProvider(name = "exportEmbeddedSvgsDataProvider") + public static Object[][] exportEmbeddedSvgsDataProvider() { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test(dataProvider = "exportFormFieldsDataProvider") + public void exportFormFields(boolean exportFormFields) throws Exception { + //ExStart + //ExFor:HtmlFixedSaveOptions.ExportFormFields + //ExSummary:Shows how to export form fields to Html. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertCheckBox("CheckBox", false, 15); + + // When we export a document with form fields to .html, + // there are two ways in which Aspose.Words can export form fields. + // Setting the "ExportFormFields" flag to "true" will export them as interactive objects. + // Setting this flag to "false" will display form fields as plain text. + // This will freeze them at their current value, and prevent the reader of our HTML document + // from being able to interact with them. + HtmlFixedSaveOptions htmlFixedSaveOptions = new HtmlFixedSaveOptions(); + { + htmlFixedSaveOptions.setExportFormFields(exportFormFields); + } + + doc.save(getArtifactsDir() + "HtmlFixedSaveOptions.ExportFormFields.html", htmlFixedSaveOptions); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlFixedSaveOptions.ExportFormFields.html"), StandardCharsets.UTF_8); + + if (exportFormFields) + { + Assert.assertTrue(Pattern.compile( + "<a name=\"CheckBox\" style=\"left:0pt; top:0pt;\"></a>" + + "<input style=\"position:absolute; left:0pt; top:0pt;\" type=\"checkbox\" name=\"CheckBox\" />").matcher(outDocContents).find()); + } + else + { + Assert.assertTrue(Pattern.compile( + "<a name=\"CheckBox\" style=\"left:0pt; top:0pt;\"></a>" + + "<div class=\"awdiv\" style=\"left:0.8pt; top:0.8pt; width:14.25pt; height:14.25pt; border:solid 0.75pt #000000;\"").matcher(outDocContents).find()); + } + //ExEnd + } + + @DataProvider(name = "exportFormFieldsDataProvider") + public static Object[][] exportFormFieldsDataProvider() { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test + public void addCssClassNamesPrefix() throws Exception { + //ExStart + //ExFor:HtmlFixedSaveOptions.CssClassNamesPrefix + //ExFor:HtmlFixedSaveOptions.SaveFontFaceCssSeparately + //ExSummary:Shows how to place CSS into a separate file and add a prefix to all of its CSS class names. + Document doc = new Document(getMyDir() + "Bookmarks.docx"); + + HtmlFixedSaveOptions htmlFixedSaveOptions = new HtmlFixedSaveOptions(); + { + htmlFixedSaveOptions.setCssClassNamesPrefix("myprefix"); + htmlFixedSaveOptions.setSaveFontFaceCssSeparately(true); + } + + doc.save(getArtifactsDir() + "HtmlFixedSaveOptions.AddCssClassNamesPrefix.html", htmlFixedSaveOptions); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlFixedSaveOptions.AddCssClassNamesPrefix.html"), StandardCharsets.UTF_8); + + Assert.assertTrue(Pattern.compile( + "<div class=\"myprefixdiv myprefixpage\" style=\"width:595[.]3pt; height:841[.]9pt;\">" + + "<div class=\"myprefixdiv\" style=\"left:85[.]05pt; top:36pt; clip:rect[(]0pt,510[.]25pt,74[.]95pt,-85.05pt[)];\">" + + "<span class=\"myprefixspan myprefixtext001\" style=\"font-size:11pt; left:294[.]73pt; top:0[.]36pt; line-height:12[.]29pt;\">").matcher(outDocContents).find()); + + outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlFixedSaveOptions.AddCssClassNamesPrefix/styles.css"), StandardCharsets.UTF_8); + + Assert.assertTrue(Pattern.compile( + ".myprefixdiv [{] position:absolute; [}] " + + ".myprefixspan [{] position:absolute; white-space:pre; color:#000000; font-size:12pt; [}]").matcher(outDocContents).find()); + //ExEnd + } + + @Test(dataProvider = "horizontalAlignmentDataProvider") + public void horizontalAlignment(int pageHorizontalAlignment) throws Exception { + //ExStart + //ExFor:HtmlFixedSaveOptions.PageHorizontalAlignment + //ExFor:HtmlFixedPageHorizontalAlignment + //ExSummary:Shows how to set the horizontal alignment of pages when saving a document to HTML. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlFixedSaveOptions htmlFixedSaveOptions = new HtmlFixedSaveOptions(); + { + htmlFixedSaveOptions.setPageHorizontalAlignment(pageHorizontalAlignment); + } + + doc.save(getArtifactsDir() + "HtmlFixedSaveOptions.HorizontalAlignment.html", htmlFixedSaveOptions); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlFixedSaveOptions.HorizontalAlignment/styles.css"), StandardCharsets.UTF_8); + + switch (pageHorizontalAlignment) + { + case HtmlFixedPageHorizontalAlignment.CENTER: + Assert.assertTrue(Pattern.compile( + "[.]awpage [{] position:relative; border:solid 1pt black; margin:10pt auto 10pt auto; overflow:hidden; [}]").matcher(outDocContents).find()); + break; + case HtmlFixedPageHorizontalAlignment.LEFT: + Assert.assertTrue(Pattern.compile( + "[.]awpage [{] position:relative; border:solid 1pt black; margin:10pt auto 10pt 10pt; overflow:hidden; [}]").matcher(outDocContents).find()); + break; + case HtmlFixedPageHorizontalAlignment.RIGHT: + Assert.assertTrue(Pattern.compile( + "[.]awpage [{] position:relative; border:solid 1pt black; margin:10pt 10pt 10pt auto; overflow:hidden; [}]").matcher(outDocContents).find()); + break; + } + //ExEnd + } + + @DataProvider(name = "horizontalAlignmentDataProvider") + public static Object[][] horizontalAlignmentDataProvider() { + return new Object[][] + { + {HtmlFixedPageHorizontalAlignment.CENTER}, + {HtmlFixedPageHorizontalAlignment.LEFT}, + {HtmlFixedPageHorizontalAlignment.RIGHT}, + }; + } + + @Test + public void pageMargins() throws Exception { + //ExStart + //ExFor:HtmlFixedSaveOptions.PageMargins + //ExSummary:Shows how to adjust page margins when saving a document to HTML. + Document doc = new Document(getMyDir() + "Document.docx"); + + HtmlFixedSaveOptions saveOptions = new HtmlFixedSaveOptions(); + { + saveOptions.setPageMargins(15.0); + } + + doc.save(getArtifactsDir() + "HtmlFixedSaveOptions.PageMargins.html", saveOptions); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlFixedSaveOptions.PageMargins/styles.css"), StandardCharsets.UTF_8); + + Assert.assertTrue(Pattern.compile( + "[.]awpage [{] position:relative; border:solid 1pt black; margin:15pt auto 15pt auto; overflow:hidden; [}]").matcher(outDocContents).find()); + //ExEnd + } + + @Test + public void pageMarginsException() { + HtmlFixedSaveOptions saveOptions = new HtmlFixedSaveOptions(); + Assert.assertThrows(IllegalArgumentException.class, () -> saveOptions.setPageMargins(-1)); + } + + @Test(dataProvider = "optimizeGraphicsOutputDataProvider") + public void optimizeGraphicsOutput(boolean optimizeOutput) throws Exception { + //ExStart + //ExFor:FixedPageSaveOptions.OptimizeOutput + //ExFor:HtmlFixedSaveOptions.OptimizeOutput + //ExSummary:Shows how to simplify a document when saving it to HTML by removing various redundant objects. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlFixedSaveOptions saveOptions = new HtmlFixedSaveOptions(); + { + saveOptions.setOptimizeOutput(optimizeOutput); + } + + doc.save(getArtifactsDir() + "HtmlFixedSaveOptions.OptimizeGraphicsOutput.html", saveOptions); + + // The size of the optimized version of the document is almost a third of the size of the unoptimized document. + if (optimizeOutput) + Assert.assertEquals(60385.0, + new File(getArtifactsDir() + "HtmlFixedSaveOptions.OptimizeGraphicsOutput.html").length(), 200.0); + else + Assert.assertEquals(191000.0, + new File(getArtifactsDir() + "HtmlFixedSaveOptions.OptimizeGraphicsOutput.html").length(), 200.0); + //ExEnd + } + + @DataProvider(name = "optimizeGraphicsOutputDataProvider") + public static Object[][] optimizeGraphicsOutputDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + + @Test(dataProvider = "usingMachineFontsDataProvider") + public void usingMachineFonts(boolean useTargetMachineFonts) throws Exception { + //ExStart + //ExFor:ExportFontFormat + //ExFor:HtmlFixedSaveOptions.FontFormat + //ExFor:HtmlFixedSaveOptions.UseTargetMachineFonts + //ExSummary:Shows how use fonts only from the target machine when saving a document to HTML. + Document doc = new Document(getMyDir() + "Bullet points with alternative font.docx"); + + HtmlFixedSaveOptions saveOptions = new HtmlFixedSaveOptions(); + { + saveOptions.setExportEmbeddedCss(true); + saveOptions.setUseTargetMachineFonts(useTargetMachineFonts); + saveOptions.setFontFormat(ExportFontFormat.TTF); + saveOptions.setExportEmbeddedFonts(false); + } + + doc.save(getArtifactsDir() + "HtmlFixedSaveOptions.UsingMachineFonts.html", saveOptions); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlFixedSaveOptions.UsingMachineFonts.html"), StandardCharsets.UTF_8); + + if (useTargetMachineFonts) + Assert.assertFalse(Pattern.compile("@font-face").matcher(outDocContents).find()); + else + Assert.assertTrue(Pattern.compile( + "@font-face [{] font-family:'Arial'; font-style:normal; font-weight:normal; src:local[(]'☺'[)], " + + "url[(]'HtmlFixedSaveOptions.UsingMachineFonts/font001.ttf'[)] format[(]'truetype'[)]; [}]").matcher(outDocContents).find()); + //ExEnd + } + + @DataProvider(name = "usingMachineFontsDataProvider") + public static Object[][] usingMachineFontsDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + //ExStart + //ExFor:IResourceSavingCallback + //ExFor:IResourceSavingCallback.ResourceSaving(ResourceSavingArgs) + //ExFor:ResourceSavingArgs + //ExFor:ResourceSavingArgs.Document + //ExFor:ResourceSavingArgs.ResourceFileName + //ExFor:ResourceSavingArgs.ResourceFileUri + //ExSummary:Shows how to use a callback to track external resources created while converting a document to HTML. + @Test //ExSkip + public void resourceSavingCallback() throws Exception { + Document doc = new Document(getMyDir() + "Bullet points with alternative font.docx"); + + FontSavingCallback callback = new FontSavingCallback(); + + HtmlFixedSaveOptions saveOptions = new HtmlFixedSaveOptions(); + { + saveOptions.setResourceSavingCallback(callback); + } + + doc.save(getArtifactsDir() + "HtmlFixedSaveOptions.UsingMachineFonts.html", saveOptions); + + System.out.println(callback.getText()); + testResourceSavingCallback(callback); //ExSkip + } + + private static class FontSavingCallback implements IResourceSavingCallback { + /// <summary> + /// Called when Aspose.Words saves an external resource to fixed page HTML or SVG. + /// </summary> + public void resourceSaving(ResourceSavingArgs args) { + mText.append(MessageFormat.format("Original document URI:\t{0}", args.getDocument().getOriginalFileName())); + mText.append(MessageFormat.format("Resource being saved:\t{0}", args.getResourceFileName())); + mText.append(MessageFormat.format("Full uri after saving:\t{0}\n", args.getResourceFileUri())); + } + + public String getText() { + return mText.toString(); + } + + private final StringBuilder mText = new StringBuilder(); + } + //ExEnd + + private void testResourceSavingCallback(FontSavingCallback callback) { + Assert.assertTrue(callback.getText().contains("font001.woff")); + Assert.assertTrue(callback.getText().contains("styles.css")); + } + + //ExStart + //ExFor:HtmlFixedSaveOptions + //ExFor:HtmlFixedSaveOptions.ResourceSavingCallback + //ExFor:HtmlFixedSaveOptions.ResourcesFolder + //ExFor:HtmlFixedSaveOptions.ResourcesFolderAlias + //ExFor:HtmlFixedSaveOptions.SaveFormat + //ExFor:HtmlFixedSaveOptions.ShowPageBorder + //ExFor:IResourceSavingCallback + //ExFor:IResourceSavingCallback.ResourceSaving(ResourceSavingArgs) + //ExFor:ResourceSavingArgs.KeepResourceStreamOpen + //ExFor:ResourceSavingArgs.ResourceStream + //ExSummary:Shows how to use a callback to print the URIs of external resources created while converting a document to HTML. + @Test //ExSkip + public void htmlFixedResourceFolder() throws Exception { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + ResourceUriPrinter callback = new ResourceUriPrinter(); + + HtmlFixedSaveOptions options = new HtmlFixedSaveOptions(); + { + options.setSaveFormat(SaveFormat.HTML_FIXED); + options.setExportEmbeddedImages(false); + options.setResourcesFolder(getArtifactsDir() + "HtmlFixedResourceFolder"); + options.setResourcesFolderAlias(getArtifactsDir() + "HtmlFixedResourceFolderAlias"); + options.setShowPageBorder(false); + options.setResourceSavingCallback(callback); + } + + // A folder specified by ResourcesFolderAlias will contain the resources instead of ResourcesFolder. + // We must ensure the folder exists before the streams can put their resources into it. + new File(options.getResourcesFolderAlias()).mkdir(); + + doc.save(getArtifactsDir() + "HtmlFixedSaveOptions.HtmlFixedResourceFolder.html", options); + + System.out.println(callback.getText()); + + String[] resourceFiles = new File(getArtifactsDir() + "HtmlFixedResourceFolderAlias").list(); + + Assert.assertFalse(new File(getArtifactsDir() + "HtmlFixedResourceFolder").exists()); + Assert.assertEquals(6, IterableUtils.countMatches(Arrays.asList(resourceFiles), + f -> f.endsWith(".jpeg") || f.endsWith(".png") || f.endsWith(".css"))); + testHtmlFixedResourceFolder(callback); //ExSkip + } + + /// <summary> + /// Counts and prints URIs of resources contained by as they are converted to fixed HTML. + /// </summary> + private static class ResourceUriPrinter implements IResourceSavingCallback { + public void resourceSaving(ResourceSavingArgs args) throws Exception { + // If we set a folder alias in the SaveOptions object, we will be able to print it from here. + mText.append(MessageFormat.format("Resource #{0} \"{1}\"", ++mSavedResourceCount, args.getResourceFileName())); + + String extension = FilenameUtils.getExtension(args.getResourceFileName()); + switch (extension) { + case "ttf": + case "woff": { + // By default, 'ResourceFileUri' uses system folder for fonts. + // To avoid problems in other platforms you must explicitly specify the path for the fonts. + args.setResourceFileUri(getArtifactsDir() + File.separatorChar + args.getResourceFileName()); + break; + } + } + + mText.append("\t" + args.getResourceFileUri()); + + // If we have specified a folder in the "ResourcesFolderAlias" property, + // we will also need to redirect each stream to put its resource in that folder. + args.setResourceStream(new FileOutputStream(args.getResourceFileUri())); + args.setKeepResourceStreamOpen(false); + } + + public String getText() { + return mText.toString(); + } + + private int mSavedResourceCount; + private final /*final*/ StringBuilder mText = new StringBuilder(); + } + //ExEnd + + private void testHtmlFixedResourceFolder(ResourceUriPrinter callback) + { + int count = 0; + + Matcher matcher = Pattern.compile("Resource #").matcher(callback.getText()); + while (matcher.find()) + count++; + + Assert.assertEquals(16, count); + } + + @Test + public void idPrefix() throws Exception + { + //ExStart:IdPrefix + //GistId:f86d49dc0e6781b93e576539a01e6ca2 + //ExFor:HtmlFixedSaveOptions.IdPrefix + //ExSummary:Shows how to add a prefix that is prepended to all generated element IDs. + Document doc = new Document(getMyDir() + "Id prefix.docx"); + + HtmlFixedSaveOptions saveOptions = new HtmlFixedSaveOptions(); + saveOptions.setIdPrefix("pfx1_"); + + doc.save(getArtifactsDir() + "HtmlFixedSaveOptions.IdPrefix.html", saveOptions); + //ExEnd:IdPrefix + } + + @Test + public void removeJavaScriptFromLinks() throws Exception + { + //ExStart:RemoveJavaScriptFromLinks + //GistId:f86d49dc0e6781b93e576539a01e6ca2 + //ExFor:HtmlFixedSaveOptions.RemoveJavaScriptFromLinks + //ExSummary:Shows how to remove JavaScript from the links for html fixed documents. + Document doc = new Document(getMyDir() + "JavaScript in HREF.docx"); + + HtmlFixedSaveOptions saveOptions = new HtmlFixedSaveOptions(); + saveOptions.setRemoveJavaScriptFromLinks(true); + + doc.save(getArtifactsDir() + "HtmlFixedSaveOptions.RemoveJavaScriptFromLinks.html", saveOptions); + //ExEnd:RemoveJavaScriptFromLinks + } +} \ No newline at end of file diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExHtmlLoadOptions.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExHtmlLoadOptions.java new file mode 100644 index 00000000..adf1fb47 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExHtmlLoadOptions.java @@ -0,0 +1,278 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.pdf.TextAbsorber; +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Date; + +public class ExHtmlLoadOptions extends ApiExampleBase { + @Test(dataProvider = "supportVmlDataProvider") + public void supportVml(boolean supportVml) throws Exception { + //ExStart + //ExFor:HtmlLoadOptions + //ExFor:HtmlLoadOptions.#ctor + //ExFor:HtmlLoadOptions.SupportVml + //ExSummary:Shows how to support conditional comments while loading an HTML document. + HtmlLoadOptions loadOptions = new HtmlLoadOptions(); + + // If the value is true, then we take VML code into account while parsing the loaded document. + loadOptions.setSupportVml(supportVml); + + // This document contains a JPEG image within "<!--[if gte vml 1]>" tags, + // and a different PNG image within "<![if !vml]>" tags. + // If we set the "SupportVml" flag to "true", then Aspose.Words will load the JPEG. + // If we set this flag to "false", then Aspose.Words will only load the PNG. + Document doc = new Document(getMyDir() + "VML conditional.htm", loadOptions); + + if (supportVml) + Assert.assertEquals(ImageType.JPEG, ((Shape) doc.getChild(NodeType.SHAPE, 0, true)).getImageData().getImageType()); + else + Assert.assertEquals(ImageType.PNG, ((Shape) doc.getChild(NodeType.SHAPE, 0, true)).getImageData().getImageType()); + //ExEnd + + Shape imageShape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + if (supportVml) + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, imageShape); + else + TestUtil.verifyImageInShape(400, 400, ImageType.PNG, imageShape); + } + + //JAVA-added data provider for test method + @DataProvider(name = "supportVmlDataProvider") + public static Object[][] supportVmlDataProvider() throws Exception { + return new Object[][] + { + {true}, + {false}, + }; + } + + /// <summary> + /// Stores all warnings that occur during a document loading operation in a List. + /// </summary> + private static class ListDocumentWarnings implements IWarningCallback { + public void warning(WarningInfo info) { + mWarnings.add(info); + } + + public ArrayList<WarningInfo> warnings() { + return mWarnings; + } + + private final ArrayList<WarningInfo> mWarnings = new ArrayList<>(); + } + + @Test + public void loadHtmlFixed() throws Exception + { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlFixedSaveOptions saveOptions = new HtmlFixedSaveOptions(); { saveOptions.setSaveFormat(SaveFormat.HTML_FIXED); } + + doc.save(getArtifactsDir() + "HtmlLoadOptions.Fixed.html", saveOptions); + + HtmlLoadOptions loadOptions = new HtmlLoadOptions(); + + ListDocumentWarnings warningCallback = new ListDocumentWarnings(); + loadOptions.setWarningCallback(warningCallback); + + doc = new Document(getArtifactsDir() + "HtmlLoadOptions.Fixed.html", loadOptions); + Assert.assertEquals(1, warningCallback.warnings().size()); + + Assert.assertEquals(WarningSource.HTML, warningCallback.warnings().get(0).getSource()); + Assert.assertEquals(WarningType.MAJOR_FORMATTING_LOSS, warningCallback.warnings().get(0).getWarningType()); + Assert.assertEquals("The document is fixed-page HTML. Its structure may not be loaded correctly.", warningCallback.warnings().get(0).getDescription()); + } + + @Test + public void encryptedHtml() throws Exception { + //ExStart + //ExFor:HtmlLoadOptions.#ctor(String) + //ExSummary:Shows how to encrypt an Html document, and then open it using a password. + // Create and sign an encrypted HTML document from an encrypted .docx. + CertificateHolder certificateHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + + SignOptions signOptions = new SignOptions(); + { + signOptions.setComments("Comment"); + signOptions.setSignTime(new Date()); + signOptions.setDecryptionPassword("docPassword"); + } + + String inputFileName = getMyDir() + "Encrypted.docx"; + String outputFileName = getArtifactsDir() + "HtmlLoadOptions.EncryptedHtml.html"; + DigitalSignatureUtil.sign(inputFileName, outputFileName, certificateHolder, signOptions); + + // To load and read this document, we will need to pass its decryption + // password using a HtmlLoadOptions object. + HtmlLoadOptions loadOptions = new HtmlLoadOptions("docPassword"); + Assert.assertEquals(loadOptions.getPassword(), signOptions.getDecryptionPassword()); + + Document doc = new Document(outputFileName, loadOptions); + Assert.assertEquals(doc.getText().trim(), "Test encrypted document."); + //ExEnd + } + + @Test + public void baseUri() throws Exception { + //ExStart + //ExFor:HtmlLoadOptions.#ctor(LoadFormat,String,String) + //ExFor:LoadOptions.#ctor(LoadFormat, String, String) + //ExFor:LoadOptions.LoadFormat + //ExFor:LoadFormat + //ExSummary:Shows how to specify a base URI when opening an html document. + // Suppose we want to load an .html document that contains an image linked by a relative URI + // while the image is in a different location. In that case, we will need to resolve the relative URI into an absolute one. + // We can provide a base URI using an HtmlLoadOptions object. + HtmlLoadOptions loadOptions = new HtmlLoadOptions(LoadFormat.HTML, "", getImageDir()); + + Assert.assertEquals(LoadFormat.HTML, loadOptions.getLoadFormat()); + + Document doc = new Document(getMyDir() + "Missing image.html", loadOptions); + + // While the image was broken in the input .html, our custom base URI helped us repair the link. + Shape imageShape = (Shape) doc.getChildNodes(NodeType.SHAPE, true).get(0); + Assert.assertTrue(imageShape.isImage()); + + // This output document will display the image that was missing. + doc.save(getArtifactsDir() + "HtmlLoadOptions.BaseUri.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "HtmlLoadOptions.BaseUri.docx"); + + Assert.assertTrue(((Shape) doc.getChild(NodeType.SHAPE, 0, true)).getImageData().getImageBytes().length > 0); + } + + @Test + public void getSelectAsSdt() throws Exception { + //ExStart + //ExFor:HtmlLoadOptions.PreferredControlType + //ExFor:HtmlControlType + //ExSummary:Shows how to set preferred type of document nodes that will represent imported <input> and <select> elements. + final String html = "\r\n<html>\r\n<select name='ComboBox' size='1'>\r\n" + + "<option value='val1'>item1</option>\r\n<option value='val2'></option>\r\n</select>\r\n</html>\r\n"; + + HtmlLoadOptions htmlLoadOptions = new HtmlLoadOptions(); + htmlLoadOptions.setPreferredControlType(HtmlControlType.STRUCTURED_DOCUMENT_TAG); + + Document doc = new Document(new ByteArrayInputStream(html.getBytes(StandardCharsets.UTF_8)), htmlLoadOptions); + NodeCollection nodes = doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG, true); + + StructuredDocumentTag tag = (StructuredDocumentTag) nodes.get(0); + //ExEnd + + Assert.assertEquals(tag.getListItems().getCount(), 2); + + Assert.assertEquals(tag.getListItems().get(0).getValue(), "val1"); + Assert.assertEquals(tag.getListItems().get(1).getValue(), "val2"); + } + + @Test + public void getInputAsFormField() throws Exception { + final String html = "\r\n<html>\r\n<input type='text' value='Input value text' />\r\n</html>\r\n"; + + // By default, "HtmlLoadOptions.PreferredControlType" value is "HtmlControlType.FormField". + // So, we do not set this value. + HtmlLoadOptions htmlLoadOptions = new HtmlLoadOptions(); + + Document doc = new Document(new ByteArrayInputStream(html.getBytes(StandardCharsets.UTF_8)), htmlLoadOptions); + NodeCollection nodes = doc.getChildNodes(NodeType.FORM_FIELD, true); + + Assert.assertEquals(nodes.getCount(), 1); + + FormField formField = (FormField) nodes.get(0); + Assert.assertEquals(formField.getResult(), "Input value text"); + } + + @Test (dataProvider = "ignoreNoscriptElementsDataProvider") + public void ignoreNoscriptElements(boolean ignoreNoscriptElements) throws Exception + { + //ExStart + //ExFor:HtmlLoadOptions.IgnoreNoscriptElements + //ExSummary:Shows how to ignore <noscript> HTML elements. + final String html = "\r\n<html>\r\n<head>\r\n<title>NOSCRIPT\r\n\r\n\r\n\r\n\r\n\r\n\r\n"; + + HtmlLoadOptions htmlLoadOptions = new HtmlLoadOptions(); + htmlLoadOptions.setIgnoreNoscriptElements(ignoreNoscriptElements); + + Document doc = new Document(new ByteArrayInputStream(html.getBytes(StandardCharsets.UTF_8)), htmlLoadOptions); + doc.save(getArtifactsDir() + "HtmlLoadOptions.IgnoreNoscriptElements.pdf"); + //ExEnd + + com.aspose.pdf.Document pdfDoc = new com.aspose.pdf.Document(getArtifactsDir() + "HtmlLoadOptions.IgnoreNoscriptElements.pdf"); + TextAbsorber textAbsorber = new TextAbsorber(); + textAbsorber.visit(pdfDoc); + + Assert.assertEquals(ignoreNoscriptElements ? "" : "Your browser does not support JavaScript!", textAbsorber.getText()); + + pdfDoc.close(); + } + + @DataProvider(name = "ignoreNoscriptElementsDataProvider") + public static Object[][] ignoreNoscriptElementsDataProvider() { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test (dataProvider = "blockImportDataProvider") + public void blockImport(int blockImportMode) throws Exception + { + //ExStart + //ExFor:HtmlLoadOptions.BlockImportMode + //ExFor:BlockImportMode + //ExSummary:Shows how properties of block-level elements are imported from HTML-based documents. + final String html = "\n\n
\n
\n

paragraph 1

\n

paragraph 2

\n
\n
\n"; + + HtmlLoadOptions loadOptions = new HtmlLoadOptions(); + // Set the new mode of import HTML block-level elements. + loadOptions.setBlockImportMode(blockImportMode); + + Document doc = new Document(new ByteArrayInputStream(html.getBytes(StandardCharsets.UTF_8)), loadOptions); + doc.save(getArtifactsDir() + "HtmlLoadOptions.BlockImport.docx"); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "blockImportDataProvider") + public static Object[][] blockImportDataProvider() throws Exception + { + return new Object[][] + { + {BlockImportMode.PRESERVE}, + {BlockImportMode.MERGE}, + }; + } + + @Test + public void fontFaceRules() throws Exception + { + //ExStart:FontFaceRules + //GistId:31b7350f8d91d4b12eb43978940d566a + //ExFor:HtmlLoadOptions.SupportFontFaceRules + //ExSummary:Shows how to load declared "@font-face" rules. + HtmlLoadOptions loadOptions = new HtmlLoadOptions(); + loadOptions.setSupportFontFaceRules(true); + Document doc = new Document(getMyDir() + "Html with FontFace.html", loadOptions); + + Assert.assertEquals("Squarish Sans CT Regular", doc.getFontInfos().get(0).getName()); + //ExEnd:FontFaceRules + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExHtmlSaveOptions.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExHtmlSaveOptions.java new file mode 100644 index 00000000..ced150c6 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExHtmlSaveOptions.java @@ -0,0 +1,2053 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.apache.commons.collections4.IterableUtils; +import org.apache.commons.io.FileUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +public class ExHtmlSaveOptions extends ApiExampleBase { + @Test(dataProvider = "exportPageMarginsEpubDataProvider") + public void exportPageMarginsEpub(int saveFormat) throws Exception { + Document doc = new Document(getMyDir() + "TextBoxes.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + { + saveOptions.setSaveFormat(saveFormat); + saveOptions.setExportPageMargins(true); + } + + doc.save( + getArtifactsDir() + "HtmlSaveOptions.ExportPageMarginsEpub" + + FileFormatUtil.saveFormatToExtension(saveFormat), saveOptions); + } + + @DataProvider(name = "exportPageMarginsEpubDataProvider") + public static Object[][] exportPageMarginsEpubDataProvider() { + return new Object[][] + { + {SaveFormat.HTML}, + {SaveFormat.MHTML}, + {SaveFormat.EPUB}, + {SaveFormat.AZW_3}, + {SaveFormat.MOBI} + }; + } + + @Test(dataProvider = "exportOfficeMathEpubDataProvider") + public void exportOfficeMathEpub(int saveFormat, int outputMode) throws Exception { + Document doc = new Document(getMyDir() + "Office math.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + saveOptions.setOfficeMathOutputMode(outputMode); + + doc.save( + getArtifactsDir() + "HtmlSaveOptions.ExportOfficeMathEpub" + + FileFormatUtil.saveFormatToExtension(saveFormat), saveOptions); + } + + @DataProvider(name = "exportOfficeMathEpubDataProvider") + public static Object[][] exportOfficeMathEpubDataProvider() { + return new Object[][] + { + {SaveFormat.HTML, HtmlOfficeMathOutputMode.IMAGE}, + {SaveFormat.MHTML, HtmlOfficeMathOutputMode.MATH_ML}, + {SaveFormat.EPUB, HtmlOfficeMathOutputMode.TEXT}, + {SaveFormat.AZW_3, HtmlOfficeMathOutputMode.TEXT}, + {SaveFormat.MOBI, HtmlOfficeMathOutputMode.TEXT} + }; + } + + @Test(dataProvider = "exportTextBoxAsSvgEpubDataProvider") + public void exportTextBoxAsSvgEpub(int saveFormat, boolean isTextBoxAsSvg) throws Exception { + ArrayList dirFiles; + + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape textbox = builder.insertShape(ShapeType.TEXT_BOX, 300.0, 100.0); + builder.moveTo(textbox.getFirstParagraph()); + builder.write("Hello world!"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(saveFormat); + saveOptions.setExportShapesAsSvg(isTextBoxAsSvg); + + doc.save(getArtifactsDir() + "HtmlSaveOptions.ExportTextBoxAsSvgEpub" + FileFormatUtil.saveFormatToExtension(saveFormat), saveOptions); + + switch (saveFormat) { + case SaveFormat.HTML: + case SaveFormat.EPUB: + case SaveFormat.MHTML: + case SaveFormat.AZW_3: + case SaveFormat.MOBI: + + dirFiles = DocumentHelper.directoryGetFiles(getArtifactsDir(), "HtmlSaveOptions.ExportTextBoxAsSvgEpub.001.png"); + Assert.assertTrue(dirFiles.isEmpty()); + return; + } + } + + @DataProvider(name = "exportTextBoxAsSvgEpubDataProvider") + public static Object[][] exportTextBoxAsSvgEpubDataProvider() { + return new Object[][] + { + {SaveFormat.HTML, true}, + {SaveFormat.EPUB, true}, + {SaveFormat.MHTML, false}, + {SaveFormat.AZW_3, false}, + {SaveFormat.MOBI, false}, + }; + } + + @Test + public void createAZW3Toc() throws Exception + { + //ExStart + //ExFor:HtmlSaveOptions.NavigationMapLevel + //ExSummary:Shows how to generate table of contents for Azw3 documents. + Document doc = new Document(getMyDir() + "Big document.docx"); + + HtmlSaveOptions options = new HtmlSaveOptions(SaveFormat.AZW_3); + options.setNavigationMapLevel(2); + + doc.save(getArtifactsDir() + "HtmlSaveOptions.CreateAZW3Toc.azw3", options); + //ExEnd + } + + @Test + public void createMobiToc() throws Exception + { + //ExStart + //ExFor:HtmlSaveOptions.NavigationMapLevel + //ExSummary:Shows how to generate table of contents for Mobi documents. + Document doc = new Document(getMyDir() + "Big document.docx"); + + HtmlSaveOptions options = new HtmlSaveOptions(SaveFormat.MOBI); + options.setNavigationMapLevel(5); + + doc.save(getArtifactsDir() + "HtmlSaveOptions.CreateMobiToc.mobi", options); + //ExEnd + } + + @Test(dataProvider = "controlListLabelsExportDataProvider") + public void controlListLabelsExport(final int howExportListLabels) throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + List bulletedList = doc.getLists().add(ListTemplate.BULLET_DEFAULT); + builder.getListFormat().setList(bulletedList); + builder.getParagraphFormat().setLeftIndent(72.0); + builder.writeln("Bulleted list item 1."); + builder.writeln("Bulleted list item 2."); + builder.getParagraphFormat().clearFormatting(); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(SaveFormat.HTML); + { + // 'ExportListLabels.Auto' - this option uses
    and
      tags are used for list label representation if it does not cause formatting loss, + // otherwise HTML

      tag is used. This is also the default value. + // 'ExportListLabels.AsInlineText' - using this option the

      tag is used for any list label representation. + // 'ExportListLabels.ByHtmlTags' - The

        and
          tags are used for list label representation. Some formatting loss is possible. + saveOptions.setExportListLabels(howExportListLabels); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.ControlListLabelsExport.html", saveOptions); + } + + @DataProvider(name = "controlListLabelsExportDataProvider") + public static Object[][] controlListLabelsExportDataProvider() { + return new Object[][]{ + {ExportListLabels.AUTO}, + {ExportListLabels.AS_INLINE_TEXT}, + {ExportListLabels.BY_HTML_TAGS} + }; + } + + @Test(dataProvider = "exportUrlForLinkedImageDataProvider") + public void exportUrlForLinkedImage(boolean export) throws Exception { + Document doc = new Document(getMyDir() + "Linked image.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + saveOptions.setExportOriginalUrlForLinkedImages(export); + + doc.save(getArtifactsDir() + "HtmlSaveOptions.ExportUrlForLinkedImage.html", saveOptions); + + ArrayList dirFiles = DocumentHelper.directoryGetFiles(getArtifactsDir() + "", "HtmlSaveOptions.ExportUrlForLinkedImage.001.png"); + + if (dirFiles.size() == 0) { + DocumentHelper.findTextInFile(getArtifactsDir() + "HtmlSaveOptions.ExportUrlForLinkedImage.html", " imageFiles = DocumentHelper.directoryGetFiles(getArtifactsDir() + "Resources/", "HtmlSaveOptions.ExternalResourceSavingConfig*.png"); + Assert.assertEquals(imageFiles.size(), 8); + + ArrayList fontFiles = DocumentHelper.directoryGetFiles(getArtifactsDir() + "Resources/", "HtmlSaveOptions.ExternalResourceSavingConfig*.ttf"); + Assert.assertEquals(fontFiles.size(), 10); + + ArrayList cssFiles = DocumentHelper.directoryGetFiles(getArtifactsDir() + "Resources/", "HtmlSaveOptions.ExternalResourceSavingConfig*.css"); + Assert.assertEquals(cssFiles.size(), 1); + + DocumentHelper.findTextInFile(getArtifactsDir() + "HtmlSaveOptions.ExternalResourceSavingConfig.html", "\r\n\r\n "); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + saveOptions.setMetafileFormat(HtmlMetafileFormat.SVG); + + builder.getDocument().save(getArtifactsDir() + "HtmlSaveOptions.SvgMetafileFormat.html", saveOptions); + } + + @Test + public void pngMetafileFormat() throws Exception { + DocumentBuilder builder = new DocumentBuilder(); + + builder.write("Here is an Png image: "); + builder.insertHtml("\r\n\r\n"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + saveOptions.setMetafileFormat(HtmlMetafileFormat.PNG); + + builder.getDocument().save(getArtifactsDir() + "HtmlSaveOptions.PngMetafileFormat.html", saveOptions); + } + + @Test + public void emfOrWmfMetafileFormat() throws Exception { + DocumentBuilder builder = new DocumentBuilder(); + + builder.write("Here is an image as is: "); + builder.insertHtml("\"Red"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + saveOptions.setMetafileFormat(HtmlMetafileFormat.EMF_OR_WMF); + + builder.getDocument().save(getArtifactsDir() + "HtmlSaveOptions.EmfOrWmfMetafileFormat.html", saveOptions); + } + + @Test + public void cssClassNamesPrefix() throws Exception { + //ExStart + //ExFor:HtmlSaveOptions.CssClassNamePrefix + //ExSummary:Shows how to save a document to HTML, and add a prefix to all of its CSS class names. + Document doc = new Document(getMyDir() + "Paragraphs.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + { + saveOptions.setCssStyleSheetType(CssStyleSheetType.EXTERNAL); + saveOptions.setCssClassNamePrefix("myprefix-"); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.CssClassNamePrefix.html", saveOptions); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlSaveOptions.CssClassNamePrefix.html"), StandardCharsets.UTF_8); + + Assert.assertTrue(outDocContents.contains("

          ")); + Assert.assertTrue(outDocContents.contains("

          ")); + + outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlSaveOptions.CssClassNamePrefix.css"), StandardCharsets.UTF_8); + + Assert.assertTrue(outDocContents.contains(".myprefix-Footer { margin-bottom:0pt; line-height:normal; font-family:Arial; font-size:11pt; -aw-style-name:footer }\r\n" + + ".myprefix-Header { margin-bottom:0pt; line-height:normal; font-family:Arial; font-size:11pt; -aw-style-name:header }\r\n")); + //ExEnd + } + + @Test + public void cssClassNamesNotValidPrefix() { + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + Assert.assertThrows(IllegalArgumentException.class, () -> saveOptions.setCssClassNamePrefix("@%-")); + } + + @Test + public void cssClassNamesNullPrefix() throws Exception { + Document doc = new Document(getMyDir() + "Paragraphs.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + saveOptions.setCssStyleSheetType(CssStyleSheetType.EMBEDDED); + saveOptions.setCssClassNamePrefix(null); + + doc.save(getArtifactsDir() + "HtmlSaveOptions.CssClassNamePrefix.html", saveOptions); + } + + @Test + public void contentIdScheme() throws Exception { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(SaveFormat.MHTML); + saveOptions.setPrettyFormat(true); + saveOptions.setExportCidUrlsForMhtmlResources(true); + + doc.save(getArtifactsDir() + "HtmlSaveOptions.ContentIdScheme.mhtml", saveOptions); + } + + @Test(enabled = false, description = "Bug", dataProvider = "resolveFontNamesDataProvider") + public void resolveFontNames(boolean resolveFontNames) throws Exception { + //ExStart + //ExFor:HtmlSaveOptions.ResolveFontNames + //ExSummary:Shows how to resolve all font names before writing them to HTML. + Document doc = new Document(getMyDir() + "Missing font.docx"); + + // This document contains text that names a font that we do not have. + Assert.assertNotNull(doc.getFontInfos().get("28 Days Later")); + + // If we have no way of getting this font, and we want to be able to display all the text + // in this document in an output HTML, we can substitute it with another font. + FontSettings fontSettings = new FontSettings(); + { + fontSettings.getSubstitutionSettings().getDefaultFontSubstitution().setDefaultFontName("Arial"); + fontSettings.getSubstitutionSettings().getDefaultFontSubstitution().setEnabled(true); + } + + doc.setFontSettings(fontSettings); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(SaveFormat.HTML); + { + // By default, this option is set to 'False' and Aspose.Words writes font names as specified in the source document. + saveOptions.setResolveFontNames(resolveFontNames); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.ResolveFontNames.html", saveOptions); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlSaveOptions.ResolveFontNames.html"), "utf-8"); + + Assert.assertTrue(outDocContents.matches("")); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "resolveFontNamesDataProvider") + public static Object[][] resolveFontNamesDataProvider() throws Exception { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void headingLevels() throws Exception { + //ExStart + //ExFor:HtmlSaveOptions.DocumentSplitHeadingLevel + //ExSummary:Shows how to split an output HTML document by headings into several parts. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Every paragraph that we format using a "Heading" style can serve as a heading. + // Each heading may also have a heading level, determined by the number of its heading style. + // The headings below are of levels 1-3. + builder.getParagraphFormat().setStyle(builder.getDocument().getStyles().get("Heading 1")); + builder.writeln("Heading #1"); + builder.getParagraphFormat().setStyle(builder.getDocument().getStyles().get("Heading 2")); + builder.writeln("Heading #2"); + builder.getParagraphFormat().setStyle(builder.getDocument().getStyles().get("Heading 3")); + builder.writeln("Heading #3"); + builder.getParagraphFormat().setStyle(builder.getDocument().getStyles().get("Heading 1")); + builder.writeln("Heading #4"); + builder.getParagraphFormat().setStyle(builder.getDocument().getStyles().get("Heading 2")); + builder.writeln("Heading #5"); + builder.getParagraphFormat().setStyle(builder.getDocument().getStyles().get("Heading 3")); + builder.writeln("Heading #6"); + + // Create a HtmlSaveOptions object and set the split criteria to "HeadingParagraph". + // These criteria will split the document at paragraphs with "Heading" styles into several smaller documents, + // and save each document in a separate HTML file in the local file system. + // We will also set the maximum heading level, which splits the document to 2. + // Saving the document will split it at headings of levels 1 and 2, but not at 3 to 9. + HtmlSaveOptions options = new HtmlSaveOptions(); + { + options.setDocumentSplitCriteria(DocumentSplitCriteria.HEADING_PARAGRAPH); + options.setDocumentSplitHeadingLevel(2); + } + + // Our document has four headings of levels 1 - 2. One of those headings will not be + // a split point since it is at the beginning of the document. + // The saving operation will split our document at three places, into four smaller documents. + doc.save(getArtifactsDir() + "HtmlSaveOptions.HeadingLevels.html", options); + + doc = new Document(getArtifactsDir() + "HtmlSaveOptions.HeadingLevels.html"); + + Assert.assertEquals("Heading #1", doc.getText().trim()); + + doc = new Document(getArtifactsDir() + "HtmlSaveOptions.HeadingLevels-01.html"); + + Assert.assertEquals("Heading #2\r" + + "Heading #3", doc.getText().trim()); + + doc = new Document(getArtifactsDir() + "HtmlSaveOptions.HeadingLevels-02.html"); + + Assert.assertEquals("Heading #4", doc.getText().trim()); + + doc = new Document(getArtifactsDir() + "HtmlSaveOptions.HeadingLevels-03.html"); + + Assert.assertEquals("Heading #5\rHeading #6", doc.getText().trim()); + //ExEnd + } + + @Test(dataProvider = "negativeIndentDataProvider") + public void negativeIndent(boolean allowNegativeIndent) throws Exception { + //ExStart + //ExFor:HtmlElementSizeOutputMode + //ExFor:HtmlSaveOptions.AllowNegativeIndent + //ExFor:HtmlSaveOptions.TableWidthOutputMode + //ExSummary:Shows how to preserve negative indents in the output .html. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a table with a negative indent, which will push it to the left past the left page boundary. + Table table = builder.startTable(); + builder.insertCell(); + builder.write("Row 1, Cell 1"); + builder.insertCell(); + builder.write("Row 1, Cell 2"); + builder.endTable(); + table.setLeftIndent(-36); + table.setPreferredWidth(PreferredWidth.fromPoints(144.0)); + + builder.insertBreak(BreakType.PARAGRAPH_BREAK); + + // Insert a table with a positive indent, which will push the table to the right. + table = builder.startTable(); + builder.insertCell(); + builder.write("Row 1, Cell 1"); + builder.insertCell(); + builder.write("Row 1, Cell 2"); + builder.endTable(); + table.setLeftIndent(36.0); + table.setPreferredWidth(PreferredWidth.fromPoints(144.0)); + + // When we save a document to HTML, Aspose.Words will only preserve negative indents + // such as the one we have applied to the first table if we set the "AllowNegativeIndent" flag + // in a SaveOptions object that we will pass to "true". + HtmlSaveOptions options = new HtmlSaveOptions(SaveFormat.HTML); + { + options.setAllowNegativeIndent(allowNegativeIndent); + options.setTableWidthOutputMode(HtmlElementSizeOutputMode.RELATIVE_ONLY); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.NegativeIndent.html", options); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlSaveOptions.NegativeIndent.html"), StandardCharsets.UTF_8); + + if (allowNegativeIndent) { + Assert.assertTrue(outDocContents.contains( + "")); + Assert.assertTrue(outDocContents.contains( + "
          ")); + } else { + Assert.assertTrue(outDocContents.contains( + "
          ")); + Assert.assertTrue(outDocContents.contains( + "
          ")); + } + //ExEnd + } + + @DataProvider(name = "negativeIndentDataProvider") + public static Object[][] negativeIndentDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void folderAlias() throws Exception { + //ExStart + //ExFor:HtmlSaveOptions.ExportOriginalUrlForLinkedImages + //ExFor:HtmlSaveOptions.FontsFolder + //ExFor:HtmlSaveOptions.FontsFolderAlias + //ExFor:HtmlSaveOptions.ImageResolution + //ExFor:HtmlSaveOptions.ImagesFolderAlias + //ExFor:HtmlSaveOptions.ResourceFolder + //ExFor:HtmlSaveOptions.ResourceFolderAlias + //ExSummary:Shows how to set folders and folder aliases for externally saved resources that Aspose.Words will create when saving a document to HTML. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlSaveOptions options = new HtmlSaveOptions(); + { + options.setCssStyleSheetType(CssStyleSheetType.EXTERNAL); + options.setExportFontResources(true); + options.setImageResolution(72); + options.setFontResourcesSubsettingSizeThreshold(0); + options.setFontsFolder(getArtifactsDir() + "Fonts"); + options.setImagesFolder(getArtifactsDir() + "Images"); + options.setResourceFolder(getArtifactsDir() + "Resources"); + options.setFontsFolderAlias("http://example.com/fonts"); + options.setImagesFolderAlias("http://example.com/images"); + options.setResourceFolderAlias("http://example.com/resources"); + options.setExportOriginalUrlForLinkedImages(true); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.FolderAlias.html", options); + //ExEnd + } + + //ExStart + //ExFor:HtmlSaveOptions.ExportFontResources + //ExFor:HtmlSaveOptions.FontSavingCallback + //ExFor:IFontSavingCallback + //ExFor:IFontSavingCallback.FontSaving + //ExFor:FontSavingArgs + //ExFor:FontSavingArgs.Bold + //ExFor:FontSavingArgs.Document + //ExFor:FontSavingArgs.FontFamilyName + //ExFor:FontSavingArgs.FontFileName + //ExFor:FontSavingArgs.FontStream + //ExFor:FontSavingArgs.IsExportNeeded + //ExFor:FontSavingArgs.IsSubsettingNeeded + //ExFor:FontSavingArgs.Italic + //ExFor:FontSavingArgs.KeepFontStreamOpen + //ExFor:FontSavingArgs.OriginalFileName + //ExFor:FontSavingArgs.OriginalFileSize + //ExSummary:Shows how to define custom logic for exporting fonts when saving to HTML. + @Test(enabled = false) //ExSkip + public void saveExportedFonts() throws Exception { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // Configure a SaveOptions object to export fonts to separate files. + // Set a callback that will handle font saving in a custom manner. + HtmlSaveOptions options = new HtmlSaveOptions(); + { + options.setExportFontResources(true); + options.setFontSavingCallback(new HandleFontSaving()); + } + + // The callback will export .ttf files and save them alongside the output document. + doc.save(getArtifactsDir() + "HtmlSaveOptions.SaveExportedFonts.html", options); + + File[] fontFileNames = new File(getArtifactsDir()).listFiles((d, name) -> name.endsWith(".ttf")); + + for (File fontFilename : fontFileNames) { + System.out.println(fontFilename.getName()); + } + + Assert.assertEquals(10, fontFileNames.length); //ExSkip + } + + /// + /// Prints information about exported fonts and saves them in the same local system folder as their output .html. + /// + public static class HandleFontSaving implements IFontSavingCallback { + public void fontSaving(FontSavingArgs args) throws Exception { + System.out.println(MessageFormat.format("Font:\t{0}", args.getFontFamilyName())); + if (args.getBold()) System.out.print(", bold"); + if (args.getItalic()) System.out.print(", italic"); + System.out.println(MessageFormat.format("\nSource:\t{0}, {1} bytes\n", args.getOriginalFileName(), args.getOriginalFileSize())); + + // We can also access the source document from here. + Assert.assertTrue(args.getDocument().getOriginalFileName().endsWith("Rendering.docx")); + + Assert.assertTrue(args.isExportNeeded()); + Assert.assertTrue(args.isSubsettingNeeded()); + + String[] splittedFileName = args.getOriginalFileName().split("\\\\"); + String fileName = splittedFileName[splittedFileName.length - 1]; + + // There are two ways of saving an exported font. + // 1 - Save it to a local file system location: + args.setFontFileName(fileName); + + // 2 - Save it to a stream: + args.setFontStream(new FileOutputStream(fileName)); + Assert.assertFalse(args.getKeepFontStreamOpen()); + } + } + //ExEnd + + @Test(dataProvider = "htmlVersionsDataProvider") + public void htmlVersions(/*HtmlVersion*/int htmlVersion) throws Exception { + //ExStart + //ExFor:HtmlSaveOptions.#ctor(SaveFormat) + //ExFor:HtmlSaveOptions.HtmlVersion + //ExFor:HtmlVersion + //ExSummary:Shows how to save a document to a specific version of HTML. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlSaveOptions options = new HtmlSaveOptions(SaveFormat.HTML); + { + options.setHtmlVersion(htmlVersion); + options.setPrettyFormat(true); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.HtmlVersions.html", options); + + // Our HTML documents will have minor differences to be compatible with different HTML versions. + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlSaveOptions.HtmlVersions.html"), StandardCharsets.UTF_8); + + switch (htmlVersion) { + case HtmlVersion.HTML_5: + Assert.assertTrue(outDocContents.contains("")); + Assert.assertTrue(outDocContents.contains("")); + Assert.assertTrue(outDocContents.contains("
          ")); + break; + case HtmlVersion.XHTML: + Assert.assertTrue(outDocContents.contains("")); + Assert.assertTrue(outDocContents.contains("
            ")); + Assert.assertTrue(outDocContents.contains("
          ")); + break; + } + //ExEnd + } + + @DataProvider(name = "htmlVersionsDataProvider") + public static Object[][] htmlVersionsDataProvider() { + return new Object[][] + { + {HtmlVersion.HTML_5}, + {HtmlVersion.XHTML}, + }; + } + + @Test(dataProvider = "exportXhtmlTransitionalDataProvider") + public void exportXhtmlTransitional(boolean showDoctypeDeclaration) throws Exception { + //ExStart + //ExFor:HtmlSaveOptions.ExportXhtmlTransitional + //ExFor:HtmlSaveOptions.HtmlVersion + //ExFor:HtmlVersion + //ExSummary:Shows how to display a DOCTYPE heading when converting documents to the Xhtml 1.0 transitional standard. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + + HtmlSaveOptions options = new HtmlSaveOptions(SaveFormat.HTML); + { + options.setHtmlVersion(HtmlVersion.XHTML); + options.setExportXhtmlTransitional(showDoctypeDeclaration); + options.setPrettyFormat(true); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.ExportXhtmlTransitional.html", options); + + // Our document will only contain a DOCTYPE declaration heading if we have set the "ExportXhtmlTransitional" flag to "true". + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlSaveOptions.ExportXhtmlTransitional.html"), StandardCharsets.UTF_8); + + if (showDoctypeDeclaration) + Assert.assertTrue(outDocContents.contains( + "\r\n" + + "\r\n" + + "")); + else + Assert.assertTrue(outDocContents.contains("")); + //ExEnd + } + + @DataProvider(name = "exportXhtmlTransitionalDataProvider") + public static Object[][] exportXhtmlTransitionalDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void epubHeadings() throws Exception { + //ExStart + //ExFor:HtmlSaveOptions.NavigationMapLevel + //ExSummary:Shows how to filter headings that appear in the navigation panel of a saved Epub document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Every paragraph that we format using a "Heading" style can serve as a heading. + // Each heading may also have a heading level, determined by the number of its heading style. + // The headings below are of levels 1-3. + builder.getParagraphFormat().setStyle(builder.getDocument().getStyles().get("Heading 1")); + builder.writeln("Heading #1"); + builder.getParagraphFormat().setStyle(builder.getDocument().getStyles().get("Heading 2")); + builder.writeln("Heading #2"); + builder.getParagraphFormat().setStyle(builder.getDocument().getStyles().get("Heading 3")); + builder.writeln("Heading #3"); + builder.getParagraphFormat().setStyle(builder.getDocument().getStyles().get("Heading 1")); + builder.writeln("Heading #4"); + builder.getParagraphFormat().setStyle(builder.getDocument().getStyles().get("Heading 2")); + builder.writeln("Heading #5"); + builder.getParagraphFormat().setStyle(builder.getDocument().getStyles().get("Heading 3")); + builder.writeln("Heading #6"); + + // Epub readers typically create a table of contents for their documents. + // Each paragraph with a "Heading" style in the document will create an entry in this table of contents. + // We can use the "NavigationMapLevel" property to set a maximum heading level. + // The Epub reader will not add headings with a level above the one we specify to the contents table. + HtmlSaveOptions options = new HtmlSaveOptions(SaveFormat.EPUB); + options.setNavigationMapLevel(2); + + // Our document has six headings, two of which are above level 2. + // The table of contents for this document will have four entries. + doc.save(getArtifactsDir() + "HtmlSaveOptions.EpubHeadings.epub", options); + //ExEnd + } + + @Test + public void doc2EpubSaveOptions() throws Exception { + //ExStart + //ExFor:DocumentSplitCriteria + //ExFor:HtmlSaveOptions + //ExFor:HtmlSaveOptions.#ctor + //ExFor:HtmlSaveOptions.Encoding + //ExFor:HtmlSaveOptions.DocumentSplitCriteria + //ExFor:HtmlSaveOptions.ExportDocumentProperties + //ExFor:HtmlSaveOptions.SaveFormat + //ExFor:SaveOptions + //ExFor:SaveOptions.SaveFormat + //ExSummary:Shows how to use a specific encoding when saving a document to .epub. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // Use a SaveOptions object to specify the encoding for a document that we will save. + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + saveOptions.setSaveFormat(SaveFormat.EPUB); + saveOptions.setEncoding(StandardCharsets.UTF_8); + + // By default, an output .epub document will have all of its contents in one HTML part. + // A split criterion allows us to segment the document into several HTML parts. + // We will set the criteria to split the document into heading paragraphs. + // This is useful for readers who cannot read HTML files more significant than a specific size. + saveOptions.setDocumentSplitCriteria(DocumentSplitCriteria.HEADING_PARAGRAPH); + + // Specify that we want to export document properties. + saveOptions.setExportDocumentProperties(true); + + doc.save(getArtifactsDir() + "HtmlSaveOptions.Doc2EpubSaveOptions.epub", saveOptions); + //ExEnd + } + + @Test(dataProvider = "contentIdUrlsDataProvider") + public void contentIdUrls(boolean exportCidUrlsForMhtmlResources) throws Exception { + //ExStart + //ExFor:HtmlSaveOptions.ExportCidUrlsForMhtmlResources + //ExSummary:Shows how to enable content IDs for output MHTML documents. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // Setting this flag will replace "Content-Location" tags + // with "Content-ID" tags for each resource from the input document. + HtmlSaveOptions options = new HtmlSaveOptions(SaveFormat.MHTML); + { + options.setExportCidUrlsForMhtmlResources(exportCidUrlsForMhtmlResources); + options.setCssStyleSheetType(CssStyleSheetType.EXTERNAL); + options.setExportFontResources(true); + options.setPrettyFormat(true); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.ContentIdUrls.mht", options); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlSaveOptions.ContentIdUrls.mht"), StandardCharsets.UTF_8); + + if (exportCidUrlsForMhtmlResources) { + Assert.assertTrue(outDocContents.contains("Content-ID: ")); + Assert.assertTrue(outDocContents.contains("")); + Assert.assertTrue(outDocContents.contains("@font-face { font-family:'Arial Black'; font-weight:bold; src:url('cid:arib=\r\nlk.ttf') }")); + Assert.assertTrue(outDocContents.contains("3D\"\"")); + } else { + Assert.assertTrue(outDocContents.contains("Content-Location: document.html")); + Assert.assertTrue(outDocContents.contains("")); + Assert.assertTrue(outDocContents.contains("@font-face { font-family:'Arial Black'; font-weight:bold; src:url('ariblk.t=\r\ntf') }")); + Assert.assertTrue(outDocContents.contains("3D\"\"")); + } + //ExEnd + } + + @DataProvider(name = "contentIdUrlsDataProvider") + public static Object[][] contentIdUrlsDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "dropDownFormFieldDataProvider") + public void dropDownFormField(boolean exportDropDownFormFieldAsText) throws Exception { + //ExStart + //ExFor:HtmlSaveOptions.ExportDropDownFormFieldAsText + //ExSummary:Shows how to get drop-down combo box form fields to blend in with paragraph text when saving to html. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Use a document builder to insert a combo box with the value "Two" selected. + builder.insertComboBox("MyComboBox", new String[]{"One", "Two", "Three"}, 1); + + // The "ExportDropDownFormFieldAsText" flag of this SaveOptions object allows us to + // control how saving the document to HTML treats drop-down combo boxes. + // Setting it to "true" will convert each combo box into simple text + // that displays the combo box's currently selected value, effectively freezing it. + // Setting it to "false" will preserve the functionality of the combo box using " + + "" + + "" + + "" + + "")); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "dropDownFormFieldDataProvider") + public static Object[][] dropDownFormFieldDataProvider() throws Exception { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "exportImagesAsBase64DataProvider") + public void exportImagesAsBase64(boolean exportImagesAsBase64) throws Exception { + //ExStart + //ExFor:HtmlSaveOptions.ExportFontsAsBase64 + //ExFor:HtmlSaveOptions.ExportImagesAsBase64 + //ExSummary:Shows how to save a .html document with images embedded inside it. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlSaveOptions options = new HtmlSaveOptions(); + { + options.setExportImagesAsBase64(exportImagesAsBase64); + options.setPrettyFormat(true); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.ExportImagesAsBase64.html", options); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlSaveOptions.ExportImagesAsBase64.html"), StandardCharsets.UTF_8); + + Assert.assertTrue(exportImagesAsBase64 + ? outDocContents.contains(" tags. + // If we set the "ExportLanguageInformation" flag to "false', + // the text in the output HTML document will not contain any locale information. + HtmlSaveOptions options = new HtmlSaveOptions(); + { + options.setExportLanguageInformation(exportLanguageInformation); + options.setPrettyFormat(true); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.ExportLanguageInformation.html", options); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlSaveOptions.ExportLanguageInformation.html"), StandardCharsets.UTF_8); + + if (exportLanguageInformation) { + Assert.assertTrue(outDocContents.contains("Hello world!")); + Assert.assertTrue(outDocContents.contains("Hello again!")); + Assert.assertTrue(outDocContents.contains("Привет, мир!")); + } else { + Assert.assertTrue(outDocContents.contains("Hello world!")); + Assert.assertTrue(outDocContents.contains("Hello again!")); + Assert.assertTrue(outDocContents.contains("Привет, мир!")); + } + //ExEnd + } + + @DataProvider(name = "exportLanguageInformationDataProvider") + public static Object[][] exportLanguageInformationDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "listDataProvider") + public void list(int exportListLabels) throws Exception { + //ExStart + //ExFor:ExportListLabels + //ExFor:HtmlSaveOptions.ExportListLabels + //ExSummary:Shows how to configure list exporting to HTML. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + List list = doc.getLists().add(ListTemplate.NUMBER_DEFAULT); + builder.getListFormat().setList(list); + + builder.writeln("Default numbered list item 1."); + builder.writeln("Default numbered list item 2."); + builder.getListFormat().listIndent(); + builder.writeln("Default numbered list item 3."); + builder.getListFormat().removeNumbers(); + + list = doc.getLists().add(ListTemplate.OUTLINE_HEADINGS_LEGAL); + builder.getListFormat().setList(list); + + builder.writeln("Outline legal heading list item 1."); + builder.writeln("Outline legal heading list item 2."); + builder.getListFormat().listIndent(); + builder.writeln("Outline legal heading list item 3."); + builder.getListFormat().listIndent(); + builder.writeln("Outline legal heading list item 4."); + builder.getListFormat().listIndent(); + builder.writeln("Outline legal heading list item 5."); + builder.getListFormat().removeNumbers(); + + // When saving the document to HTML, we can pass a SaveOptions object + // to decide which HTML elements the document will use to represent lists. + // Setting the "ExportListLabels" property to "ExportListLabels.AsInlineText" + // will create lists by formatting spans. + // Setting the "ExportListLabels" property to "ExportListLabels.Auto" will use the

          tag + // to build lists in cases when using the

            and
          1. tags may cause loss of formatting. + // Setting the "ExportListLabels" property to "ExportListLabels.ByHtmlTags" + // will use
              and
            1. tags to build all lists. + HtmlSaveOptions options = new HtmlSaveOptions(); + { + options.setExportListLabels(exportListLabels); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.List.html", options); + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlSaveOptions.List.html"), StandardCharsets.UTF_8); + + switch (exportListLabels) { + case ExportListLabels.AS_INLINE_TEXT: + Assert.assertTrue(outDocContents.contains( + "

              " + + "" + + "a." + + "       " + + "" + + "Default numbered list item 3." + + "

              ")); + + Assert.assertTrue(outDocContents.contains( + "

              " + + "" + + "2.1.1.1" + + "       " + + "" + + "Outline legal heading list item 5." + + "

              ")); + break; + case ExportListLabels.AUTO: + Assert.assertTrue(outDocContents.contains( + "
                " + + "
              1. " + + "Default numbered list item 3." + + "
              2. " + + "
              ")); + + break; + case ExportListLabels.BY_HTML_TAGS: + Assert.assertTrue(outDocContents.contains( + "
                " + + "
              1. " + + "Default numbered list item 3." + + "
              2. " + + "
              ")); + + break; + } + //ExEnd + } + + @DataProvider(name = "listDataProvider") + public static Object[][] listDataProvider() { + return new Object[][] + { + {ExportListLabels.AS_INLINE_TEXT}, + {ExportListLabels.AUTO}, + {ExportListLabels.BY_HTML_TAGS}, + }; + } + + @Test(dataProvider = "exportPageMarginsDataProvider") + public void exportPageMargins(boolean exportPageMargins) throws Exception { + //ExStart + //ExFor:HtmlSaveOptions.ExportPageMargins + //ExSummary:Shows how to show out-of-bounds objects in output HTML documents. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Use a builder to insert a shape with no wrapping. + Shape shape = builder.insertShape(ShapeType.CUBE, 200.0, 200.0); + + shape.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE); + shape.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE); + shape.setWrapType(WrapType.NONE); + + // Negative shape position values may place the shape outside of page boundaries. + // If we export this to HTML, the shape will appear truncated. + shape.setLeft(-150); + + // When saving the document to HTML, we can pass a SaveOptions object + // to decide whether to adjust the page to display out-of-bounds objects fully. + // If we set the "ExportPageMargins" flag to "true", the shape will be fully visible in the output HTML. + // If we set the "ExportPageMargins" flag to "false", + // our document will display the shape truncated as we would see it in Microsoft Word. + HtmlSaveOptions options = new HtmlSaveOptions(); + { + options.setExportPageMargins(exportPageMargins); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.ExportPageMargins.html", options); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlSaveOptions.ExportPageMargins.html"), StandardCharsets.UTF_8); + + if (exportPageMargins) + { + Assert.assertTrue(outDocContents.contains("")); + Assert.assertTrue(outDocContents.contains("

              ")); + } + else + { + Assert.assertFalse(outDocContents.contains("style type=\"text/css\">")); + Assert.assertTrue(outDocContents.contains("

              ")); + } + //ExEnd + } + + @DataProvider(name = "exportPageMarginsDataProvider") + public static Object[][] exportPageMarginsDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "exportPageSetupDataProvider") + public void exportPageSetup(boolean exportPageSetup) throws Exception { + //ExStart + //ExFor:HtmlSaveOptions.ExportPageSetup + //ExSummary:Shows how decide whether to preserve section structure/page setup information when saving to HTML. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Section 1"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.write("Section 2"); + + PageSetup pageSetup = doc.getSections().get(0).getPageSetup(); + pageSetup.setTopMargin(36.0); + pageSetup.setBottomMargin(36.0); + pageSetup.setPaperSize(PaperSize.A5); + + // When saving the document to HTML, we can pass a SaveOptions object + // to decide whether to preserve or discard page setup settings. + // If we set the "ExportPageSetup" flag to "true", the output HTML document will contain our page setup configuration. + // If we set the "ExportPageSetup" flag to "false", the save operation will discard our page setup settings + // for the first section, and both sections will look identical. + HtmlSaveOptions options = new HtmlSaveOptions(); + { + options.setExportPageSetup(exportPageSetup); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.ExportPageSetup.html", options); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlSaveOptions.ExportPageSetup.html"), StandardCharsets.UTF_8); + + if (exportPageSetup) { + Assert.assertTrue(outDocContents.contains( + "")); + + Assert.assertTrue(outDocContents.contains( + "

              " + + "

              " + + "Section 1" + + "

              " + + "
              ")); + } else { + Assert.assertFalse(outDocContents.contains("style type=\"text/css\">")); + + Assert.assertTrue(outDocContents.contains( + "
              " + + "

              " + + "Section 1" + + "

              " + + "
              ")); + } + //ExEnd + } + + @DataProvider(name = "exportPageSetupDataProvider") + public static Object[][] exportPageSetupDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "relativeFontSizeDataProvider") + public void relativeFontSize(boolean exportRelativeFontSize) throws Exception { + //ExStart + //ExFor:HtmlSaveOptions.ExportRelativeFontSize + //ExSummary:Shows how to use relative font sizes when saving to .html. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Default font size, "); + builder.getFont().setSize(24.0); + builder.writeln("2x default font size,"); + builder.getFont().setSize(96.0); + builder.write("8x default font size"); + + // When we save the document to HTML, we can pass a SaveOptions object + // to determine whether to use relative or absolute font sizes. + // Set the "ExportRelativeFontSize" flag to "true" to declare font sizes + // using the "em" measurement unit, which is a factor that multiplies the current font size. + // Set the "ExportRelativeFontSize" flag to "false" to declare font sizes + // using the "pt" measurement unit, which is the font's absolute size in points. + HtmlSaveOptions options = new HtmlSaveOptions(); + { + options.setExportRelativeFontSize(exportRelativeFontSize); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.RelativeFontSize.html", options); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlSaveOptions.RelativeFontSize.html"), StandardCharsets.UTF_8); + + if (exportRelativeFontSize) { + Assert.assertTrue(outDocContents.contains( + "" + + "
              " + + "

              " + + "Default font size, " + + "

              " + + "

              " + + "2x default font size," + + "

              " + + "

              " + + "8x default font size" + + "

              " + + "
              " + + "")); + } else { + Assert.assertTrue(outDocContents.contains( + "" + + "
              " + + "

              " + + "Default font size, " + + "

              " + + "

              " + + "2x default font size," + + "

              " + + "

              " + + "8x default font size" + + "

              " + + "
              " + + "")); + } + //ExEnd + } + + @DataProvider(name = "relativeFontSizeDataProvider") + public static Object[][] relativeFontSizeDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "exportShapesDataProvider") + public void exportShapes(boolean exportShapesAsSvg) throws Exception { + //ExStart + //ExFor:HtmlSaveOptions.ExportShapesAsSvg + //ExSummary:Shows how to export shape as scalable vector graphics. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape textBox = builder.insertShape(ShapeType.TEXT_BOX, 100.0, 60.0); + builder.moveTo(textBox.getFirstParagraph()); + builder.write("My text box"); + + // When we save the document to HTML, we can pass a SaveOptions object + // to determine how the saving operation will export text box shapes. + // If we set the "ExportTextBoxAsSvg" flag to "true", + // the save operation will convert shapes with text into SVG objects. + // If we set the "ExportTextBoxAsSvg" flag to "false", + // the save operation will convert shapes with text into images. + HtmlSaveOptions options = new HtmlSaveOptions(); + { + options.setExportShapesAsSvg(exportShapesAsSvg); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.ExportTextBox.html", options); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlSaveOptions.ExportTextBox.html"), StandardCharsets.UTF_8); + + if (exportShapesAsSvg) { + Assert.assertTrue(outDocContents.contains( + "" + + "")); + } else { + Assert.assertTrue(outDocContents.contains( + "

              " + + "\"\"" + + "

              ")); + } + //ExEnd + } + + @DataProvider(name = "exportShapesDataProvider") + public static Object[][] exportShapesDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "roundTripInformationDataProvider") + public void roundTripInformation(boolean exportRoundtripInformation) throws Exception { + //ExStart + //ExFor:HtmlSaveOptions.ExportRoundtripInformation + //ExSummary:Shows how to preserve hidden elements when converting to .html. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // When converting a document to .html, some elements such as hidden bookmarks, original shape positions, + // or footnotes will be either removed or converted to plain text and effectively be lost. + // Saving with a HtmlSaveOptions object with ExportRoundtripInformation set to true will preserve these elements. + + // When we save the document to HTML, we can pass a SaveOptions object to determine + // how the saving operation will export document elements that HTML does not support or use, + // such as hidden bookmarks and original shape positions. + // If we set the "ExportRoundtripInformation" flag to "true", the save operation will preserve these elements. + // If we set the "ExportRoundTripInformation" flag to "false", the save operation will discard these elements. + // We will want to preserve such elements if we intend to load the saved HTML using Aspose.Words, + // as they could be of use once again. + HtmlSaveOptions options = new HtmlSaveOptions(); + { + options.setExportRoundtripInformation(exportRoundtripInformation); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.RoundTripInformation.html", options); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlSaveOptions.RoundTripInformation.html"), StandardCharsets.UTF_8); + doc = new Document(getArtifactsDir() + "HtmlSaveOptions.RoundTripInformation.html"); + + if (exportRoundtripInformation) { + Assert.assertTrue(outDocContents.contains("
              ")); + Assert.assertTrue(outDocContents.contains(" ")); + + Assert.assertTrue(outDocContents.contains( + "td colspan=\"2\" style=\"width:210.6pt; border-style:solid; border-width:0.75pt 6pt 0.75pt 0.75pt; " + + "padding-right:2.4pt; padding-left:5.03pt; vertical-align:top; " + + "-aw-border-bottom:0.5pt single; -aw-border-left:0.5pt single; -aw-border-top:0.5pt single\">")); + + Assert.assertTrue(outDocContents.contains( + "
            2. ")); + + Assert.assertTrue(outDocContents.contains( + "\"\"")); + + + Assert.assertTrue(outDocContents.contains( + "Page number " + + "" + + "" + + "" + + "1" + + "")); + + Assert.assertEquals(1, IterableUtils.countMatches(doc.getRange().getFields(), f -> f.getType() == FieldType.FIELD_PAGE)); + } else { + Assert.assertTrue(outDocContents.contains("
              ")); + Assert.assertTrue(outDocContents.contains(" ")); + + Assert.assertTrue(outDocContents.contains( + "
          ")); + + Assert.assertTrue(outDocContents.contains( + "
        1. ")); + + Assert.assertTrue(outDocContents.contains( + "\"\"")); + + Assert.assertTrue(outDocContents.contains( + "Page number 1")); + + Assert.assertEquals(0, IterableUtils.countMatches(doc.getRange().getFields(), f -> f.getType() == FieldType.FIELD_PAGE)); + } + //ExEnd + } + + @DataProvider(name = "roundTripInformationDataProvider") + public static Object[][] roundTripInformationDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "exportTocPageNumbersDataProvider") + public void exportTocPageNumbers(boolean exportTocPageNumbers) throws Exception { + //ExStart + //ExFor:HtmlSaveOptions.ExportTocPageNumbers + //ExSummary:Shows how to display page numbers when saving a document with a table of contents to .html. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a table of contents, and then populate the document with paragraphs formatted using a "Heading" + // style that the table of contents will pick up as entries. Each entry will display the heading paragraph on the left, + // and the page number that contains the heading on the right. + FieldToc fieldToc = (FieldToc) builder.insertField(FieldType.FIELD_TOC, true); + + builder.getParagraphFormat().setStyle(builder.getDocument().getStyles().get("Heading 1")); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Entry 1"); + builder.writeln("Entry 2"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Entry 3"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Entry 4"); + fieldToc.updatePageNumbers(); + doc.updateFields(); + + // HTML documents do not have pages. If we save this document to HTML, + // the page numbers that our TOC displays will have no meaning. + // When we save the document to HTML, we can pass a SaveOptions object to omit these page numbers from the TOC. + // If we set the "ExportTocPageNumbers" flag to "true", + // each TOC entry will display the heading, separator, and page number, preserving its appearance in Microsoft Word. + // If we set the "ExportTocPageNumbers" flag to "false", + // the save operation will omit both the separator and page number and leave the heading for each entry intact. + HtmlSaveOptions options = new HtmlSaveOptions(); + { + options.setExportTocPageNumbers(exportTocPageNumbers); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.ExportTocPageNumbers.html", options); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlSaveOptions.ExportTocPageNumbers.html"), StandardCharsets.UTF_8); + + if (exportTocPageNumbers) { + Assert.assertTrue(outDocContents.contains( + "Entry 1" + + "......................................................................" + + "2" + + "

          ")); + } else { + Assert.assertTrue(outDocContents.contains( + "

          " + + "Entry 2" + + "

          ")); + } + //ExEnd + } + + @DataProvider(name = "exportTocPageNumbersDataProvider") + public static Object[][] exportTocPageNumbersDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "fontSubsettingDataProvider") + public void fontSubsetting(int fontResourcesSubsettingSizeThreshold) throws Exception { + //ExStart + //ExFor:HtmlSaveOptions.FontResourcesSubsettingSizeThreshold + //ExSummary:Shows how to work with font subsetting. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Arial"); + builder.writeln("Hello world!"); + builder.getFont().setName("Times New Roman"); + builder.writeln("Hello world!"); + builder.getFont().setName("Courier New"); + builder.writeln("Hello world!"); + + // When we save the document to HTML, we can pass a SaveOptions object configure font subsetting. + // Suppose we set the "ExportFontResources" flag to "true" and also name a folder in the "FontsFolder" property. + // In that case, the saving operation will create that folder and place a .ttf file inside + // that folder for each font that our document uses. + // Each .ttf file will contain that font's entire glyph set, + // which may potentially result in a very large file that accompanies the document. + // When we apply subsetting to a font, its exported raw data will only contain the glyphs that the document is + // using instead of the entire glyph set. If the text in our document only uses a small fraction of a font's + // glyph set, then subsetting will significantly reduce our output documents' size. + // We can use the "FontResourcesSubsettingSizeThreshold" property to define a .ttf file size, in bytes. + // If an exported font creates a size bigger file than that, then the save operation will apply subsetting to that font. + // Setting a threshold of 0 applies subsetting to all fonts, + // and setting it to "int.MaxValue" effectively disables subsetting. + String fontsFolder = getArtifactsDir() + "HtmlSaveOptions.FontSubsetting.Fonts"; + + HtmlSaveOptions options = new HtmlSaveOptions(); + { + options.setExportFontResources(true); + options.setFontsFolder(fontsFolder); + options.setFontResourcesSubsettingSizeThreshold(fontResourcesSubsettingSizeThreshold); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.FontSubsetting.html", options); + + File[] fontFileNames = new File(fontsFolder).listFiles((d, name) -> name.endsWith(".ttf")); + + Assert.assertEquals(3, fontFileNames.length); + //ExEnd + } + + @DataProvider(name = "fontSubsettingDataProvider") + public static Object[][] fontSubsettingDataProvider() { + return new Object[][] + { + {0}, + {1000000}, + {Integer.MAX_VALUE}, + }; + } + + @Test(dataProvider = "metafileFormatDataProvider", enabled = false) + public void metafileFormat(int htmlMetafileFormat) throws Exception { + //ExStart + //ExFor:HtmlMetafileFormat + //ExFor:HtmlSaveOptions.MetafileFormat + //ExFor:HtmlLoadOptions.ConvertSvgToEmf + //ExSummary:Shows how to convert SVG objects to a different format when saving HTML documents. + String html = + "\n \n Hello world!\n \n "; + + // Use 'ConvertSvgToEmf' to turn back the legacy behavior + // where all SVG images loaded from an HTML document were converted to EMF. + // Now SVG images are loaded without conversion + // if the MS Word version specified in load options supports SVG images natively. + HtmlLoadOptions loadOptions = new HtmlLoadOptions(); { loadOptions.setConvertSvgToEmf(true); } + + Document doc = new Document(new ByteArrayInputStream(html.getBytes())); + + // This document contains a element in the form of text. + // When we save the document to HTML, we can pass a SaveOptions object + // to determine how the saving operation handles this object. + // Setting the "MetafileFormat" property to "HtmlMetafileFormat.Png" to convert it to a PNG image. + // Setting the "MetafileFormat" property to "HtmlMetafileFormat.Svg" preserve it as a SVG object. + // Setting the "MetafileFormat" property to "HtmlMetafileFormat.EmfOrWmf" to convert it to a metafile. + HtmlSaveOptions options = new HtmlSaveOptions(); + { + options.setMetafileFormat(htmlMetafileFormat); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.MetafileFormat.html", options); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlSaveOptions.MetafileFormat.html"), StandardCharsets.UTF_8); + + switch (htmlMetafileFormat) { + case HtmlMetafileFormat.PNG: + Assert.assertTrue(outDocContents.contains( + "

          " + + "\"\"" + + "

          ")); + break; + case HtmlMetafileFormat.SVG: + Assert.assertTrue(outDocContents.contains( + "" + + "")); + break; + case HtmlMetafileFormat.EMF_OR_WMF: + Assert.assertTrue(outDocContents.contains( + "

          " + + "\"\"" + + "

          ")); + break; + } + //ExEnd + } + + @DataProvider(name = "metafileFormatDataProvider") + public static Object[][] metafileFormatDataProvider() { + return new Object[][] + { + {HtmlMetafileFormat.PNG}, + {HtmlMetafileFormat.SVG}, + {HtmlMetafileFormat.EMF_OR_WMF}, + }; + } + + @Test(dataProvider = "officeMathOutputModeDataProvider") + public void officeMathOutputMode(/*HtmlOfficeMathOutputMode*/int htmlOfficeMathOutputMode) throws Exception { + //ExStart + //ExFor:HtmlOfficeMathOutputMode + //ExFor:HtmlSaveOptions.OfficeMathOutputMode + //ExSummary:Shows how to specify how to export Microsoft OfficeMath objects to HTML. + Document doc = new Document(getMyDir() + "Office math.docx"); + + // When we save the document to HTML, we can pass a SaveOptions object + // to determine how the saving operation handles OfficeMath objects. + // Setting the "OfficeMathOutputMode" property to "HtmlOfficeMathOutputMode.Image" + // will render each OfficeMath object into an image. + // Setting the "OfficeMathOutputMode" property to "HtmlOfficeMathOutputMode.MathML" + // will convert each OfficeMath object into MathML. + // Setting the "OfficeMathOutputMode" property to "HtmlOfficeMathOutputMode.Text" + // will represent each OfficeMath formula using plain HTML text. + HtmlSaveOptions options = new HtmlSaveOptions(); + { + options.setOfficeMathOutputMode(htmlOfficeMathOutputMode); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.OfficeMathOutputMode.html", options); + //ExEnd + } + + @DataProvider(name = "officeMathOutputModeDataProvider") + public static Object[][] officeMathOutputModeDataProvider() { + return new Object[][] + { + {HtmlOfficeMathOutputMode.IMAGE}, + {HtmlOfficeMathOutputMode.MATH_ML}, + {HtmlOfficeMathOutputMode.TEXT}, + }; + } + + @Test(dataProvider = "scaleImageToShapeSizeDataProvider") + public void scaleImageToShapeSize(boolean scaleImageToShapeSize) throws Exception { + //ExStart + //ExFor:HtmlSaveOptions.ScaleImageToShapeSize + //ExSummary:Shows how to disable the scaling of images to their parent shape dimensions when saving to .html. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a shape which contains an image, and then make that shape considerably smaller than the image. + Shape imageShape = builder.insertImage(getImageDir() + "Transparent background logo.png"); + imageShape.setWidth(50.0); + imageShape.setHeight(50.0); + + // Saving a document that contains shapes with images to HTML will create an image file in the local file system + // for each such shape. The output HTML document will use tags to link to and display these images. + // When we save the document to HTML, we can pass a SaveOptions object to determine + // whether to scale all images that are inside shapes to the sizes of their shapes. + // Setting the "ScaleImageToShapeSize" flag to "true" will shrink every image + // to the size of the shape that contains it, so that no saved images will be larger than the document requires them to be. + // Setting the "ScaleImageToShapeSize" flag to "false" will preserve these images' original sizes, + // which will take up more space in exchange for preserving image quality. + HtmlSaveOptions options = new HtmlSaveOptions(); + { + options.setScaleImageToShapeSize(scaleImageToShapeSize); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.ScaleImageToShapeSize.html", options); + //ExEnd + + long testedImageLength = new File(getArtifactsDir() + "HtmlSaveOptions.ScaleImageToShapeSize.001.png").length(); + if (scaleImageToShapeSize) + Assert.assertTrue(testedImageLength < 6000); + else + Assert.assertTrue(testedImageLength < 16000); + } + + @DataProvider(name = "scaleImageToShapeSizeDataProvider") + public static Object[][] scaleImageToShapeSizeDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void imageFolder() throws Exception { + //ExStart + //ExFor:HtmlSaveOptions + //ExFor:HtmlSaveOptions.ExportTextInputFormFieldAsText + //ExFor:HtmlSaveOptions.ImagesFolder + //ExSummary:Shows how to specify the folder for storing linked images after saving to .html. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + File imagesDir = new File(getArtifactsDir() + "SaveHtmlWithOptions"); + + if (imagesDir.exists()) + imagesDir.delete(); + + imagesDir.mkdir(); + + // Set an option to export form fields as plain text instead of HTML input elements. + HtmlSaveOptions options = new HtmlSaveOptions(SaveFormat.HTML); + options.setExportTextInputFormFieldAsText(true); + options.setImagesFolder(imagesDir.getPath()); + + doc.save(getArtifactsDir() + "HtmlSaveOptions.SaveHtmlWithOptions.html", options); + //ExEnd + + Assert.assertTrue(new File(getArtifactsDir() + "HtmlSaveOptions.SaveHtmlWithOptions.html").exists()); + Assert.assertEquals(9, imagesDir.list().length); + + imagesDir.delete(); + } + + //ExStart + //ExFor:ImageSavingArgs.CurrentShape + //ExFor:ImageSavingArgs.Document + //ExFor:ImageSavingArgs.ImageStream + //ExFor:ImageSavingArgs.IsImageAvailable + //ExFor:ImageSavingArgs.KeepImageStreamOpen + //ExSummary:Shows how to involve an image saving callback in an HTML conversion process. + @Test //ExSkip + public void imageSavingCallback() throws Exception { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // When we save the document to HTML, we can pass a SaveOptions object to designate a callback + // to customize the image saving process. + HtmlSaveOptions options = new HtmlSaveOptions(); + options.setImageSavingCallback(new ImageShapePrinter()); + + doc.save(getArtifactsDir() + "HtmlSaveOptions.ImageSavingCallback.html", options); + } + + /// + /// Prints the properties of each image as the saving process saves it to an image file in the local file system + /// during the exporting of a document to HTML. + /// + private static class ImageShapePrinter implements IImageSavingCallback { + public void imageSaving(ImageSavingArgs args) throws Exception { + args.setKeepImageStreamOpen(false); + Assert.assertTrue(args.isImageAvailable()); + + String[] splitOriginalFileName = args.getDocument().getOriginalFileName().split("\\\\"); + System.out.println(MessageFormat.format("{0} Image #{1}", splitOriginalFileName[splitOriginalFileName.length - 1], ++mImageCount)); + + LayoutCollector layoutCollector = new LayoutCollector(args.getDocument()); + + System.out.println(MessageFormat.format("\tOn page:\t{0}", layoutCollector.getStartPageIndex(args.getCurrentShape()))); + System.out.println(MessageFormat.format("\tDimensions:\t{0}", args.getCurrentShape().getBounds().toString())); + System.out.println(MessageFormat.format("\tAlignment:\t{0}", args.getCurrentShape().getVerticalAlignment())); + System.out.println(MessageFormat.format("\tWrap type:\t{0}", args.getCurrentShape().getWrapType())); + System.out.println(MessageFormat.format("Output filename:\t{0}\n", args.getImageFileName())); + } + + private int mImageCount; + } + //ExEnd + + @Test(dataProvider = "prettyFormatDataProvider") + public void prettyFormat(boolean usePrettyFormat) throws Exception { + //ExStart + //ExFor:SaveOptions.PrettyFormat + //ExSummary:Shows how to enhance the readability of the raw code of a saved .html document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + HtmlSaveOptions htmlOptions = new HtmlSaveOptions(SaveFormat.HTML); + { + htmlOptions.setPrettyFormat(usePrettyFormat); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.PrettyFormat.html", htmlOptions); + + // Enabling pretty format makes the raw html code more readable by adding tab stop and new line characters. + String html = FileUtils.readFileToString(new File(getArtifactsDir() + "HtmlSaveOptions.PrettyFormat.html"), StandardCharsets.UTF_8); + + if (usePrettyFormat) + Assert.assertEquals( + "\r\n" + + "\t\r\n" + + "\t\t\r\n" + + "\t\t\r\n" + + MessageFormat.format("\t\t\r\n", BuildVersionInfo.getProduct(), BuildVersionInfo.getVersion()) + + "\t\t\r\n" + + "\t\t\r\n" + + "\t\r\n" + + "\t\r\n" + + "\t\t
          \r\n" + + "\t\t\t

          \r\n" + + "\t\t\t\tHello world!\r\n" + + "\t\t\t

          \r\n" + + "\t\t\t

          \r\n" + + "\t\t\t\t \r\n" + + "\t\t\t

          \r\n" + + "\t\t
          \r\n" + + "\t\r\n", + html); + else + Assert.assertEquals( + "" + + "" + + MessageFormat.format("", BuildVersionInfo.getProduct(), BuildVersionInfo.getVersion()) + + "" + + "

          Hello world!

          " + + "

           

          ", + html); + //ExEnd + } + + @DataProvider(name = "prettyFormatDataProvider") + public static Object[][] prettyFormatDataProvider() { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test (dataProvider = "progressCallbackDataProvider") + //ExStart + //ExFor:SaveOptions.ProgressCallback + //ExFor:IDocumentSavingCallback + //ExFor:IDocumentSavingCallback.Notify(DocumentSavingArgs) + //ExFor:DocumentSavingArgs.EstimatedProgress + //ExFor:DocumentSavingArgs + //ExSummary:Shows how to manage a document while saving to html. + public void progressCallback(int saveFormat, String ext) throws Exception + { + Document doc = new Document(getMyDir() + "Big document.docx"); + + // Following formats are supported: Html, Mhtml, Epub. + HtmlSaveOptions saveOptions = new HtmlSaveOptions(saveFormat); + { + saveOptions.setProgressCallback(new SavingProgressCallback()); + } + + try { + doc.save(getArtifactsDir() + MessageFormat.format("HtmlSaveOptions.ProgressCallback.{0}", ext), saveOptions); + } + catch (IllegalStateException exception) { + Assert.assertTrue(exception.getMessage().contains("EstimatedProgress")); + } + + } + + @DataProvider(name = "progressCallbackDataProvider") //ExSkip + public static Object[][] progressCallbackDataProvider() throws Exception + { + return new Object[][] + { + {SaveFormat.HTML, "html"}, + {SaveFormat.MHTML, "mhtml"}, + {SaveFormat.EPUB, "epub"}, + }; + } + + /// + /// Saving progress callback. Cancel a document saving after the "MaxDuration" seconds. + /// + public static class SavingProgressCallback implements IDocumentSavingCallback + { + /// + /// Ctr. + /// + public SavingProgressCallback() + { + mSavingStartedAt = new Date(); + } + + /// + /// Callback method which called during document saving. + /// + /// Saving arguments. + public void notify(DocumentSavingArgs args) + { + Date canceledAt = new Date(); + long diff = canceledAt.getTime() - mSavingStartedAt.getTime(); + long ellapsedSeconds = TimeUnit.MILLISECONDS.toSeconds(diff); + + if (ellapsedSeconds > MAX_DURATION) + throw new IllegalStateException(MessageFormat.format("EstimatedProgress = {0}; CanceledAt = {1}", args.getEstimatedProgress(), canceledAt)); + } + + /// + /// Date and time when document saving is started. + /// + private Date mSavingStartedAt; + + /// + /// Maximum allowed duration in sec. + /// + private static final double MAX_DURATION = 0.01d; + } + //ExEnd + + @Test (dataProvider = "mobiAzw3DefaultEncodingDataProvider") + public void mobiAzw3DefaultEncoding(int saveFormat) throws Exception + { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + saveOptions.setSaveFormat(saveFormat); + saveOptions.setEncoding(StandardCharsets.US_ASCII); + + String outputFileName = String.format("%sHtmlSaveOptions.MobiDefaultEncoding%s", getArtifactsDir(), FileFormatUtil.saveFormatToExtension(saveFormat)); + doc.save(outputFileName, saveOptions); + + Charset encoding = TestUtil.getEncoding(outputFileName); + Assert.assertNotEquals(StandardCharsets.US_ASCII, encoding); + Assert.assertEquals(StandardCharsets.UTF_8, encoding); + } + + @DataProvider(name = "mobiAzw3DefaultEncodingDataProvider") + public static Object[][] mobiAzw3DefaultEncodingDataProvider() { + return new Object[][] + { + {SaveFormat.MOBI}, + {SaveFormat.AZW_3}, + }; + } + + @Test + public void htmlReplaceBackslashWithYenSign() throws Exception + { + //ExStart:HtmlReplaceBackslashWithYenSign + //GistId:0ede368e82d1e97d02e615a76923846b + //ExFor:HtmlSaveOptions.ReplaceBackslashWithYenSign + //ExSummary:Shows how to replace backslash characters with yen signs (Html). + Document doc = new Document(getMyDir() + "Korean backslash symbol.docx"); + + // By default, Aspose.Words mimics MS Word's behavior and doesn't replace backslash characters with yen signs in + // generated HTML documents. However, previous versions of Aspose.Words performed such replacements in certain + // scenarios. This flag enables backward compatibility with previous versions of Aspose.Words. + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + saveOptions.setReplaceBackslashWithYenSign(true); + + doc.save(getArtifactsDir() + "HtmlSaveOptions.ReplaceBackslashWithYenSign.html", saveOptions); + //ExEnd:HtmlReplaceBackslashWithYenSign + } + + @Test + public void removeJavaScriptFromLinks() throws Exception + { + //ExStart:HtmlRemoveJavaScriptFromLinks + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:HtmlFixedSaveOptions.RemoveJavaScriptFromLinks + //ExSummary:Shows how to remove JavaScript from the links. + Document doc = new Document(getMyDir() + "JavaScript in HREF.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + saveOptions.setRemoveJavaScriptFromLinks(true); + + doc.save(getArtifactsDir() + "HtmlSaveOptions.RemoveJavaScriptFromLinks.html", saveOptions); + //ExEnd:HtmlRemoveJavaScriptFromLinks + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExHyphenation.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExHyphenation.java new file mode 100644 index 00000000..008588ca --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExHyphenation.java @@ -0,0 +1,149 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.pdf.TextAbsorber; +import com.aspose.words.*; +import org.apache.commons.collections4.IterableUtils; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.io.FileInputStream; +import java.io.InputStream; +import java.util.HashMap; + +public class ExHyphenation extends ApiExampleBase { + @Test + public void dictionary() throws Exception { + //ExStart + //ExFor:Hyphenation.IsDictionaryRegistered(String) + //ExFor:Hyphenation.RegisterDictionary(String, String) + //ExFor:Hyphenation.UnregisterDictionary(String) + //ExSummary:Shows how to register a hyphenation dictionary. + // A hyphenation dictionary contains a list of strings that define hyphenation rules for the dictionary's language. + // When a document contains lines of text in which a word could be split up and continued on the next line, + // hyphenation will look through the dictionary's list of strings for that word's substrings. + // If the dictionary contains a substring, then hyphenation will split the word across two lines + // by the substring and add a hyphen to the first half. + // Register a dictionary file from the local file system to the "de-CH" locale. + Hyphenation.registerDictionary("de-CH", getMyDir() + "hyph_de_CH.dic"); + + Assert.assertTrue(Hyphenation.isDictionaryRegistered("de-CH")); + + // Open a document containing text with a locale matching that of our dictionary, + // and save it to a fixed-page save format. The text in that document will be hyphenated. + Document doc = new Document(getMyDir() + "German text.docx"); + + Assert.assertTrue(IterableUtils.matchesAll(doc.getFirstSection().getBody().getFirstParagraph().getRuns(), r -> r.getFont().getLocaleId() == 2055)); + + doc.save(getArtifactsDir() + "Hyphenation.Dictionary.Registered.pdf"); + + // Re-load the document after un-registering the dictionary, + // and save it to another PDF, which will not have hyphenated text. + Hyphenation.unregisterDictionary("de-CH"); + + Assert.assertFalse(Hyphenation.isDictionaryRegistered("de-CH")); + + doc = new Document(getMyDir() + "German text.docx"); + doc.save(getArtifactsDir() + "Hyphenation.Dictionary.Unregistered.pdf"); + //ExEnd + + com.aspose.pdf.Document pdfDoc = new com.aspose.pdf.Document(getArtifactsDir() + "Hyphenation.Dictionary.Registered.pdf"); + TextAbsorber textAbsorber = new TextAbsorber(); + textAbsorber.visit(pdfDoc); + + Assert.assertTrue(textAbsorber.getText().contains("La ob storen an deinen am sachen. Dop\u00AD\r\n" + + "pelte um da am spateren verlogen ge\u00AD\r\n" + + "kommen achtzehn blaulich.")); + + pdfDoc.close(); + + pdfDoc = new com.aspose.pdf.Document(getArtifactsDir() + "Hyphenation.Dictionary.Unregistered.pdf"); + textAbsorber = new TextAbsorber(); + textAbsorber.visit(pdfDoc); + + Assert.assertTrue(textAbsorber.getText().contains("La ob storen an deinen am sachen. \r\n" + + "Doppelte um da am spateren verlogen \r\n" + + "gekommen achtzehn blaulich.")); + + pdfDoc.close(); + } + + //ExStart + //ExFor:Hyphenation + //ExFor:Hyphenation.Callback + //ExFor:Hyphenation.RegisterDictionary(String, Stream) + //ExFor:Hyphenation.RegisterDictionary(String, String) + //ExFor:Hyphenation.WarningCallback + //ExFor:IHyphenationCallback + //ExFor:IHyphenationCallback.RequestDictionary(String) + //ExSummary:Shows how to open and register a dictionary from a file. + @Test //ExSkip + public void registerDictionary() throws Exception { + // Set up a callback that tracks warnings that occur during hyphenation dictionary registration. + WarningInfoCollection warningInfoCollection = new WarningInfoCollection(); + Hyphenation.setWarningCallback(warningInfoCollection); + + // Register an English (US) hyphenation dictionary by stream. + InputStream dictionaryStream = new FileInputStream(getMyDir() + "hyph_en_US.dic"); + Hyphenation.registerDictionary("en-US", dictionaryStream); + + Assert.assertEquals(0, warningInfoCollection.getCount()); + + // Open a document with a locale that Microsoft Word may not hyphenate on an English machine, such as German. + Document doc = new Document(getMyDir() + "German text.docx"); + + // To hyphenate that document upon saving, we need a hyphenation dictionary for the "de-CH" language code. + // This callback will handle the automatic request for that dictionary. + Hyphenation.setCallback(new CustomHyphenationDictionaryRegister()); + + // When we save the document, German hyphenation will take effect. + doc.save(getArtifactsDir() + "Hyphenation.RegisterDictionary.pdf"); + + // This dictionary contains two identical patterns, which will trigger a warning. + Assert.assertEquals(warningInfoCollection.getCount(), 1); + Assert.assertEquals(warningInfoCollection.get(0).getWarningType(), WarningType.MINOR_FORMATTING_LOSS); + Assert.assertEquals(warningInfoCollection.get(0).getSource(), WarningSource.LAYOUT); + Assert.assertEquals(warningInfoCollection.get(0).getDescription(), "Hyphenation dictionary contains duplicate patterns. " + + "The only first found pattern will be used. Content can be wrapped differently."); + } + + /// + /// Associates ISO language codes with local system filenames for hyphenation dictionary files. + /// + private static class CustomHyphenationDictionaryRegister implements IHyphenationCallback { + public CustomHyphenationDictionaryRegister() { + mHyphenationDictionaryFiles = new HashMap<>(); + { + mHyphenationDictionaryFiles.put("en-US", getMyDir() + "hyph_en_US.dic"); + mHyphenationDictionaryFiles.put("de-CH", getMyDir() + "hyph_de_CH.dic"); + } + } + + public void requestDictionary(String language) throws Exception { + System.out.print("Hyphenation dictionary requested: " + language); + + if (Hyphenation.isDictionaryRegistered(language)) { + System.out.println(", is already registered."); + return; + } + + if (mHyphenationDictionaryFiles.containsKey(language)) { + Hyphenation.registerDictionary(language, mHyphenationDictionaryFiles.get(language)); + System.out.println(", successfully registered."); + return; + } + + System.out.println(", no respective dictionary file known by this Callback."); + } + + private final HashMap mHyphenationDictionaryFiles; + } + //ExEnd +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExImage.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExImage.java new file mode 100644 index 00000000..84bb2930 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExImage.java @@ -0,0 +1,467 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.apache.commons.collections4.IterableUtils; +import org.testng.Assert; +import org.testng.annotations.Test; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; + +public class ExImage extends ApiExampleBase { + @Test + public void fromFile() throws Exception { + //ExStart + //ExFor:Shape.#ctor(DocumentBase,ShapeType) + //ExFor:ShapeType + //ExSummary:Shows how to insert a shape with an image from the local file system into a document. + Document doc = new Document(); + + // The "Shape" class's public constructor will create a shape with "ShapeMarkupLanguage.Vml" markup type. + // If you need to create a shape of a non-primitive type, such as SingleCornerSnipped, TopCornersSnipped, DiagonalCornersSnipped, + // TopCornersOneRoundedOneSnipped, SingleCornerRounded, TopCornersRounded, or DiagonalCornersRounded, + // please use DocumentBuilder.InsertShape. + Shape shape = new Shape(doc, ShapeType.IMAGE); + shape.getImageData().setImage(getImageDir() + "Windows MetaFile.wmf"); + shape.setWidth(100.0); + shape.setHeight(100.0); + + doc.getFirstSection().getBody().getFirstParagraph().appendChild(shape); + + doc.save(getArtifactsDir() + "Image.FromFile.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Image.FromFile.docx"); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(1600, 1600, ImageType.WMF, shape); + Assert.assertEquals(100.0d, shape.getHeight()); + Assert.assertEquals(100.0d, shape.getWidth()); + } + + @Test + public void fromUrl() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertImage(String) + //ExSummary:Shows how to insert a shape with an image into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are two locations where the document builder's "InsertShape" method + // can source the image that the shape will display. + // 1 - Pass a local file system filename of an image file: + builder.write("Image from local file: "); + builder.insertImage(getImageDir() + "Logo.jpg"); + builder.writeln(); + + // 2 - Pass a URL which points to an image. + builder.write("Image from a URL: "); + builder.insertImage(getAsposelogoUri().toURL().openStream()); + builder.writeln(); + + doc.save(getArtifactsDir() + "Image.FromUrl.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Image.FromUrl.docx"); + NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); + + Assert.assertEquals(2, shapes.getCount()); + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, (Shape) shapes.get(0)); + TestUtil.verifyImageInShape(272, 92, ImageType.PNG, (Shape) shapes.get(1)); + } + + @Test + public void fromStream() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertImage(Stream) + //ExSummary:Shows how to insert a shape with an image from a stream into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + InputStream stream = new FileInputStream(getImageDir() + "Logo.jpg"); + try { + builder.write("Image from stream: "); + builder.insertImage(stream); + } finally { + stream.close(); + } + + doc.save(getArtifactsDir() + "Image.FromStream.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Image.FromStream.docx"); + + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, (Shape) doc.getChildNodes(NodeType.SHAPE, true).get(0)); + } + + @Test + public void createFloatingPageCenter() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertImage(String) + //ExFor:Shape + //ExFor:ShapeBase + //ExFor:ShapeBase.WrapType + //ExFor:ShapeBase.BehindText + //ExFor:ShapeBase.RelativeHorizontalPosition + //ExFor:ShapeBase.RelativeVerticalPosition + //ExFor:ShapeBase.HorizontalAlignment + //ExFor:ShapeBase.VerticalAlignment + //ExFor:WrapType + //ExFor:RelativeHorizontalPosition + //ExFor:RelativeVerticalPosition + //ExFor:HorizontalAlignment + //ExFor:VerticalAlignment + //ExSummary:Shows how to insert a floating image to the center of a page. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a floating image that will appear behind the overlapping text and align it to the page's center. + Shape shape = builder.insertImage(getImageDir() + "Logo.jpg"); + shape.setWrapType(WrapType.NONE); + shape.setBehindText(true); + shape.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE); + shape.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE); + shape.setHorizontalAlignment(HorizontalAlignment.CENTER); + shape.setVerticalAlignment(VerticalAlignment.CENTER); + + doc.save(getArtifactsDir() + "Image.CreateFloatingPageCenter.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Image.CreateFloatingPageCenter.docx"); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, shape); + Assert.assertEquals(WrapType.NONE, shape.getWrapType()); + Assert.assertTrue(shape.getBehindText()); + Assert.assertEquals(RelativeHorizontalPosition.PAGE, shape.getRelativeHorizontalPosition()); + Assert.assertEquals(RelativeVerticalPosition.PAGE, shape.getRelativeVerticalPosition()); + Assert.assertEquals(HorizontalAlignment.CENTER, shape.getHorizontalAlignment()); + Assert.assertEquals(VerticalAlignment.CENTER, shape.getVerticalAlignment()); + } + + @Test + public void createFloatingPositionSize() throws Exception { + //ExStart + //ExFor:ShapeBase.Left + //ExFor:ShapeBase.Right + //ExFor:ShapeBase.Top + //ExFor:ShapeBase.Bottom + //ExFor:ShapeBase.Width + //ExFor:ShapeBase.Height + //ExFor:DocumentBuilder.CurrentSection + //ExFor:PageSetup.PageWidth + //ExSummary:Shows how to insert a floating image, and specify its position and size. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertImage(getImageDir() + "Logo.jpg"); + shape.setWrapType(WrapType.NONE); + + // Configure the shape's "RelativeHorizontalPosition" property to treat the value of the "Left" property + // as the shape's horizontal distance, in points, from the left side of the page. + shape.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE); + + // Set the shape's horizontal distance from the left side of the page to 100. + shape.setLeft(100.0); + + // Use the "RelativeVerticalPosition" property in a similar way to position the shape 80pt below the top of the page. + shape.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE); + shape.setTop(80.0); + + // Set the shape's height, which will automatically scale the width to preserve dimensions. + shape.setHeight(125.0); + + Assert.assertEquals(125.0d, shape.getWidth()); + + // The "Bottom" and "Right" properties contain the bottom and right edges of the image. + Assert.assertEquals(shape.getTop() + shape.getHeight(), shape.getBottom()); + Assert.assertEquals(shape.getLeft() + shape.getWidth(), shape.getRight()); + + doc.save(getArtifactsDir() + "Image.CreateFloatingPositionSize.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Image.CreateFloatingPositionSize.docx"); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, shape); + Assert.assertEquals(WrapType.NONE, shape.getWrapType()); + Assert.assertEquals(RelativeHorizontalPosition.PAGE, shape.getRelativeHorizontalPosition()); + Assert.assertEquals(RelativeVerticalPosition.PAGE, shape.getRelativeVerticalPosition()); + Assert.assertEquals(100.0d, shape.getLeft()); + Assert.assertEquals(80.0d, shape.getTop()); + Assert.assertEquals(125.0d, shape.getHeight()); + Assert.assertEquals(125.0d, shape.getWidth()); + Assert.assertEquals(shape.getTop() + shape.getHeight(), shape.getBottom()); + Assert.assertEquals(shape.getLeft() + shape.getWidth(), shape.getRight()); + } + + @Test + public void insertImageWithHyperlink() throws Exception { + //ExStart + //ExFor:ShapeBase.HRef + //ExFor:ShapeBase.ScreenTip + //ExFor:ShapeBase.Target + //ExSummary:Shows how to insert a shape which contains an image, and is also a hyperlink. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertImage(getImageDir() + "Logo.jpg"); + shape.setHRef("https://forum.aspose.com/"); + shape.setTarget("New Window"); + shape.setScreenTip("Aspose.Words Support Forums"); + + // Ctrl + left-clicking the shape in Microsoft Word will open a new web browser window + // and take us to the hyperlink in the "HRef" property. + doc.save(getArtifactsDir() + "Image.InsertImageWithHyperlink.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Image.InsertImageWithHyperlink.docx"); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyWebResponseStatusCode(200, new URL(shape.getHRef())); + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, shape); + Assert.assertEquals("New Window", shape.getTarget()); + Assert.assertEquals("Aspose.Words Support Forums", shape.getScreenTip()); + } + + @Test + public void createLinkedImage() throws Exception { + //ExStart + //ExFor:Shape.ImageData + //ExFor:ImageData + //ExFor:ImageData.SourceFullName + //ExFor:ImageData.SetImage(String) + //ExFor:DocumentBuilder.InsertNode + //ExSummary:Shows how to insert a linked image into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + String imageFileName = getImageDir() + "Windows MetaFile.wmf"; + + // Below are two ways of applying an image to a shape so that it can display it. + // 1 - Set the shape to contain the image. + Shape shape = new Shape(builder.getDocument(), ShapeType.IMAGE); + shape.setWrapType(WrapType.INLINE); + shape.getImageData().setImage(imageFileName); + + builder.insertNode(shape); + + doc.save(getArtifactsDir() + "Image.CreateLinkedImage.Embedded.docx"); + + // Every image that we store in shape will increase the size of our document. + Assert.assertTrue(new File(getArtifactsDir() + "Image.CreateLinkedImage.Embedded.docx").length() > 70000); + + doc.getFirstSection().getBody().getFirstParagraph().removeAllChildren(); + + // 2 - Set the shape to link to an image file in the local file system. + shape = new Shape(builder.getDocument(), ShapeType.IMAGE); + shape.setWrapType(WrapType.INLINE); + shape.getImageData().setSourceFullName(imageFileName); + + builder.insertNode(shape); + doc.save(getArtifactsDir() + "Image.CreateLinkedImage.Linked.docx"); + + // Linking to images will save space and result in a smaller document. + // However, the document can only display the image correctly while + // the image file is present at the location that the shape's "SourceFullName" property points to. + Assert.assertTrue(new File(getArtifactsDir() + "Image.CreateLinkedImage.Linked.docx").length() < 10000); + //ExEnd + + doc = new Document(getArtifactsDir() + "Image.CreateLinkedImage.Embedded.docx"); + + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(1600, 1600, ImageType.WMF, shape); + Assert.assertEquals(WrapType.INLINE, shape.getWrapType()); + Assert.assertEquals("", shape.getImageData().getSourceFullName().replace("%20", " ")); + + doc = new Document(getArtifactsDir() + "Image.CreateLinkedImage.Linked.docx"); + + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(0, 0, ImageType.WMF, shape); + Assert.assertEquals(WrapType.INLINE, shape.getWrapType()); + Assert.assertEquals(imageFileName, shape.getImageData().getSourceFullName().replace("%20", " ")); + } + + @Test + public void deleteAllImages() throws Exception { + //ExStart + //ExFor:Shape.HasImage + //ExFor:Node.Remove + //ExSummary:Shows how to delete all shapes with images from a document. + Document doc = new Document(getMyDir() + "Images.docx"); + ArrayList shapes = (ArrayList) IterableUtils.toList(doc.getChildNodes(NodeType.SHAPE, true)); + + Assert.assertEquals(9, IterableUtils.countMatches(shapes, s -> { + try { + return s.hasImage(); + } catch (Exception e) { + e.printStackTrace(); + } + return false; + })); + + for (Shape shape : shapes) + if (shape.hasImage()) + shape.remove(); + + shapes = (ArrayList) IterableUtils.toList(doc.getChildNodes(NodeType.SHAPE, true)); + + Assert.assertEquals(0, IterableUtils.countMatches(shapes, s -> { + try { + return s.hasImage(); + } catch (Exception e) { + e.printStackTrace(); + } + return false; + })); + //ExEnd + } + + @Test + public void deleteAllImagesPreOrder() throws Exception { + //ExStart + //ExFor:Node.NextPreOrder(Node) + //ExFor:Node.PreviousPreOrder(Node) + //ExSummary:Shows how to traverse the document's node tree using the pre-order traversal algorithm, and delete any encountered shape with an image. + Document doc = new Document(getMyDir() + "Images.docx"); + ArrayList shapes = (ArrayList) IterableUtils.toList(doc.getChildNodes(NodeType.SHAPE, true)); + + Assert.assertEquals(9, IterableUtils.countMatches(shapes, s -> { + try { + return s.hasImage(); + } catch (Exception e) { + e.printStackTrace(); + } + return false; + })); + + Node curNode = doc; + while (curNode != null) { + Node nextNode = curNode.nextPreOrder(doc); + + if (curNode.previousPreOrder(doc) != null && nextNode != null) + Assert.assertEquals(curNode, nextNode.previousPreOrder(doc)); + + if (curNode.getNodeType() == NodeType.SHAPE && ((Shape) curNode).hasImage()) + curNode.remove(); + + curNode = nextNode; + } + + shapes = (ArrayList) IterableUtils.toList(doc.getChildNodes(NodeType.SHAPE, true)); + + Assert.assertEquals(0, IterableUtils.countMatches(shapes, s -> { + try { + return s.hasImage(); + } catch (Exception e) { + e.printStackTrace(); + } + return false; + })); + //ExEnd + } + + @Test + public void scaleImage() throws Exception { + //ExStart + //ExFor:ImageData.ImageSize + //ExFor:ImageSize + //ExFor:ImageSize.WidthPoints + //ExFor:ImageSize.HeightPoints + //ExFor:ShapeBase.Width + //ExFor:ShapeBase.Height + //ExSummary:Shows how to resize a shape with an image. + // When we insert an image using the "InsertImage" method, the builder scales the shape that displays the image so that, + // when we view the document using 100% zoom in Microsoft Word, the shape displays the image in its actual size. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + Shape shape = builder.insertImage(getImageDir() + "Logo.jpg"); + + // A 400x400 image will create an ImageData object with an image size of 300x300pt. + ImageSize imageSize = shape.getImageData().getImageSize(); + + Assert.assertEquals(300.0d, imageSize.getWidthPoints()); + Assert.assertEquals(300.0d, imageSize.getHeightPoints()); + + // If a shape's dimensions match the image data's dimensions, + // then the shape is displaying the image in its original size. + Assert.assertEquals(300.0d, shape.getWidth()); + Assert.assertEquals(300.0d, shape.getHeight()); + + // Reduce the overall size of the shape by 50%. + shape.setWidth(shape.getWidth() * 0.5); + + // Scaling factors apply to both the width and the height at the same time to preserve the shape's proportions. + Assert.assertEquals(150.0d, shape.getWidth()); + Assert.assertEquals(150.0d, shape.getHeight()); + + // When we resize the shape, the size of the image data remains the same. + Assert.assertEquals(300.0d, imageSize.getWidthPoints()); + Assert.assertEquals(300.0d, imageSize.getHeightPoints()); + + // We can reference the image data dimensions to apply a scaling based on the size of the image. + shape.setWidth(imageSize.getWidthPoints() * 1.1); + + Assert.assertEquals(330.0d, shape.getWidth()); + Assert.assertEquals(330.0d, shape.getHeight()); + + doc.save(getArtifactsDir() + "Image.ScaleImage.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Image.ScaleImage.docx"); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(330.0d, shape.getWidth()); + Assert.assertEquals(330.0d, shape.getHeight()); + + imageSize = shape.getImageData().getImageSize(); + + Assert.assertEquals(300.0d, imageSize.getWidthPoints()); + Assert.assertEquals(300.0d, imageSize.getHeightPoints()); + } + + @Test + public void insertWebpImage() throws Exception + { + //ExStart:InsertWebpImage + //GistId:e386727403c2341ce4018bca370a5b41 + //ExFor:DocumentBuilder.InsertImage(String) + //ExSummary:Shows how to insert WebP image. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertImage(getImageDir() + "WebP image.webp"); + + doc.save(getArtifactsDir() + "Image.InsertWebpImage.docx"); + //ExEnd:InsertWebpImage + } + + @Test + public void readWebpImage() throws Exception + { + //ExStart:ReadWebpImage + //GistId:e386727403c2341ce4018bca370a5b41 + //ExFor:ImageType + //ExSummary:Shows how to read WebP image. + Document doc = new Document(getMyDir() + "Document with WebP image.docx"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + Assert.assertEquals(ImageType.WEB_P, shape.getImageData().getImageType()); + //ExEnd:ReadWebpImage + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExImageSaveOptions.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExImageSaveOptions.java new file mode 100644 index 00000000..b23bbc43 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExImageSaveOptions.java @@ -0,0 +1,665 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import com.aspose.words.Shape; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.text.MessageFormat; + +public class ExImageSaveOptions extends ApiExampleBase { + @Test + public void onePage() throws Exception { + //ExStart + //ExFor:Document.Save(String, SaveOptions) + //ExFor:FixedPageSaveOptions + //ExFor:ImageSaveOptions.PageSet + //ExFor:PageSet + //ExFor:PageSet.#ctor(Int32) + //ExSummary:Shows how to render one page from a document to a JPEG image. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Page 1."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 2."); + builder.insertImage(getImageDir() + "Logo.jpg"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 3."); + + // Create an "ImageSaveOptions" object which we can pass to the document's "Save" method + // to modify the way in which that method renders the document into an image. + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.JPEG); + // Set the "PageSet" to "1" to select the second page via + // the zero-based index to start rendering the document from. + options.setPageSet(new PageSet(1)); + + // When we save the document to the JPEG format, Aspose.Words only renders one page. + // This image will contain one page starting from page two, + // which will just be the second page of the original document. + doc.save(getArtifactsDir() + "ImageSaveOptions.OnePage.jpg", options); + //ExEnd + + TestUtil.verifyImage(816, 1056, getArtifactsDir() + "ImageSaveOptions.OnePage.jpg"); + } + + @Test(dataProvider = "rendererDataProvider") + public void renderer(boolean useGdiEmfRenderer) throws Exception { + //ExStart + //ExFor:ImageSaveOptions.UseGdiEmfRenderer + //ExSummary:Shows how to choose a renderer when converting a document to .emf. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 1")); + builder.writeln("Hello world!"); + builder.insertImage(getImageDir() + "Logo.jpg"); + + // When we save the document as an EMF image, we can pass a SaveOptions object to select a renderer for the image. + // If we set the "UseGdiEmfRenderer" flag to "true", Aspose.Words will use the GDI+ renderer. + // If we set the "UseGdiEmfRenderer" flag to "false", Aspose.Words will use its own metafile renderer. + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.EMF); + saveOptions.setUseGdiEmfRenderer(useGdiEmfRenderer); + + doc.save(getArtifactsDir() + "ImageSaveOptions.Renderer.emf", saveOptions); + + // The GDI+ renderer usually creates larger files. + if (useGdiEmfRenderer) + Assert.assertTrue(new File(getArtifactsDir() + "ImageSaveOptions.Renderer.emf").length() < 300000); + else + Assert.assertTrue(new File(getArtifactsDir() + "ImageSaveOptions.Renderer.emf").length() <= 30000); + //ExEnd + } + + @DataProvider(name = "rendererDataProvider") + public static Object[][] rendererDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void pageSet() throws Exception { + //ExStart + //ExFor:ImageSaveOptions.PageSet + //ExSummary:Shows how to specify which page in a document to render as an image. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 1")); + builder.writeln("Hello world! This is page 1."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("This is page 2."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("This is page 3."); + + Assert.assertEquals(3, doc.getPageCount()); + + // When we save the document as an image, Aspose.Words only renders the first page by default. + // We can pass a SaveOptions object to specify a different page to render. + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.GIF); + + // Render every page of the document to a separate image file. + for (int i = 1; i <= doc.getPageCount(); i++) { + saveOptions.setPageSet(new PageSet(1)); + + doc.save(getArtifactsDir() + MessageFormat.format("ImageSaveOptions.PageIndex.Page {0}.gif", i), saveOptions); + } + //ExEnd + + TestUtil.verifyImage(816, 1056, getArtifactsDir() + "ImageSaveOptions.PageIndex.Page 1.gif"); + TestUtil.verifyImage(816, 1056, getArtifactsDir() + "ImageSaveOptions.PageIndex.Page 2.gif"); + TestUtil.verifyImage(816, 1056, getArtifactsDir() + "ImageSaveOptions.PageIndex.Page 3.gif"); + Assert.assertFalse(new File(getArtifactsDir() + "ImageSaveOptions.PageIndex.Page 4.gif").exists()); + } + + @Test + public void graphicsQuality() throws Exception { + //ExStart + //ExFor:GraphicsQualityOptions + //ExFor:GraphicsQualityOptions.CompositingMode + //ExFor:GraphicsQualityOptions.CompositingQuality + //ExFor:GraphicsQualityOptions.InterpolationMode + //ExFor:GraphicsQualityOptions.StringFormat + //ExFor:GraphicsQualityOptions.SmoothingMode + //ExFor:GraphicsQualityOptions.TextRenderingHint + //ExFor:ImageSaveOptions.GraphicsQualityOptions + //ExSummary:Shows how to set render quality options while converting documents to image formats. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + GraphicsQualityOptions qualityOptions = new GraphicsQualityOptions(); + qualityOptions.getRenderingHints().put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // SmoothingMode + qualityOptions.getRenderingHints().put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); // TextRenderingHint + qualityOptions.getRenderingHints().put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); // CompositingMode + qualityOptions.getRenderingHints().put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); // CompositingQuality + qualityOptions.getRenderingHints().put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); // InterpolationMode + qualityOptions.getRenderingHints().put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); // StringFormat + + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.JPEG); + saveOptions.setGraphicsQualityOptions(qualityOptions); + + doc.save(getArtifactsDir() + "ImageSaveOptions.GraphicsQuality.jpg", saveOptions); + //ExEnd + + TestUtil.verifyImage(794, 1122, getArtifactsDir() + "ImageSaveOptions.GraphicsQuality.jpg"); + } + + @Test + public void useTileFlipMode() throws Exception + { + //ExStart + //ExFor:GraphicsQualityOptions.UseTileFlipMode + //ExSummary:Shows how to prevent the white line appears when rendering with a high resolution. + Document doc = new Document(getMyDir() + "Shape high dpi.docx"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + ShapeRenderer renderer = shape.getShapeRenderer(); + + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.PNG); + { + saveOptions.setResolution(500f); saveOptions.setGraphicsQualityOptions(new GraphicsQualityOptions()); { saveOptions.getGraphicsQualityOptions().setUseTileFlipMode(true); } + } + renderer.save(getArtifactsDir() + "ImageSaveOptions.UseTileFlipMode.png", saveOptions); + //ExEnd + } + + @Test(dataProvider = "windowsMetaFileDataProvider") + public void windowsMetaFile(int metafileRenderingMode) throws Exception { + //ExStart + //ExFor:ImageSaveOptions.MetafileRenderingOptions + //ExFor:MetafileRenderingOptions.UseGdiRasterOperationsEmulation + //ExSummary:Shows how to set the rendering mode when saving documents with Windows Metafile images to other image formats. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertImage(getImageDir() + "Windows MetaFile.wmf"); + + // When we save the document as an image, we can pass a SaveOptions object to + // determine how the saving operation will process Windows Metafiles in the document. + // If we set the "RenderingMode" property to "MetafileRenderingMode.Vector", + // or "MetafileRenderingMode.VectorWithFallback", we will render all metafiles as vector graphics. + // If we set the "RenderingMode" property to "MetafileRenderingMode.Bitmap", we will render all metafiles as bitmaps. + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.PNG); + options.getMetafileRenderingOptions().setRenderingMode(metafileRenderingMode); + // Aspose.Words uses GDI+ for raster operations emulation, when value is set to true. + options.getMetafileRenderingOptions().setUseGdiRasterOperationsEmulation(true); + + doc.save(getArtifactsDir() + "ImageSaveOptions.WindowsMetaFile.png", options); + //ExEnd + + TestUtil.verifyImage(816, 1056, getArtifactsDir() + "ImageSaveOptions.WindowsMetaFile.png"); + } + + @DataProvider(name = "windowsMetaFileDataProvider") + public static Object[][] windowsMetaFileDataProvider() { + return new Object[][] + { + {MetafileRenderingMode.VECTOR}, + {MetafileRenderingMode.BITMAP}, + {MetafileRenderingMode.VECTOR_WITH_FALLBACK}, + }; + } + + @Test + public void pageByPage() throws Exception { + //ExStart + //ExFor:Document.Save(String, SaveOptions) + //ExFor:FixedPageSaveOptions + //ExFor:ImageSaveOptions.PageSet + //ExFor:ImageSaveOptions.ImageSize + //ExSummary:Shows how to render every page of a document to a separate TIFF image. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Page 1."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 2."); + builder.insertImage(getImageDir() + "Logo.jpg"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 3."); + + // Create an "ImageSaveOptions" object which we can pass to the document's "Save" method + // to modify the way in which that method renders the document into an image. + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.TIFF); + + for (int i = 0; i < doc.getPageCount(); i++) { + // Set the "PageSet" property to the number of the first page from + // which to start rendering the document from. + options.setPageSet(new PageSet(i)); + // Export page at 2325x5325 pixels and 600 dpi. + options.setResolution(600f); + options.setImageSize(new Dimension(2325, 5325)); + + doc.save(getArtifactsDir() + MessageFormat.format("ImageSaveOptions.PageByPage.{0}.tiff", i + 1), options); + } + //ExEnd + + String[] imageFileNames = DocumentHelper.directoryGetFiles(getArtifactsDir(), "*.tiff").stream().filter(i -> i.contains("ImageSaveOptions.PageByPage.") && i.endsWith(".tiff")).toArray(String[]::new); + + Assert.assertEquals(3, imageFileNames.length); + } + + @Test(dataProvider = "colorModeDataProvider") + public void colorMode(int imageColorMode) throws Exception { + //ExStart + //ExFor:ImageColorMode + //ExFor:ImageSaveOptions.ImageColorMode + //ExSummary:Shows how to set a color mode when rendering documents. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 1")); + builder.writeln("Hello world!"); + builder.insertImage(getImageDir() + "Logo.jpg"); + + Assert.assertTrue(new File(getImageDir() + "Logo.jpg").length() < 20200); + + // When we save the document as an image, we can pass a SaveOptions object to + // select a color mode for the image that the saving operation will generate. + // If we set the "ImageColorMode" property to "ImageColorMode.BlackAndWhite", + // the saving operation will apply grayscale color reduction while rendering the document. + // If we set the "ImageColorMode" property to "ImageColorMode.Grayscale", + // the saving operation will render the document into a monochrome image. + // If we set the "ImageColorMode" property to "None", the saving operation will apply the default method + // and preserve all the document's colors in the output image. + ImageSaveOptions imageSaveOptions = new ImageSaveOptions(SaveFormat.PNG); + imageSaveOptions.setImageColorMode(imageColorMode); + + doc.save(getArtifactsDir() + "ImageSaveOptions.ColorMode.png", imageSaveOptions); + //ExEnd + + long testedImageLength = new File(getArtifactsDir() + "ImageSaveOptions.ColorMode.png").length(); + switch (imageColorMode) { + case ImageColorMode.NONE: + Assert.assertTrue(testedImageLength < 156000); + break; + case ImageColorMode.GRAYSCALE: + Assert.assertTrue(testedImageLength < 85000); + break; + case ImageColorMode.BLACK_AND_WHITE: + Assert.assertTrue(testedImageLength <= 20000); + break; + } + } + + @DataProvider(name = "colorModeDataProvider") + public static Object[][] colorModeDataProvider() { + return new Object[][] + { + {ImageColorMode.BLACK_AND_WHITE}, + {ImageColorMode.GRAYSCALE}, + {ImageColorMode.NONE}, + }; + } + + @Test + public void paperColor() throws Exception { + //ExStart + //ExFor:ImageSaveOptions + //ExFor:ImageSaveOptions.PaperColor + //ExSummary:Renders a page of a Word document into an image with transparent or colored background. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Times New Roman"); + builder.getFont().setSize(24.0); + builder.writeln("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + + builder.insertImage(getImageDir() + "Logo.jpg"); + + // Create an "ImageSaveOptions" object which we can pass to the document's "Save" method + // to modify the way in which that method renders the document into an image. + ImageSaveOptions imgOptions = new ImageSaveOptions(SaveFormat.PNG); + + // Set the "PaperColor" property to a transparent color to apply a transparent + // background to the document while rendering it to an image. + imgOptions.setPaperColor(new Color(1f, 0f, 0f, .5f)); + + doc.save(getArtifactsDir() + "ImageSaveOptions.PaperColor.Transparent.png", imgOptions); + + // Set the "PaperColor" property to an opaque color to apply that color + // as the background of the document as we render it to an image. + imgOptions.setPaperColor(Color.cyan); + + doc.save(getArtifactsDir() + "ImageSaveOptions.PaperColor.LightCoral.png", imgOptions); + //ExEnd + + TestUtil.imageContainsTransparency(getArtifactsDir() + "ImageSaveOptions.PaperColor.Transparent.png"); + Assert.assertThrows(AssertionError.class, () -> TestUtil.imageContainsTransparency(getArtifactsDir() + "ImageSaveOptions.PaperColor.LightCoral.png")); + } + + @Test(dataProvider = "pixelFormatDataProvider") + public void pixelFormat(int imagePixelFormat) throws Exception { + //ExStart + //ExFor:ImagePixelFormat + //ExFor:ImageSaveOptions.Clone + //ExFor:ImageSaveOptions.PixelFormat + //ExSummary:Shows how to select a bit-per-pixel rate with which to render a document to an image. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 1")); + builder.writeln("Hello world!"); + builder.insertImage(getImageDir() + "Logo.jpg"); + + Assert.assertTrue(new File(getImageDir() + "Logo.jpg").length() < 21000); + + // When we save the document as an image, we can pass a SaveOptions object to + // select a pixel format for the image that the saving operation will generate. + // Various bit per pixel rates will affect the quality and file size of the generated image. + ImageSaveOptions imageSaveOptions = new ImageSaveOptions(SaveFormat.PNG); + imageSaveOptions.setPixelFormat(imagePixelFormat); + + // We can clone ImageSaveOptions instances. + Assert.assertNotEquals(imageSaveOptions, imageSaveOptions.deepClone()); + + doc.save(getArtifactsDir() + "ImageSaveOptions.PixelFormat.png", imageSaveOptions); + //ExEnd + + switch (imagePixelFormat) { + case ImagePixelFormat.FORMAT_1_BPP_INDEXED: + Assert.assertTrue(new File(getArtifactsDir() + "ImageSaveOptions.PixelFormat.png").length() <= 10000); + break; + case ImagePixelFormat.FORMAT_16_BPP_RGB_565: + Assert.assertTrue(new File(getArtifactsDir() + "ImageSaveOptions.PixelFormat.png").length() <= 160000); + break; + case ImagePixelFormat.FORMAT_16_BPP_RGB_555: + case ImagePixelFormat.FORMAT_32_BPP_RGB: + case ImagePixelFormat.FORMAT_32_BPP_ARGB: + case ImagePixelFormat.FORMAT_48_BPP_RGB: + Assert.assertTrue(new File(getArtifactsDir() + "ImageSaveOptions.PixelFormat.png").length() < 156000); + break; + case ImagePixelFormat.FORMAT_24_BPP_RGB: + Assert.assertTrue(new File(getArtifactsDir() + "ImageSaveOptions.PixelFormat.png").length() < 146000); + break; + case ImagePixelFormat.FORMAT_64_BPP_ARGB: + case ImagePixelFormat.FORMAT_64_BPP_P_ARGB: + Assert.assertTrue(new File(getArtifactsDir() + "ImageSaveOptions.PixelFormat.png").length() < 239000); + break; + } + } + + @DataProvider(name = "pixelFormatDataProvider") + public static Object[][] pixelFormatDataProvider() { + return new Object[][] + { + {ImagePixelFormat.FORMAT_1_BPP_INDEXED}, + {ImagePixelFormat.FORMAT_16_BPP_RGB_555}, + {ImagePixelFormat.FORMAT_16_BPP_RGB_565}, + {ImagePixelFormat.FORMAT_24_BPP_RGB}, + {ImagePixelFormat.FORMAT_32_BPP_RGB}, + {ImagePixelFormat.FORMAT_32_BPP_ARGB}, + {ImagePixelFormat.FORMAT_32_BPP_P_ARGB}, + {ImagePixelFormat.FORMAT_48_BPP_RGB}, + {ImagePixelFormat.FORMAT_64_BPP_ARGB}, + {ImagePixelFormat.FORMAT_64_BPP_P_ARGB}, + }; + } + + @Test + public void floydSteinbergDithering() throws Exception { + //ExStart + //ExFor:ImageBinarizationMethod + //ExFor:ImageSaveOptions.ThresholdForFloydSteinbergDithering + //ExFor:ImageSaveOptions.TiffBinarizationMethod + //ExSummary:Shows how to set the TIFF binarization error threshold when using the Floyd-Steinberg method to render a TIFF image. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 1")); + builder.writeln("Hello world!"); + builder.insertImage(getImageDir() + "Logo.jpg"); + + // When we save the document as a TIFF, we can pass a SaveOptions object to + // adjust the dithering that Aspose.Words will apply when rendering this image. + // The default value of the "ThresholdForFloydSteinbergDithering" property is 128. + // Higher values tend to produce darker images. + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.TIFF); + options.setTiffCompression(TiffCompression.CCITT_3); + options.setTiffBinarizationMethod(ImageBinarizationMethod.FLOYD_STEINBERG_DITHERING); + options.setThresholdForFloydSteinbergDithering((byte) 240); + + doc.save(getArtifactsDir() + "ImageSaveOptions.FloydSteinbergDithering.tiff", options); + //ExEnd + } + + @Test + public void editImage() throws Exception { + //ExStart + //ExFor:ImageSaveOptions.HorizontalResolution + //ExFor:ImageSaveOptions.ImageBrightness + //ExFor:ImageSaveOptions.ImageContrast + //ExFor:ImageSaveOptions.SaveFormat + //ExFor:ImageSaveOptions.Scale + //ExFor:ImageSaveOptions.VerticalResolution + //ExSummary:Shows how to edit the image while Aspose.Words converts a document to one. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 1")); + builder.writeln("Hello world!"); + builder.insertImage(getImageDir() + "Logo.jpg"); + + // When we save the document as an image, we can pass a SaveOptions object to + // edit the image while the saving operation renders it. + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.PNG); + { + // We can adjust these properties to change the image's brightness and contrast. + // Both are on a 0-1 scale and are at 0.5 by default. + options.setImageBrightness(0.3f); + options.setImageContrast(0.7f); + + // We can adjust horizontal and vertical resolution with these properties. + // This will affect the dimensions of the image. + // The default value for these properties is 96.0, for a resolution of 96dpi. + options.setHorizontalResolution(72f); + options.setVerticalResolution(72f); + + // We can scale the image using this property. The default value is 1.0, for scaling of 100%. + // We can use this property to negate any changes in image dimensions that changing the resolution would cause. + options.setScale(96f / 72f); + } + + doc.save(getArtifactsDir() + "ImageSaveOptions.EditImage.png", options); + //ExEnd + + TestUtil.verifyImage(816, 1056, getArtifactsDir() + "ImageSaveOptions.EditImage.png"); + } + + @Test + public void jpegQuality() throws Exception { + //ExStart + //ExFor:Document.Save(String, SaveOptions) + //ExFor:FixedPageSaveOptions.JpegQuality + //ExFor:ImageSaveOptions + //ExFor:ImageSaveOptions.#ctor + //ExFor:ImageSaveOptions.JpegQuality + //ExSummary:Shows how to configure compression while saving a document as a JPEG. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertImage(getImageDir() + "Logo.jpg"); + + // Create an "ImageSaveOptions" object which we can pass to the document's "Save" method + // to modify the way in which that method renders the document into an image. + ImageSaveOptions imageOptions = new ImageSaveOptions(SaveFormat.JPEG); + + // Set the "JpegQuality" property to "10" to use stronger compression when rendering the document. + // This will reduce the file size of the document, but the image will display more prominent compression artifacts. + imageOptions.setJpegQuality(10); + + doc.save(getArtifactsDir() + "ImageSaveOptions.JpegQuality.HighCompression.jpg", imageOptions); + + Assert.assertTrue(new File(getArtifactsDir() + "ImageSaveOptions.JpegQuality.HighCompression.jpg").length() <= 20000); + + // Set the "JpegQuality" property to "100" to use weaker compression when rending the document. + // This will improve the quality of the image at the cost of an increased file size. + imageOptions.setJpegQuality(100); + + doc.save(getArtifactsDir() + "ImageSaveOptions.JpegQuality.HighQuality.jpg", imageOptions); + + Assert.assertTrue(new File(getArtifactsDir() + "ImageSaveOptions.JpegQuality.HighQuality.jpg").length() < 60000); + //ExEnd + } + + @Test + public void saveToTiffDefault() throws Exception { + Document doc = new Document(getMyDir() + "Rendering.docx"); + doc.save(getArtifactsDir() + "ImageSaveOptions.SaveToTiffDefault.tiff"); + } + + @Test(dataProvider = "tiffImageCompressionDataProvider") + public void tiffImageCompression(int tiffCompression) throws Exception { + //ExStart:TiffImageCompression + //GistId:f99d87e10ab87a581c52206321d8b617 + //ExFor:TiffCompression + //ExFor:ImageSaveOptions.TiffCompression + //ExSummary:Shows how to select the compression scheme to apply to a document that we convert into a TIFF image. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertImage(getImageDir() + "Tagged Image File Format.tiff"); + + // Create an "ImageSaveOptions" object which we can pass to the document's "Save" method + // to modify the way in which that method renders the document into an image. + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.TIFF); + + // Set the "TiffCompression" property to "TiffCompression.None" to apply no compression while saving, + // which may result in a very large output file. + // Set the "TiffCompression" property to "TiffCompression.Rle" to apply RLE compression + // Set the "TiffCompression" property to "TiffCompression.Lzw" to apply LZW compression. + // Set the "TiffCompression" property to "TiffCompression.Ccitt3" to apply CCITT3 compression. + // Set the "TiffCompression" property to "TiffCompression.Ccitt4" to apply CCITT4 compression. + options.setTiffCompression(tiffCompression); + + doc.save(getArtifactsDir() + "ImageSaveOptions.TiffImageCompression.tiff", options); + //ExEnd:TiffImageCompression + } + + //JAVA-added data provider for test method + @DataProvider(name = "tiffImageCompressionDataProvider") + public static Object[][] tiffImageCompressionDataProvider() throws Exception { + return new Object[][] + { + {TiffCompression.NONE}, + {TiffCompression.RLE}, + {TiffCompression.LZW}, + {TiffCompression.CCITT_3}, + {TiffCompression.CCITT_4}, + }; + } + + @Test + public void resolution() throws Exception { + //ExStart + //ExFor:ImageSaveOptions + //ExFor:ImageSaveOptions.Resolution + //ExSummary:Shows how to specify a resolution while rendering a document to PNG. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Times New Roman"); + builder.getFont().setSize(24.0); + builder.writeln("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + + builder.insertImage(getImageDir() + "Logo.jpg"); + + // Create an "ImageSaveOptions" object which we can pass to the document's "Save" method + // to modify the way in which that method renders the document into an image. + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.PNG); + + // Set the "Resolution" property to "72" to render the document in 72dpi. + options.setResolution(72f); + doc.save(getArtifactsDir() + "ImageSaveOptions.Resolution.72dpi.png", options); + + // Set the "Resolution" property to "300" to render the document in 300dpi. + options.setResolution(300f); + doc.save(getArtifactsDir() + "ImageSaveOptions.Resolution.300dpi.png", options); + //ExEnd + + TestUtil.verifyImage(612, 792, getArtifactsDir() + "ImageSaveOptions.Resolution.72dpi.png"); + TestUtil.verifyImage(2550, 3300, getArtifactsDir() + "ImageSaveOptions.Resolution.300dpi.png"); + } + + @Test(enabled = false) + public void exportVariousPageRanges() throws Exception { + //ExStart + //ExFor:PageSet.#ctor(PageRange[]) + //ExFor:PageRange + //ExFor:PageRange.#ctor(int, int) + //ExFor:ImageSaveOptions.PageSet + //ExSummary:Shows how to extract pages based on exact page ranges. + Document doc = new Document(getMyDir() + "Images.docx"); + + ImageSaveOptions imageOptions = new ImageSaveOptions(SaveFormat.TIFF); + PageSet pageSet = new PageSet(new PageRange(1, 1), new PageRange(2, 3), new PageRange(1, 3), new PageRange(2, 4), new PageRange(1, 1)); + + imageOptions.setPageSet(pageSet); + doc.save(getArtifactsDir() + "ImageSaveOptions.ExportVariousPageRanges.tiff", imageOptions); + //ExEnd + } + + @Test + public void renderInkObject() throws Exception + { + //ExStart + //ExFor:SaveOptions.ImlRenderingMode + //ExFor:ImlRenderingMode + //ExSummary:Shows how to render Ink object. + Document doc = new Document(getMyDir() + "Ink object.docx"); + + // Set 'ImlRenderingMode.InkML' ignores fall-back shape of ink (InkML) object and renders InkML itself. + // If the rendering result is unsatisfactory, + // please use 'ImlRenderingMode.Fallback' to get a result similar to previous versions. + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.JPEG); + { + saveOptions.setImlRenderingMode(ImlRenderingMode.INK_ML); + } + + doc.save(getArtifactsDir() + "ImageSaveOptions.RenderInkObject.jpeg", saveOptions); + //ExEnd + } + + @Test + public void gridLayout() throws Exception + { + //ExStart:GridLayout + //GistId:8abf985c6b9db41b7b20b19227e95ebc + //ExFor:ImageSaveOptions.PageLayout + //ExFor:MultiPageLayout + //ExSummary:Shows how to save the document into JPG image with multi-page layout settings. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.JPEG); + // Set up a grid layout with: + // - 3 columns per row. + // - 10pts spacing between pages (horizontal and vertical). + options.setPageLayout(MultiPageLayout.grid(3, 10f, 10f)); + + // Alternative layouts: + // options.PageLayout = MultiPageLayout.Horizontal(10); + // options.PageLayout = MultiPageLayout.Vertical(10); + + // Customize the background and border. + options.getPageLayout().setBackColor(Color.lightGray); + options.getPageLayout().setBorderColor(Color.BLUE); + options.getPageLayout().setBorderWidth(2f); + + doc.save(getArtifactsDir() + "ImageSaveOptions.GridLayout.jpg", options); + //ExEnd:GridLayout + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExInline.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExInline.java new file mode 100644 index 00000000..24cdd917 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExInline.java @@ -0,0 +1,85 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.Document; +import com.aspose.words.Paragraph; +import com.aspose.words.Run; +import com.aspose.words.RunCollection; +import org.testng.Assert; +import org.testng.annotations.Test; + +@Test +public class ExInline extends ApiExampleBase { + @Test + public void inlineRevisions() throws Exception { + //ExStart + //ExFor:Inline + //ExFor:Inline.IsDeleteRevision + //ExFor:Inline.IsFormatRevision + //ExFor:Inline.IsInsertRevision + //ExFor:Inline.IsMoveFromRevision + //ExFor:Inline.IsMoveToRevision + //ExFor:Inline.ParentParagraph + //ExFor:Paragraph.Runs + //ExFor:Revision.ParentNode + //ExFor:RunCollection + //ExFor:RunCollection.Item(Int32) + //ExFor:RunCollection.ToArray + //ExSummary:Shows how to determine the revision type of an inline node. + Document doc = new Document(getMyDir() + "Revision runs.docx"); + + // When we edit the document while the "Track Changes" option, found in via Review -> Tracking, + // is turned on in Microsoft Word, the changes we apply count as revisions. + // When editing a document using Aspose.Words, we can begin tracking revisions by + // invoking the document's "StartTrackRevisions" method and stop tracking by using the "StopTrackRevisions" method. + // We can either accept revisions to assimilate them into the document + // or reject them to change the proposed change effectively. + Assert.assertEquals(6, doc.getRevisions().getCount()); + + // The parent node of a revision is the run that the revision concerns. A Run is an Inline node. + Run run = (Run) doc.getRevisions().get(0).getParentNode(); + + Paragraph firstParagraph = run.getParentParagraph(); + RunCollection runs = firstParagraph.getRuns(); + + Assert.assertEquals(runs.getCount(), 6); + + // Below are five types of revisions that can flag an Inline node. + // 1 - An "insert" revision: + // This revision occurs when we insert text while tracking changes. + Assert.assertTrue(runs.get(2).isInsertRevision()); + + // 2 - A "format" revision: + // This revision occurs when we change the formatting of text while tracking changes. + Assert.assertTrue(runs.get(2).isFormatRevision()); + + // 3 - A "move from" revision: + // When we highlight text in Microsoft Word, and then drag it to a different place in the document + // while tracking changes, two revisions appear. + // The "move from" revision is a copy of the text originally before we moved it. + Assert.assertTrue(runs.get(4).isMoveFromRevision()); + + // 4 - A "move to" revision: + // The "move to" revision is the text that we moved in its new position in the document. + // "Move from" and "move to" revisions appear in pairs for every move revision we carry out. + // Accepting a move revision deletes the "move from" revision and its text, + // and keeps the text from the "move to" revision. + // Rejecting a move revision conversely keeps the "move from" revision and deletes the "move to" revision. + Assert.assertTrue(runs.get(1).isMoveToRevision()); + + // 5 - A "delete" revision: + // This revision occurs when we delete text while tracking changes. When we delete text like this, + // it will stay in the document as a revision until we either accept the revision, + // which will delete the text for good, or reject the revision, which will keep the text we deleted where it was. + Assert.assertTrue(runs.get(5).isDeleteRevision()); + //ExEnd + } +} + diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExInlineStory.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExInlineStory.java new file mode 100644 index 00000000..c4092bd9 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExInlineStory.java @@ -0,0 +1,688 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.awt.*; +import java.util.Date; + +@Test +public class ExInlineStory extends ApiExampleBase { + @Test(dataProvider = "positionFootnoteDataProvider") + public void positionFootnote(/*FootnotePosition*/int footnotePosition) throws Exception { + //ExStart + //ExFor:Document.FootnoteOptions + //ExFor:FootnoteOptions + //ExFor:FootnoteOptions.Position + //ExFor:FootnotePosition + //ExSummary:Shows how to select a different place where the document collects and displays its footnotes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // A footnote is a way to attach a reference or a side comment to text + // that does not interfere with the main body text's flow. + // Inserting a footnote adds a small superscript reference symbol + // at the main body text where we insert the footnote. + // Each footnote also creates an entry at the bottom of the page, consisting of a symbol + // that matches the reference symbol in the main body text. + // The reference text that we pass to the document builder's "InsertFootnote" method. + builder.write("Hello world!"); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote contents."); + + // We can use the "Position" property to determine where the document will place all its footnotes. + // If we set the value of the "Position" property to "FootnotePosition.BottomOfPage", + // every footnote will show up at the bottom of the page that contains its reference mark. This is the default value. + // If we set the value of the "Position" property to "FootnotePosition.BeneathText", + // every footnote will show up at the end of the page's text that contains its reference mark. + doc.getFootnoteOptions().setPosition(footnotePosition); + + doc.save(getArtifactsDir() + "InlineStory.PositionFootnote.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "InlineStory.PositionFootnote.docx"); + + Assert.assertEquals(footnotePosition, doc.getFootnoteOptions().getPosition()); + + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote contents.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 0, true)); + } + + @DataProvider(name = "positionFootnoteDataProvider") + public static Object[][] positionFootnoteDataProvider() { + return new Object[][] + { + {FootnotePosition.BENEATH_TEXT}, + {FootnotePosition.BOTTOM_OF_PAGE}, + }; + } + + @Test(dataProvider = "positionEndnoteDataProvider") + public void positionEndnote(/*EndnotePosition*/int endnotePosition) throws Exception { + //ExStart + //ExFor:Document.EndnoteOptions + //ExFor:EndnoteOptions + //ExFor:EndnoteOptions.Position + //ExFor:EndnotePosition + //ExSummary:Shows how to select a different place where the document collects and displays its endnotes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // An endnote is a way to attach a reference or a side comment to text + // that does not interfere with the main body text's flow. + // Inserting an endnote adds a small superscript reference symbol + // at the main body text where we insert the endnote. + // Each endnote also creates an entry at the end of the document, consisting of a symbol + // that matches the reference symbol in the main body text. + // The reference text that we pass to the document builder's "InsertEndnote" method. + builder.write("Hello world!"); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote contents."); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.write("This is the second section."); + + // We can use the "Position" property to determine where the document will place all its endnotes. + // If we set the value of the "Position" property to "EndnotePosition.EndOfDocument", + // every footnote will show up in a collection at the end of the document. This is the default value. + // If we set the value of the "Position" property to "EndnotePosition.EndOfSection", + // every footnote will show up in a collection at the end of the section whose text contains the endnote's reference mark. + doc.getEndnoteOptions().setPosition(endnotePosition); + + doc.save(getArtifactsDir() + "InlineStory.PositionEndnote.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "InlineStory.PositionEndnote.docx"); + + Assert.assertEquals(endnotePosition, doc.getEndnoteOptions().getPosition()); + + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "Endnote contents.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 0, true)); + } + + //JAVA-added data provider for test method + @DataProvider(name = "positionEndnoteDataProvider") + public static Object[][] positionEndnoteDataProvider() throws Exception { + return new Object[][] + { + {EndnotePosition.END_OF_DOCUMENT}, + {EndnotePosition.END_OF_SECTION}, + }; + } + + @Test + public void refMarkNumberStyle() throws Exception { + //ExStart + //ExFor:Document.EndnoteOptions + //ExFor:EndnoteOptions + //ExFor:EndnoteOptions.NumberStyle + //ExFor:Document.FootnoteOptions + //ExFor:FootnoteOptions + //ExFor:FootnoteOptions.NumberStyle + //ExSummary:Shows how to change the number style of footnote/endnote reference marks. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Footnotes and endnotes are a way to attach a reference or a side comment to text + // that does not interfere with the main body text's flow. + // Inserting a footnote/endnote adds a small superscript reference symbol + // at the main body text where we insert the footnote/endnote. + // Each footnote/endnote also creates an entry, which consists of a symbol that matches the reference + // symbol in the main body text. The reference text that we pass to the document builder's "InsertEndnote" method. + // Footnote entries, by default, show up at the bottom of each page that contains + // their reference symbols, and endnotes show up at the end of the document. + builder.write("Text 1. "); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote 1."); + builder.write("Text 2. "); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote 2."); + builder.write("Text 3. "); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote 3.", "Custom footnote reference mark"); + + builder.insertParagraph(); + + builder.write("Text 1. "); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote 1."); + builder.write("Text 2. "); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote 2."); + builder.write("Text 3. "); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote 3.", "Custom endnote reference mark"); + + // By default, the reference symbol for each footnote and endnote is its index + // among all the document's footnotes/endnotes. Each document maintains separate counts + // for footnotes and for endnotes. By default, footnotes display their numbers using Arabic numerals, + // and endnotes display their numbers in lowercase Roman numerals. + Assert.assertEquals(NumberStyle.ARABIC, doc.getFootnoteOptions().getNumberStyle()); + Assert.assertEquals(NumberStyle.LOWERCASE_ROMAN, doc.getEndnoteOptions().getNumberStyle()); + + // We can use the "NumberStyle" property to apply custom numbering styles to footnotes and endnotes. + // This will not affect footnotes/endnotes with custom reference marks. + doc.getFootnoteOptions().setNumberStyle(NumberStyle.UPPERCASE_ROMAN); + doc.getEndnoteOptions().setNumberStyle(NumberStyle.UPPERCASE_LETTER); + + doc.save(getArtifactsDir() + "InlineStory.RefMarkNumberStyle.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "InlineStory.RefMarkNumberStyle.docx"); + + Assert.assertEquals(NumberStyle.UPPERCASE_ROMAN, doc.getFootnoteOptions().getNumberStyle()); + Assert.assertEquals(NumberStyle.UPPERCASE_LETTER, doc.getEndnoteOptions().getNumberStyle()); + + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote 1.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 0, true)); + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote 2.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 1, true)); + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, false, "Custom footnote reference mark", + "Custom footnote reference mark Footnote 3.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 2, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "Endnote 1.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 3, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "Endnote 2.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 4, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, false, "Custom endnote reference mark", + "Custom endnote reference mark Endnote 3.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 5, true)); + } + + @Test + public void numberingRule() throws Exception { + //ExStart + //ExFor:Document.EndnoteOptions + //ExFor:EndnoteOptions + //ExFor:EndnoteOptions.RestartRule + //ExFor:FootnoteNumberingRule + //ExFor:Document.FootnoteOptions + //ExFor:FootnoteOptions + //ExFor:FootnoteOptions.RestartRule + //ExSummary:Shows how to restart footnote/endnote numbering at certain places in the document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Footnotes and endnotes are a way to attach a reference or a side comment to text + // that does not interfere with the main body text's flow. + // Inserting a footnote/endnote adds a small superscript reference symbol + // at the main body text where we insert the footnote/endnote. + // Each footnote/endnote also creates an entry, which consists of a symbol that matches the reference + // symbol in the main body text. The reference text that we pass to the document builder's "InsertEndnote" method. + // Footnote entries, by default, show up at the bottom of each page that contains + // their reference symbols, and endnotes show up at the end of the document. + builder.write("Text 1. "); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote 1."); + builder.write("Text 2. "); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote 2."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.write("Text 3. "); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote 3."); + builder.write("Text 4. "); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote 4."); + + builder.insertBreak(BreakType.PAGE_BREAK); + + builder.write("Text 1. "); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote 1."); + builder.write("Text 2. "); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote 2."); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.write("Text 3. "); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote 3."); + builder.write("Text 4. "); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote 4."); + + // By default, the reference symbol for each footnote and endnote is its index + // among all the document's footnotes/endnotes. Each document maintains separate counts + // for footnotes and endnotes and does not restart these counts at any point. + Assert.assertEquals(doc.getFootnoteOptions().getRestartRule(), FootnoteNumberingRule.DEFAULT); + Assert.assertEquals(FootnoteNumberingRule.DEFAULT, FootnoteNumberingRule.CONTINUOUS); + + // We can use the "RestartRule" property to get the document to restart + // the footnote/endnote counts at a new page or section. + doc.getFootnoteOptions().setRestartRule(FootnoteNumberingRule.RESTART_PAGE); + doc.getEndnoteOptions().setRestartRule(FootnoteNumberingRule.RESTART_SECTION); + + doc.save(getArtifactsDir() + "InlineStory.NumberingRule.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "InlineStory.NumberingRule.docx"); + + Assert.assertEquals(FootnoteNumberingRule.RESTART_PAGE, doc.getFootnoteOptions().getRestartRule()); + Assert.assertEquals(FootnoteNumberingRule.RESTART_SECTION, doc.getEndnoteOptions().getRestartRule()); + + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote 1.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 0, true)); + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote 2.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 1, true)); + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote 3.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 2, true)); + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote 4.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 3, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "Endnote 1.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 4, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "Endnote 2.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 5, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "Endnote 3.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 6, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "Endnote 4.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 7, true)); + } + + @Test + public void startNumber() throws Exception { + //ExStart + //ExFor:Document.EndnoteOptions + //ExFor:EndnoteOptions + //ExFor:EndnoteOptions.StartNumber + //ExFor:Document.FootnoteOptions + //ExFor:FootnoteOptions + //ExFor:FootnoteOptions.StartNumber + //ExSummary:Shows how to set a number at which the document begins the footnote/endnote count. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Footnotes and endnotes are a way to attach a reference or a side comment to text + // that does not interfere with the main body text's flow. + // Inserting a footnote/endnote adds a small superscript reference symbol + // at the main body text where we insert the footnote/endnote. + // Each footnote/endnote also creates an entry, which consists of a symbol + // that matches the reference symbol in the main body text. + // The reference text that we pass to the document builder's "InsertEndnote" method. + // Footnote entries, by default, show up at the bottom of each page that contains + // their reference symbols, and endnotes show up at the end of the document. + builder.write("Text 1. "); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote 1."); + builder.write("Text 2. "); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote 2."); + builder.write("Text 3. "); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote 3."); + + builder.insertParagraph(); + + builder.write("Text 1. "); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote 1."); + builder.write("Text 2. "); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote 2."); + builder.write("Text 3. "); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote 3."); + + // By default, the reference symbol for each footnote and endnote is its index + // among all the document's footnotes/endnotes. Each document maintains separate counts + // for footnotes and for endnotes, which both begin at 1. + Assert.assertEquals(1, doc.getFootnoteOptions().getStartNumber()); + Assert.assertEquals(1, doc.getEndnoteOptions().getStartNumber()); + + // We can use the "StartNumber" property to get the document to + // begin a footnote or endnote count at a different number. + doc.getEndnoteOptions().setNumberStyle(NumberStyle.ARABIC); + doc.getEndnoteOptions().setStartNumber(50); + + doc.save(getArtifactsDir() + "InlineStory.StartNumber.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "InlineStory.StartNumber.docx"); + + Assert.assertEquals(1, doc.getFootnoteOptions().getStartNumber()); + Assert.assertEquals(50, doc.getEndnoteOptions().getStartNumber()); + Assert.assertEquals(NumberStyle.ARABIC, doc.getFootnoteOptions().getNumberStyle()); + Assert.assertEquals(NumberStyle.ARABIC, doc.getEndnoteOptions().getNumberStyle()); + + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote 1.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 0, true)); + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote 2.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 1, true)); + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote 3.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 2, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "Endnote 1.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 3, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "Endnote 2.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 4, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "Endnote 3.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 5, true)); + } + + @Test + public void addFootnote() throws Exception { + //ExStart + //ExFor:Footnote + //ExFor:Footnote.IsAuto + //ExFor:Footnote.ReferenceMark + //ExFor:InlineStory + //ExFor:InlineStory.Paragraphs + //ExFor:InlineStory.FirstParagraph + //ExFor:FootnoteType + //ExFor:Footnote.#ctor + //ExSummary:Shows how to insert and customize footnotes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Add text, and reference it with a footnote. This footnote will place a small superscript reference + // mark after the text that it references and create an entry below the main body text at the bottom of the page. + // This entry will contain the footnote's reference mark and the reference text, + // which we will pass to the document builder's "InsertFootnote" method. + builder.write("Main body text."); + Footnote footnote = builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote text."); + + // If this property is set to "true", then our footnote's reference mark + // will be its index among all the section's footnotes. + // This is the first footnote, so the reference mark will be "1". + Assert.assertTrue(footnote.isAuto()); + + // We can move the document builder inside the footnote to edit its reference text. + builder.moveTo(footnote.getFirstParagraph()); + builder.write(" More text added by a DocumentBuilder."); + builder.moveToDocumentEnd(); + + Assert.assertEquals(footnote.getParagraphs().get(0).toString(SaveFormat.TEXT).trim(), "Footnote text. More text added by a DocumentBuilder."); + + builder.write(" More main body text."); + footnote = builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote text."); + + // We can set a custom reference mark which the footnote will use instead of its index number. + footnote.setReferenceMark("RefMark"); + + Assert.assertFalse(footnote.isAuto()); + + // A bookmark with the "IsAuto" flag set to true will still show its real index + // even if previous bookmarks display custom reference marks, so this bookmark's reference mark will be a "3". + builder.write(" More main body text."); + footnote = builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote text."); + + Assert.assertTrue(footnote.isAuto()); + + doc.save(getArtifactsDir() + "InlineStory.AddFootnote.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "InlineStory.AddFootnote.docx"); + + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote text. More text added by a DocumentBuilder.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 0, true)); + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, false, "RefMark", + "Footnote text.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 1, true)); + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote text.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 2, true)); + } + + @Test + public void footnoteEndnote() throws Exception { + //ExStart + //ExFor:Footnote.FootnoteType + //ExSummary:Shows the difference between footnotes and endnotes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are two ways of attaching numbered references to the text. Both these references will add a + // small superscript reference mark at the location that we insert them. + // The reference mark, by default, is the index number of the reference among all the references in the document. + // Each reference will also create an entry, which will have the same reference mark as in the body text + // and reference text, which we will pass to the document builder's "InsertFootnote" method. + // 1 - A footnote, whose entry will appear on the same page as the text that it references: + builder.write("Footnote referenced main body text."); + Footnote footnote = builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote text, will appear at the bottom of the page that contains the referenced text."); + + // 2 - An endnote, whose entry will appear at the end of the document: + builder.write("Endnote referenced main body text."); + Footnote endnote = builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote text, will appear at the very end of the document."); + + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + + Assert.assertEquals(footnote.getFootnoteType(), FootnoteType.FOOTNOTE); + Assert.assertEquals(endnote.getFootnoteType(), FootnoteType.ENDNOTE); + + doc.save(getArtifactsDir() + "InlineStory.FootnoteEndnote.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "InlineStory.FootnoteEndnote.docx"); + + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote text, will appear at the bottom of the page that contains the referenced text.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 0, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "Endnote text, will appear at the very end of the document.", (Footnote) doc.getChild(NodeType.FOOTNOTE, 1, true)); + } + + @Test(enabled = false, description = "WORDSJAVA-2406") + public void addComment() throws Exception { + //ExStart + //ExFor:Comment + //ExFor:InlineStory + //ExFor:InlineStory.Paragraphs + //ExFor:InlineStory.FirstParagraph + //ExFor:Comment.#ctor(DocumentBase, String, String, DateTime) + //ExSummary:Shows how to add a comment to a paragraph. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.write("Hello world!"); + + Comment comment = new Comment(doc, "John Doe", "JD", new Date()); + builder.getCurrentParagraph().appendChild(comment); + builder.moveTo(comment.appendChild(new Paragraph(doc))); + builder.write("Comment text."); + + Assert.assertEquals(new Date(), comment.getDateTime()); + + // In Microsoft Word, we can right-click this comment in the document body to edit it, or reply to it. + doc.save(getArtifactsDir() + "InlineStory.AddComment.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "InlineStory.AddComment.docx"); + comment = (Comment) doc.getChild(NodeType.COMMENT, 0, true); + + Assert.assertEquals("Comment text.\r", comment.getText()); + Assert.assertEquals("John Doe", comment.getAuthor()); + Assert.assertEquals("JD", comment.getInitial()); + Assert.assertEquals(new Date(), comment.getDateTime()); + } + + @Test + public void inlineStoryRevisions() throws Exception { + //ExStart + //ExFor:InlineStory.IsDeleteRevision + //ExFor:InlineStory.IsInsertRevision + //ExFor:InlineStory.IsMoveFromRevision + //ExFor:InlineStory.IsMoveToRevision + //ExSummary:Shows how to view revision-related properties of InlineStory nodes. + Document doc = new Document(getMyDir() + "Revision footnotes.docx"); + + // When we edit the document while the "Track Changes" option, found in via Review -> Tracking, + // is turned on in Microsoft Word, the changes we apply count as revisions. + // When editing a document using Aspose.Words, we can begin tracking revisions by + // invoking the document's "StartTrackRevisions" method and stop tracking by using the "StopTrackRevisions" method. + // We can either accept revisions to assimilate them into the document + // or reject them to undo and discard the proposed change. + Assert.assertTrue(doc.hasRevisions()); + + NodeCollection footnotes = doc.getChildNodes(NodeType.FOOTNOTE, true); + Assert.assertEquals(5, footnotes.getCount()); + + // Below are five types of revisions that can flag an InlineStory node. + // 1 - An "insert" revision: + // This revision occurs when we insert text while tracking changes. + Footnote footnote = (Footnote) footnotes.get(2); + Assert.assertTrue(footnote.isInsertRevision()); + + // 2 - A "move from" revision: + // When we highlight text in Microsoft Word, and then drag it to a different place in the document + // while tracking changes, two revisions appear. + // The "move from" revision is a copy of the text originally before we moved it. + footnote = (Footnote) footnotes.get(4); + Assert.assertTrue(footnote.isMoveFromRevision()); + + // 3 - A "move to" revision: + // The "move to" revision is the text that we moved in its new position in the document. + // "Move from" and "move to" revisions appear in pairs for every move revision we carry out. + // Accepting a move revision deletes the "move from" revision and its text, + // and keeps the text from the "move to" revision. + // Rejecting a move revision conversely keeps the "move from" revision and deletes the "move to" revision. + footnote = (Footnote) footnotes.get(1); + Assert.assertTrue(footnote.isMoveToRevision()); + + // 4 - A "delete" revision: + // This revision occurs when we delete text while tracking changes. When we delete text like this, + // it will stay in the document as a revision until we either accept the revision, + // which will delete the text for good, or reject the revision, which will keep the text we deleted where it was. + footnote = (Footnote) footnotes.get(3); + Assert.assertTrue(footnote.isDeleteRevision()); + //ExEnd + } + + @Test + public void insertInlineStoryNodes() throws Exception { + //ExStart + //ExFor:Comment.StoryType + //ExFor:Footnote.StoryType + //ExFor:InlineStory.EnsureMinimum + //ExFor:InlineStory.Font + //ExFor:InlineStory.LastParagraph + //ExFor:InlineStory.ParentParagraph + //ExFor:InlineStory.StoryType + //ExFor:InlineStory.Tables + //ExSummary:Shows how to insert InlineStory nodes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + Footnote footnote = builder.insertFootnote(FootnoteType.FOOTNOTE, null); + + // Table nodes have an "EnsureMinimum()" method that makes sure the table has at least one cell. + Table table = new Table(doc); + table.ensureMinimum(); + + // We can place a table inside a footnote, which will make it appear at the referencing page's footer. + Assert.assertEquals(footnote.getTables().getCount(), 0); + footnote.appendChild(table); + Assert.assertEquals(footnote.getTables().getCount(), 1); + Assert.assertEquals(footnote.getLastChild().getNodeType(), NodeType.TABLE); + + // An InlineStory has an "EnsureMinimum()" method as well, but in this case, + // it makes sure the last child of the node is a paragraph, + // for us to be able to click and write text easily in Microsoft Word. + footnote.ensureMinimum(); + Assert.assertEquals(footnote.getLastChild().getNodeType(), NodeType.PARAGRAPH); + + // Edit the appearance of the anchor, which is the small superscript number + // in the main text that points to the footnote. + footnote.getFont().setName("Arial"); + footnote.getFont().setColor(Color.GREEN); + + // All inline story nodes have their respective story types. + Assert.assertEquals(footnote.getStoryType(), StoryType.FOOTNOTES); + + // A comment is another type of inline story. + Comment comment = (Comment) builder.getCurrentParagraph().appendChild(new Comment(doc, "John Doe", "J. D.", new Date())); + + // The parent paragraph of an inline story node will be the one from the main document body. + Assert.assertEquals(doc.getFirstSection().getBody().getFirstParagraph(), comment.getParentParagraph()); + + // However, the last paragraph is the one from the comment text contents, + // which will be outside the main document body in a speech bubble. + // A comment will not have any child nodes by default, + // so we can apply the EnsureMinimum() method to place a paragraph here as well. + Assert.assertNull(comment.getLastParagraph()); + comment.ensureMinimum(); + Assert.assertEquals(comment.getLastChild().getNodeType(), NodeType.PARAGRAPH); + + // Once we have a paragraph, we can move the builder to do it and write our comment. + builder.moveTo(comment.getLastParagraph()); + builder.write("My comment."); + + Assert.assertEquals(comment.getStoryType(), StoryType.COMMENTS); + + doc.save(getArtifactsDir() + "InlineStory.InsertInlineStoryNodes.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "InlineStory.InsertInlineStoryNodes.docx"); + + footnote = (Footnote) doc.getChild(NodeType.FOOTNOTE, 0, true); + + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", "", + (Footnote) doc.getChild(NodeType.FOOTNOTE, 0, true)); + Assert.assertEquals("Arial", footnote.getFont().getName()); + Assert.assertEquals(Color.GREEN.getRGB(), footnote.getFont().getColor().getRGB()); + + comment = (Comment) doc.getChild(NodeType.COMMENT, 0, true); + + Assert.assertEquals("My comment.", comment.toString(SaveFormat.TEXT).trim()); + } + + @Test + public void deleteShapes() throws Exception { + //ExStart + //ExFor:Story + //ExFor:Story.DeleteShapes + //ExFor:Story.StoryType + //ExFor:StoryType + //ExSummary:Shows how to remove all shapes from a node. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Use a DocumentBuilder to insert a shape. This is an inline shape, + // which has a parent Paragraph, which is a child node of the first section's Body. + builder.insertShape(ShapeType.CUBE, 100.0, 100.0); + + Assert.assertEquals(doc.getChildNodes(NodeType.SHAPE, true).getCount(), 1); + + // We can delete all shapes from the child paragraphs of this Body. + Assert.assertEquals(doc.getFirstSection().getBody().getStoryType(), StoryType.MAIN_TEXT); + doc.getFirstSection().getBody().deleteShapes(); + + Assert.assertEquals(doc.getChildNodes(NodeType.SHAPE, true).getCount(), 0); + //ExEnd + } + + @Test + public void updateActualReferenceMarks() throws Exception + { + //ExStart:UpdateActualReferenceMarks + //GistId:9c17d666c47318436785490829a3984f + //ExFor:Document.UpdateActualReferenceMarks + //ExFor:Footnote.ActualReferenceMark + //ExSummary:Shows how to get actual footnote reference mark. + Document doc = new Document(getMyDir() + "Footnotes and endnotes.docx"); + + Footnote footnote = (Footnote)doc.getChild(NodeType.FOOTNOTE, 1, true); + doc.updateFields(); + doc.updateActualReferenceMarks(); + + Assert.assertEquals("1", footnote.getActualReferenceMark()); + //ExEnd:UpdateActualReferenceMarks + } + + @Test + public void endnoteSeparator() throws Exception + { + //ExStart:EndnoteSeparator + //GistId:6280fd6c1c1854468bea095ec2af902b + //ExFor:DocumentBase.FootnoteSeparators + //ExFor:FootnoteSeparator + //ExFor:FootnoteSeparatorType + //ExFor:FootnoteSeparatorCollection + //ExFor:FootnoteSeparatorCollection.Item(FootnoteSeparatorType) + //ExSummary:Shows how to remove endnote separator. + Document doc = new Document(getMyDir() + "Footnotes and endnotes.docx"); + + FootnoteSeparator endnoteSeparator = doc.getFootnoteSeparators().getByFootnoteSeparatorType(FootnoteSeparatorType.ENDNOTE_SEPARATOR); + // Remove endnote separator. + endnoteSeparator.getFirstParagraph().getFirstChild().remove(); + //ExEnd:EndnoteSeparator + + doc.save(getArtifactsDir() + "InlineStory.EndnoteSeparator.docx"); + } + + @Test + public void footnoteSeparator() throws Exception + { + //ExStart:FootnoteSeparator + //GistId:6280fd6c1c1854468bea095ec2af902b + //ExFor:DocumentBase.FootnoteSeparators + //ExFor:FootnoteSeparatorType + //ExSummary:Shows how to manage footnote separator format. + Document doc = new Document(getMyDir() + "Footnotes and endnotes.docx"); + + FootnoteSeparator footnoteSeparator = doc.getFootnoteSeparators().getByFootnoteSeparatorType(FootnoteSeparatorType.FOOTNOTE_SEPARATOR); + // Align footnote separator. + footnoteSeparator.getFirstParagraph().getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + //ExEnd:FootnoteSeparator + + doc.save(getArtifactsDir() + "InlineStory.FootnoteSeparator.docx"); + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExLayout.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExLayout.java new file mode 100644 index 00000000..f460fffa --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExLayout.java @@ -0,0 +1,311 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.apache.commons.lang.StringUtils; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.awt.geom.Rectangle2D; +import java.io.FileOutputStream; +import java.text.MessageFormat; + +public class ExLayout extends ApiExampleBase { + @Test + public void layoutCollector() throws Exception { + //ExStart + //ExFor:LayoutCollector + //ExFor:LayoutCollector.#ctor(Document) + //ExFor:LayoutCollector.Clear + //ExFor:LayoutCollector.Document + //ExFor:LayoutCollector.GetEndPageIndex(Node) + //ExFor:LayoutCollector.GetEntity(Node) + //ExFor:LayoutCollector.GetNumPagesSpanned(Node) + //ExFor:LayoutCollector.GetStartPageIndex(Node) + //ExFor:LayoutEnumerator.Current + //ExSummary:Shows how to see the the ranges of pages that a node spans. + Document doc = new Document(); + LayoutCollector layoutCollector = new LayoutCollector(doc); + + // Call the "GetNumPagesSpanned" method to count how many pages the content of our document spans. + // Since the document is empty, that number of pages is currently zero. + Assert.assertEquals(doc, layoutCollector.getDocument()); + Assert.assertEquals(0, layoutCollector.getNumPagesSpanned(doc)); + + // Populate the document with 5 pages of content. + DocumentBuilder builder = new DocumentBuilder(doc); + builder.write("Section 1"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.insertBreak(BreakType.SECTION_BREAK_EVEN_PAGE); + builder.write("Section 2"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.insertBreak(BreakType.PAGE_BREAK); + + // Before the layout collector, we need to call the "UpdatePageLayout" method to give us + // an accurate figure for any layout-related metric, such as the page count. + Assert.assertEquals(0, layoutCollector.getNumPagesSpanned(doc)); + + layoutCollector.clear(); + doc.updatePageLayout(); + + Assert.assertEquals(5, layoutCollector.getNumPagesSpanned(doc)); + + // We can see the numbers of the start and end pages of any node and their overall page spans. + NodeCollection nodes = doc.getChildNodes(NodeType.ANY, true); + for (Node node : (Iterable) nodes) { + System.out.println(MessageFormat.format("-> NodeType.{0}: ", node.getNodeType())); + System.out.println(MessageFormat.format("\tStarts on page {0}, ends on page {1},", layoutCollector.getStartPageIndex(node), layoutCollector.getEndPageIndex(node)) + + MessageFormat.format(" spanning {0} pages.", layoutCollector.getNumPagesSpanned(node))); + } + + // We can iterate over the layout entities using a LayoutEnumerator. + LayoutEnumerator layoutEnumerator = new LayoutEnumerator(doc); + + Assert.assertEquals(LayoutEntityType.PAGE, layoutEnumerator.getType()); + + // The LayoutEnumerator can traverse the collection of layout entities like a tree. + // We can also apply it to any node's corresponding layout entity. + layoutEnumerator.setCurrent(layoutCollector.getEntity(doc.getChild(NodeType.PARAGRAPH, 1, true))); + + Assert.assertEquals(LayoutEntityType.SPAN, layoutEnumerator.getType()); + Assert.assertEquals("¶", layoutEnumerator.getText()); + //ExEnd + } + + //ExStart + //ExFor:LayoutEntityType + //ExFor:LayoutEnumerator + //ExFor:LayoutEnumerator.#ctor(Document) + //ExFor:LayoutEnumerator.Document + //ExFor:LayoutEnumerator.Kind + //ExFor:LayoutEnumerator.MoveFirstChild + //ExFor:LayoutEnumerator.MoveLastChild + //ExFor:LayoutEnumerator.MoveNext + //ExFor:LayoutEnumerator.MoveNextLogical + //ExFor:LayoutEnumerator.MoveParent + //ExFor:LayoutEnumerator.MoveParent(LayoutEntityType) + //ExFor:LayoutEnumerator.MovePrevious + //ExFor:LayoutEnumerator.MovePreviousLogical + //ExFor:LayoutEnumerator.PageIndex + //ExFor:LayoutEnumerator.Rectangle + //ExFor:LayoutEnumerator.Reset + //ExFor:LayoutEnumerator.Text + //ExFor:LayoutEnumerator.Type + //ExSummary:Shows ways of traversing a document's layout entities. + @Test //ExSkip + public void layoutEnumerator() throws Exception { + // Open a document that contains a variety of layout entities. + // Layout entities are pages, cells, rows, lines, and other objects included in the LayoutEntityType enum. + // Each layout entity has a rectangular space that it occupies in the document body. + Document doc = new Document(getMyDir() + "Layout entities.docx"); + + // Create an enumerator that can traverse these entities like a tree. + LayoutEnumerator layoutEnumerator = new LayoutEnumerator(doc); + + Assert.assertEquals(doc, layoutEnumerator.getDocument()); + + layoutEnumerator.moveParent(LayoutEntityType.PAGE); + + Assert.assertEquals(LayoutEntityType.PAGE, layoutEnumerator.getType()); + Assert.assertThrows(IllegalStateException.class, () -> System.out.println(layoutEnumerator.getText())); + + // We can call this method to make sure that the enumerator will be at the first layout entity. + layoutEnumerator.reset(); + + // There are two orders that determine how the layout enumerator continues traversing layout entities + // when it encounters entities that span across multiple pages. + // 1 - In visual order: + // When moving through an entity's children that span multiple pages, + // page layout takes precedence, and we move to other child elements on this page and avoid the ones on the next. + System.out.println("Traversing from first to last, elements between pages separated:"); + traverseLayoutForward(layoutEnumerator, 1); + + // Our enumerator is now at the end of the collection. We can traverse the layout entities backwards to go back to the beginning. + System.out.println("Traversing from last to first, elements between pages separated:"); + traverseLayoutBackward(layoutEnumerator, 1); + + // 2 - In logical order: + // When moving through an entity's children that span multiple pages, + // the enumerator will move between pages to traverse all the child entities. + System.out.println("Traversing from first to last, elements between pages mixed:"); + traverseLayoutForwardLogical(layoutEnumerator, 1); + + System.out.println("Traversing from last to first, elements between pages mixed:"); + traverseLayoutBackwardLogical(layoutEnumerator, 1); + } + + /// + /// Enumerate through layoutEnumerator's layout entity collection front-to-back, + /// in a depth-first manner, and in the "Visual" order. + /// + private static void traverseLayoutForward(LayoutEnumerator layoutEnumerator, int depth) throws Exception { + do { + printCurrentEntity(layoutEnumerator, depth); + + if (layoutEnumerator.moveFirstChild()) { + traverseLayoutForward(layoutEnumerator, depth + 1); + layoutEnumerator.moveParent(); + } + } while (layoutEnumerator.moveNext()); + } + + /// + /// Enumerate through layoutEnumerator's layout entity collection back-to-front, + /// in a depth-first manner, and in the "Visual" order. + /// + private static void traverseLayoutBackward(LayoutEnumerator layoutEnumerator, int depth) throws Exception { + do { + printCurrentEntity(layoutEnumerator, depth); + + if (layoutEnumerator.moveLastChild()) { + traverseLayoutBackward(layoutEnumerator, depth + 1); + layoutEnumerator.moveParent(); + } + } while (layoutEnumerator.movePrevious()); + } + + /// + /// Enumerate through layoutEnumerator's layout entity collection front-to-back, + /// in a depth-first manner, and in the "Logical" order. + /// + private static void traverseLayoutForwardLogical(LayoutEnumerator layoutEnumerator, int depth) throws Exception { + do { + printCurrentEntity(layoutEnumerator, depth); + + if (layoutEnumerator.moveFirstChild()) { + traverseLayoutForwardLogical(layoutEnumerator, depth + 1); + layoutEnumerator.moveParent(); + } + } while (layoutEnumerator.moveNextLogical()); + } + + /// + /// Enumerate through layoutEnumerator's layout entity collection back-to-front, + /// in a depth-first manner, and in the "Logical" order. + /// + private static void traverseLayoutBackwardLogical(LayoutEnumerator layoutEnumerator, int depth) throws Exception { + do { + printCurrentEntity(layoutEnumerator, depth); + + if (layoutEnumerator.moveLastChild()) { + traverseLayoutBackwardLogical(layoutEnumerator, depth + 1); + layoutEnumerator.moveParent(); + } + } while (layoutEnumerator.movePreviousLogical()); + } + + /// + /// Print information about layoutEnumerator's current entity to the console, while indenting the text with tab characters + /// based on its depth relative to the root node that we provided in the constructor LayoutEnumerator instance. + /// The rectangle that we process at the end represents the area and location that the entity takes up in the document. + /// + private static void printCurrentEntity(LayoutEnumerator layoutEnumerator, int indent) throws Exception { + String tabs = StringUtils.repeat("\t", indent); + + System.out.println(layoutEnumerator.getKind().equals("") + ? MessageFormat.format("{0}-> Entity type: {1}", tabs, layoutEnumerator.getType()) + : MessageFormat.format("{0}-> Entity type & kind: {1}, {2}", tabs, layoutEnumerator.getType(), layoutEnumerator.getKind())); + + // Only spans can contain text. + if (layoutEnumerator.getType() == LayoutEntityType.SPAN) + System.out.println("{tabs} Span contents: \"{layoutEnumerator.Text}\""); + + Rectangle2D.Float leRect = layoutEnumerator.getRectangle(); + System.out.println(MessageFormat.format("{0} Rectangle dimensions {1}x{2}, X={3} Y={4}", tabs, leRect.getWidth(), leRect.getHeight(), leRect.getX(), leRect.getY())); + System.out.println(MessageFormat.format("{0} Page {1}", tabs, layoutEnumerator.getPageIndex())); + } + //ExEnd + + //ExStart + //ExFor:IPageLayoutCallback + //ExFor:IPageLayoutCallback.Notify(PageLayoutCallbackArgs) + //ExFor:PageLayoutCallbackArgs + //ExFor:PageLayoutCallbackArgs.Event + //ExFor:PageLayoutCallbackArgs.Document + //ExFor:PageLayoutCallbackArgs.PageIndex + //ExFor:PageLayoutEvent + //ExFor:LayoutOptions.Callback + //ExSummary:Shows how to track layout changes with a layout callback. + @Test//ExSkip + public void pageLayoutCallback() throws Exception { + Document doc = new Document(); + doc.getBuiltInDocumentProperties().setTitle("My Document"); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + doc.getLayoutOptions().setCallback(new RenderPageLayoutCallback()); + doc.updatePageLayout(); + + doc.save(getArtifactsDir() + "Layout.PageLayoutCallback.pdf"); + } + + /// + /// Notifies us when we save the document to a fixed page format + /// and renders a page that we perform a page reflow on to an image in the local file system. + /// + private static class RenderPageLayoutCallback implements IPageLayoutCallback { + public void notify(PageLayoutCallbackArgs a) throws Exception { + switch (a.getEvent()) { + case PageLayoutEvent.PART_REFLOW_FINISHED: + notifyPartFinished(a); + break; + case PageLayoutEvent.CONVERSION_FINISHED: + notifyConversionFinished(a); + break; + } + } + + private void notifyPartFinished(PageLayoutCallbackArgs a) throws Exception { + System.out.println(MessageFormat.format("Part at page {0} reflow.", a.getPageIndex() + 1)); + renderPage(a, a.getPageIndex()); + } + + private void notifyConversionFinished(PageLayoutCallbackArgs a) { + System.out.println(MessageFormat.format("Document \"{0}\" converted to page format.", a.getDocument().getBuiltInDocumentProperties().getTitle())); + } + + private void renderPage(PageLayoutCallbackArgs a, int pageIndex) throws Exception { + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.PNG); + { + saveOptions.setPageSet(new PageSet(pageIndex)); + } + + try (FileOutputStream stream = new FileOutputStream(getArtifactsDir() + MessageFormat.format("PageLayoutCallback.page-{0} {1}.png", pageIndex + 1, ++mNum))) { + a.getDocument().save(stream, saveOptions); + } + } + + private int mNum; + } + //ExEnd + + @Test + public void restartPageNumberingInContinuousSection() throws Exception + { + //ExStart + //ExFor:LayoutOptions.ContinuousSectionPageNumberingRestart + //ExFor:ContinuousSectionRestart + //ExSummary:Shows how to control page numbering in a continuous section. + Document doc = new Document(getMyDir() + "Continuous section page numbering.docx"); + + // By default Aspose.Words behavior matches the Microsoft Word 2019. + // If you need old Aspose.Words behavior, repetitive Microsoft Word 2016, use 'ContinuousSectionRestart.FromNewPageOnly'. + // Page numbering restarts only if there is no other content before the section on the page where the section starts, + // because of that the numbering will reset to 2 from the second page. + doc.getLayoutOptions().setContinuousSectionPageNumberingRestart(ContinuousSectionRestart.FROM_NEW_PAGE_ONLY); + doc.updatePageLayout(); + + doc.save(getArtifactsDir() + "Layout.RestartPageNumberingInContinuousSection.pdf"); + //ExEnd + } +} + diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExLicense.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExLicense.java new file mode 100644 index 00000000..1d1839b2 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExLicense.java @@ -0,0 +1,62 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.License; +import org.apache.commons.io.FileUtils; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.FileInputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +public class ExLicense extends ApiExampleBase { + @Test + public void licenseFromFileNoPath() throws Exception { + //ExStart + //ExFor:License + //ExFor:License.#ctor + //ExFor:License.SetLicense(String) + //ExSummary:Shows how initialize a license for Aspose.Words using a license file in the local file system. + // Set the license for our Aspose.Words product by passing the local file system filename of a valid license file. + Path licenseFileName = Paths.get(getLicenseDir(), "Aspose.Words.Java.lic"); + + License license = new License(); + license.setLicense(licenseFileName.toString()); + + // Create a copy of our license file in the binaries folder of our application. + Path licenseCopyFileName = Paths.get(System.getProperty("user.dir"), "Aspose.Words.Java.lic"); + FileUtils.copyFile(new File(licenseFileName.toString()), new File(licenseCopyFileName.toString())); + + // If we pass a file's name without a path, + // the SetLicense will search several local file system locations for this file. + // One of those locations will be the "bin" folder, which contains a copy of our license file. + license.setLicense("Aspose.Words.Java.lic"); + //ExEnd + + license.setLicense(""); + Files.deleteIfExists(licenseCopyFileName); + } + + @Test + public void licenseFromStream() throws Exception { + //ExStart + //ExFor:License.SetLicense(Stream) + //ExSummary:Shows how to initialize a license for Aspose.Words from a stream. + // Set the license for our Aspose.Words product by passing a stream for a valid license file in our local file system. + try (FileInputStream myStream = new FileInputStream(getLicenseDir() + "Aspose.Words.Java.lic")) { + License license = new License(); + license.setLicense(myStream); + } + //ExEnd + } +} + diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExLists.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExLists.java new file mode 100644 index 00000000..6b18e42c --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExLists.java @@ -0,0 +1,1046 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.List; +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.awt.*; +import java.text.MessageFormat; + +public class ExLists extends ApiExampleBase { + @Test + public void applyDefaultBulletsAndNumbers() throws Exception { + //ExStart + //ExFor:DocumentBuilder.ListFormat + //ExFor:ListFormat.ApplyNumberDefault + //ExFor:ListFormat.ApplyBulletDefault + //ExFor:ListFormat.ListIndent + //ExFor:ListFormat.ListOutdent + //ExFor:ListFormat.RemoveNumbers + //ExFor:ListFormat.ListLevelNumber + //ExSummary:Shows how to create bulleted and numbered lists. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Aspose.Words main advantages are:"); + + // A list allows us to organize and decorate sets of paragraphs with prefix symbols and indents. + // We can create nested lists by increasing the indent level. + // We can begin and end a list by using a document builder's "ListFormat" property. + // Each paragraph that we add between a list's start and the end will become an item in the list. + // Below are two types of lists that we can create with a document builder. + // 1 - A bulleted list: + // This list will apply an indent and a bullet symbol ("•") before each paragraph. + builder.getListFormat().applyBulletDefault(); + builder.writeln("Great performance"); + builder.writeln("High reliability"); + builder.writeln("Quality code and working"); + builder.writeln("Wide variety of features"); + builder.writeln("Easy to understand API"); + + // End the bulleted list. + builder.getListFormat().removeNumbers(); + + builder.insertBreak(BreakType.PARAGRAPH_BREAK); + builder.writeln("Aspose.Words allows:"); + + // 2 - A numbered list: + // Numbered lists create a logical order for their paragraphs by numbering each item. + builder.getListFormat().applyNumberDefault(); + + // This paragraph is the first item. The first item of a numbered list will have a "1." as its list item symbol. + builder.writeln("Opening documents from different formats:"); + + Assert.assertEquals(0, builder.getListFormat().getListLevelNumber()); + + // Call the "ListIndent" method to increase the current list level, + // which will start a new self-contained list, with a deeper indent, at the current item of the first list level. + builder.getListFormat().listIndent(); + + Assert.assertEquals(1, builder.getListFormat().getListLevelNumber()); + + // These are the first three list items of the second list level, which will maintain a count + // independent of the count of the first list level. According to the current list format, + // they will have symbols of "a.", "b.", and "c.". + builder.writeln("DOC"); + builder.writeln("PDF"); + builder.writeln("HTML"); + + // Call the "ListOutdent" method to return to the previous list level. + builder.getListFormat().listOutdent(); + + Assert.assertEquals(0, builder.getListFormat().getListLevelNumber()); + + // These two paragraphs will continue the count of the first list level. + // These items will have symbols of "2.", and "3." + builder.writeln("Processing documents"); + builder.writeln("Saving documents in different formats:"); + + // If we increase the list level to a level that we have added items to previously, + // the nested list will be separate from the previous, and its numbering will start from the beginning. + // These list items will have symbols of "a.", "b.", "c.", "d.", and "e". + builder.getListFormat().listIndent(); + builder.writeln("DOC"); + builder.writeln("PDF"); + builder.writeln("HTML"); + builder.writeln("MHTML"); + builder.writeln("Plain text"); + + // Outdent the list level again. + builder.getListFormat().listOutdent(); + builder.writeln("Doing many other things!"); + + // End the numbered list. + builder.getListFormat().removeNumbers(); + + doc.save(getArtifactsDir() + "Lists.ApplyDefaultBulletsAndNumbers.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Lists.ApplyDefaultBulletsAndNumbers.docx"); + + TestUtil.verifyListLevel("\u0000.", 18.0d, NumberStyle.ARABIC, doc.getLists().get(1).getListLevels().get(0)); + TestUtil.verifyListLevel("\u0001.", 54.0d, NumberStyle.LOWERCASE_LETTER, doc.getLists().get(1).getListLevels().get(1)); + TestUtil.verifyListLevel("\uf0b7", 18.0d, NumberStyle.BULLET, doc.getLists().get(0).getListLevels().get(0)); + } + + @Test + public void specifyListLevel() throws Exception { + //ExStart + //ExFor:ListCollection + //ExFor:List + //ExFor:ListFormat + //ExFor:ListFormat.IsListItem + //ExFor:ListFormat.ListLevelNumber + //ExFor:ListFormat.List + //ExFor:ListTemplate + //ExFor:DocumentBase.Lists + //ExFor:ListCollection.Add(ListTemplate) + //ExSummary:Shows how to work with list levels. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Assert.assertFalse(builder.getListFormat().isListItem()); + + // A list allows us to organize and decorate sets of paragraphs with prefix symbols and indents. + // We can create nested lists by increasing the indent level. + // We can begin and end a list by using a document builder's "ListFormat" property. + // Each paragraph that we add between a list's start and the end will become an item in the list. + // Below are two types of lists that we can create using a document builder. + // 1 - A numbered list: + // Numbered lists create a logical order for their paragraphs by numbering each item. + builder.getListFormat().setList(doc.getLists().add(ListTemplate.NUMBER_DEFAULT)); + + Assert.assertTrue(builder.getListFormat().isListItem()); + + // By setting the "ListLevelNumber" property, we can increase the list level + // to begin a self-contained sub-list at the current list item. + // The Microsoft Word list template called "NumberDefault" uses numbers to create list levels for the first list level. + // Deeper list levels use letters and lowercase Roman numerals. + for (int i = 0; i < 9; i++) { + builder.getListFormat().setListLevelNumber(i); + builder.writeln("Level " + i); + } + + // 2 - A bulleted list: + // This list will apply an indent and a bullet symbol ("•") before each paragraph. + // Deeper levels of this list will use different symbols, such as "■" and "○". + builder.getListFormat().setList(doc.getLists().add(ListTemplate.BULLET_DEFAULT)); + + for (int i = 0; i < 9; i++) { + builder.getListFormat().setListLevelNumber(i); + builder.writeln("Level " + i); + } + + // We can disable list formatting to not format any subsequent paragraphs as lists by un-setting the "List" flag. + builder.getListFormat().setList(null); + + Assert.assertFalse(builder.getListFormat().isListItem()); + + doc.save(getArtifactsDir() + "Lists.SpecifyListLevel.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Lists.SpecifyListLevel.docx"); + + TestUtil.verifyListLevel("\u0000.", 18.0d, NumberStyle.ARABIC, doc.getLists().get(0).getListLevels().get(0)); + } + + @Test + public void nestedLists() throws Exception { + //ExStart + //ExFor:ListFormat.List + //ExFor:ParagraphFormat.ClearFormatting + //ExFor:ParagraphFormat.DropCapPosition + //ExFor:ParagraphFormat.IsListItem + //ExFor:Paragraph.IsListItem + //ExSummary:Shows how to nest a list inside another list. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // A list allows us to organize and decorate sets of paragraphs with prefix symbols and indents. + // We can create nested lists by increasing the indent level. + // We can begin and end a list by using a document builder's "ListFormat" property. + // Each paragraph that we add between a list's start and the end will become an item in the list. + // Create an outline list for the headings. + List outlineList = doc.getLists().add(ListTemplate.OUTLINE_NUMBERS); + builder.getListFormat().setList(outlineList); + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + builder.writeln("This is my Chapter 1"); + + // Create a numbered list. + List numberedList = doc.getLists().add(ListTemplate.NUMBER_DEFAULT); + builder.getListFormat().setList(numberedList); + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.NORMAL); + builder.writeln("Numbered list item 1."); + + // Every paragraph that comprises a list will have this flag. + Assert.assertTrue(builder.getCurrentParagraph().isListItem()); + Assert.assertTrue(builder.getParagraphFormat().isListItem()); + + // Create a bulleted list. + List bulletedList = doc.getLists().add(ListTemplate.BULLET_DEFAULT); + builder.getListFormat().setList(bulletedList); + builder.getParagraphFormat().setLeftIndent(72.0); + builder.writeln("Bulleted list item 1."); + builder.writeln("Bulleted list item 2."); + builder.getParagraphFormat().clearFormatting(); + + // Revert to the numbered list. + builder.getListFormat().setList(numberedList); + builder.writeln("Numbered list item 2."); + builder.writeln("Numbered list item 3."); + + // Revert to the outline list. + builder.getListFormat().setList(outlineList); + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + builder.writeln("This is my Chapter 2"); + + builder.getParagraphFormat().clearFormatting(); + + builder.getDocument().save(getArtifactsDir() + "Lists.NestedLists.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Lists.NestedLists.docx"); + + TestUtil.verifyListLevel("\u0000)", 0.0d, NumberStyle.ARABIC, doc.getLists().get(0).getListLevels().get(0)); + TestUtil.verifyListLevel("\u0000.", 18.0d, NumberStyle.ARABIC, doc.getLists().get(1).getListLevels().get(0)); + TestUtil.verifyListLevel("\uf0b7", 18.0d, NumberStyle.BULLET, doc.getLists().get(2).getListLevels().get(0)); + } + + @Test + public void createCustomList() throws Exception { + //ExStart + //ExFor:List + //ExFor:List.ListLevels + //ExFor:ListFormat.ListLevel + //ExFor:ListLevelCollection + //ExFor:ListLevelCollection.Item + //ExFor:ListLevel + //ExFor:ListLevel.Alignment + //ExFor:ListLevel.Font + //ExFor:ListLevel.NumberStyle + //ExFor:ListLevel.StartAt + //ExFor:ListLevel.TrailingCharacter + //ExFor:ListLevelAlignment + //ExFor:NumberStyle + //ExFor:ListTrailingCharacter + //ExFor:ListLevel.NumberFormat + //ExFor:ListLevel.NumberPosition + //ExFor:ListLevel.TextPosition + //ExFor:ListLevel.TabPosition + //ExSummary:Shows how to apply custom list formatting to paragraphs when using DocumentBuilder. + Document doc = new Document(); + + // A list allows us to organize and decorate sets of paragraphs with prefix symbols and indents. + // We can create nested lists by increasing the indent level. + // We can begin and end a list by using a document builder's "ListFormat" property. + // Each paragraph that we add between a list's start and the end will become an item in the list. + // Create a list from a Microsoft Word template, and customize the first two of its list levels. + List docList = doc.getLists().add(ListTemplate.NUMBER_DEFAULT); + + ListLevel listLevel = docList.getListLevels().get(0); + listLevel.getFont().setColor(Color.RED); + listLevel.getFont().setSize(24.0); + listLevel.setNumberStyle(NumberStyle.ORDINAL_TEXT); + listLevel.setStartAt(21); + listLevel.setNumberFormat("\u0000"); + + listLevel.setNumberPosition(-36); + listLevel.setTextPosition(144.0); + listLevel.setTabPosition(144.0); + + listLevel = docList.getListLevels().get(1); + listLevel.setAlignment(ListLevelAlignment.RIGHT); + listLevel.setNumberStyle(NumberStyle.BULLET); + listLevel.getFont().setName("Wingdings"); + listLevel.getFont().setColor(Color.BLUE); + listLevel.getFont().setSize(24.0); + + // This NumberFormat value will create star-shaped bullet list symbols. + listLevel.setNumberFormat("\uf0af"); + listLevel.setTrailingCharacter(ListTrailingCharacter.SPACE); + listLevel.setNumberPosition(144.0); + + // Create paragraphs and apply both list levels of our custom list formatting to them. + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getListFormat().setList(docList); + builder.writeln("The quick brown fox..."); + builder.writeln("The quick brown fox..."); + + builder.getListFormat().listIndent(); + builder.writeln("jumped over the lazy dog."); + builder.writeln("jumped over the lazy dog."); + + builder.getListFormat().listOutdent(); + builder.writeln("The quick brown fox..."); + + builder.getListFormat().removeNumbers(); + + builder.getDocument().save(getArtifactsDir() + "Lists.CreateCustomList.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Lists.CreateCustomList.docx"); + + listLevel = doc.getLists().get(0).getListLevels().get(0); + + TestUtil.verifyListLevel("\u0000", -36.0d, NumberStyle.ORDINAL_TEXT, listLevel); + Assert.assertEquals(Color.RED.getRGB(), listLevel.getFont().getColor().getRGB()); + Assert.assertEquals(24.0d, listLevel.getFont().getSize()); + Assert.assertEquals(21, listLevel.getStartAt()); + + listLevel = doc.getLists().get(0).getListLevels().get(1); + + TestUtil.verifyListLevel("\uf0af", 144.0d, NumberStyle.BULLET, listLevel); + Assert.assertEquals(Color.BLUE.getRGB(), listLevel.getFont().getColor().getRGB()); + Assert.assertEquals(24.0d, listLevel.getFont().getSize()); + Assert.assertEquals(1, listLevel.getStartAt()); + Assert.assertEquals(ListTrailingCharacter.SPACE, listLevel.getTrailingCharacter()); + } + + @Test + public void restartNumberingUsingListCopy() throws Exception { + //ExStart + //ExFor:List + //ExFor:ListCollection + //ExFor:ListCollection.Add(ListTemplate) + //ExFor:ListCollection.AddCopy(List) + //ExFor:ListLevel.StartAt + //ExFor:ListTemplate + //ExSummary:Shows how to restart numbering in a list by copying a list. + Document doc = new Document(); + + // A list allows us to organize and decorate sets of paragraphs with prefix symbols and indents. + // We can create nested lists by increasing the indent level. + // We can begin and end a list by using a document builder's "ListFormat" property. + // Each paragraph that we add between a list's start and the end will become an item in the list. + // Create a list from a Microsoft Word template, and customize its first list level. + List list1 = doc.getLists().add(ListTemplate.NUMBER_ARABIC_PARENTHESIS); + list1.getListLevels().get(0).getFont().setColor(Color.RED); + list1.getListLevels().get(0).setAlignment(ListLevelAlignment.RIGHT); + + // Apply our list to some paragraphs. + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("List 1 starts below:"); + builder.getListFormat().setList(list1); + builder.writeln("Item 1"); + builder.writeln("Item 2"); + builder.getListFormat().removeNumbers(); + + // We can add a copy of an existing list to the document's list collection + // to create a similar list without making changes to the original. + List list2 = doc.getLists().addCopy(list1); + list2.getListLevels().get(0).getFont().setColor(Color.BLUE); + list2.getListLevels().get(0).setStartAt(10); + + // Apply the second list to new paragraphs. + builder.writeln("List 2 starts below:"); + builder.getListFormat().setList(list2); + builder.writeln("Item 1"); + builder.writeln("Item 2"); + builder.getListFormat().removeNumbers(); + + doc.save(getArtifactsDir() + "Lists.RestartNumberingUsingListCopy.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Lists.RestartNumberingUsingListCopy.docx"); + + list1 = doc.getLists().get(0); + TestUtil.verifyListLevel("\u0000)", 18.0d, NumberStyle.ARABIC, list1.getListLevels().get(0)); + Assert.assertEquals(Color.RED.getRGB(), list1.getListLevels().get(0).getFont().getColor().getRGB()); + Assert.assertEquals(10.0d, list1.getListLevels().get(0).getFont().getSize()); + Assert.assertEquals(1, list1.getListLevels().get(0).getStartAt()); + + list2 = doc.getLists().get(1); + TestUtil.verifyListLevel("\u0000)", 18.0d, NumberStyle.ARABIC, list2.getListLevels().get(0)); + Assert.assertEquals(Color.BLUE.getRGB(), list2.getListLevels().get(0).getFont().getColor().getRGB()); + Assert.assertEquals(10.0d, list2.getListLevels().get(0).getFont().getSize()); + Assert.assertEquals(10, list2.getListLevels().get(0).getStartAt()); + } + + @Test + public void createAndUseListStyle() throws Exception { + //ExStart + //ExFor:StyleCollection.Add(StyleType,String) + //ExFor:Style.List + //ExFor:StyleType + //ExFor:List.IsListStyleDefinition + //ExFor:List.IsListStyleReference + //ExFor:List.IsMultiLevel + //ExFor:List.Style + //ExFor:ListLevelCollection + //ExFor:ListLevelCollection.Count + //ExFor:ListLevelCollection.Item + //ExFor:ListCollection.Add(Style) + //ExSummary:Shows how to create a list style and use it in a document. + Document doc = new Document(); + + // A list allows us to organize and decorate sets of paragraphs with prefix symbols and indents. + // We can create nested lists by increasing the indent level. + // We can begin and end a list by using a document builder's "ListFormat" property. + // Each paragraph that we add between a list's start and the end will become an item in the list. + // We can contain an entire List object within a style. + Style listStyle = doc.getStyles().add(StyleType.LIST, "MyListStyle"); + + List list1 = listStyle.getList(); + + Assert.assertTrue(list1.isListStyleDefinition()); + Assert.assertFalse(list1.isListStyleReference()); + Assert.assertTrue(list1.isMultiLevel()); + Assert.assertEquals(listStyle, list1.getStyle()); + + // Change the appearance of all list levels in our list. + for (ListLevel level : list1.getListLevels()) { + level.getFont().setName("Verdana"); + level.getFont().setColor(Color.BLUE); + level.getFont().setBold(true); + } + + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Using list style first time:"); + + // Create another list from a list within a style. + List list2 = doc.getLists().add(listStyle); + + Assert.assertFalse(list2.isListStyleDefinition()); + Assert.assertTrue(list2.isListStyleReference()); + Assert.assertEquals(listStyle, list2.getStyle()); + + // Add some list items that our list will format. + builder.getListFormat().setList(list2); + builder.writeln("Item 1"); + builder.writeln("Item 2"); + builder.getListFormat().removeNumbers(); + + builder.writeln("Using list style second time:"); + + // Create and apply another list based on the list style. + List list3 = doc.getLists().add(listStyle); + builder.getListFormat().setList(list3); + builder.writeln("Item 1"); + builder.writeln("Item 2"); + builder.getListFormat().removeNumbers(); + + builder.getDocument().save(getArtifactsDir() + "Lists.CreateAndUseListStyle.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Lists.CreateAndUseListStyle.docx"); + + list1 = doc.getLists().get(0); + + TestUtil.verifyListLevel("\u0000.", 18.0d, NumberStyle.ARABIC, list1.getListLevels().get(0)); + Assert.assertTrue(list1.isListStyleDefinition()); + Assert.assertFalse(list1.isListStyleReference()); + Assert.assertTrue(list1.isMultiLevel()); + Assert.assertEquals(Color.BLUE.getRGB(), list1.getListLevels().get(0).getFont().getColor().getRGB()); + Assert.assertEquals("Verdana", list1.getListLevels().get(0).getFont().getName()); + Assert.assertTrue(list1.getListLevels().get(0).getFont().getBold()); + + list2 = doc.getLists().get(1); + + TestUtil.verifyListLevel("\u0000.", 18.0d, NumberStyle.ARABIC, list2.getListLevels().get(0)); + Assert.assertFalse(list2.isListStyleDefinition()); + Assert.assertTrue(list2.isListStyleReference()); + Assert.assertTrue(list2.isMultiLevel()); + + list3 = doc.getLists().get(2); + + TestUtil.verifyListLevel("\u0000.", 18.0d, NumberStyle.ARABIC, list3.getListLevels().get(0)); + Assert.assertFalse(list3.isListStyleDefinition()); + Assert.assertTrue(list3.isListStyleReference()); + Assert.assertTrue(list3.isMultiLevel()); + } + + @Test + public void detectBulletedParagraphs() throws Exception { + //ExStart + //ExFor:Paragraph.ListFormat + //ExFor:ListFormat.IsListItem + //ExFor:CompositeNode.GetText + //ExFor:List.ListId + //ExSummary:Shows how to output all paragraphs in a document that are list items. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getListFormat().applyNumberDefault(); + builder.writeln("Numbered list item 1"); + builder.writeln("Numbered list item 2"); + builder.writeln("Numbered list item 3"); + builder.getListFormat().removeNumbers(); + + builder.getListFormat().applyBulletDefault(); + builder.writeln("Bulleted list item 1"); + builder.writeln("Bulleted list item 2"); + builder.writeln("Bulleted list item 3"); + builder.getListFormat().removeNumbers(); + + NodeCollection paras = doc.getChildNodes(NodeType.PARAGRAPH, true); + for (Paragraph para : (Iterable) paras) { + if (para.getListFormat().isListItem()) { + System.out.println(java.text.MessageFormat.format("*** A paragraph belongs to list {0}", para.getListFormat().getList().getListId())); + System.out.println(para.getText()); + } + } + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + paras = doc.getChildNodes(NodeType.PARAGRAPH, true); + + Assert.assertEquals(6, DocumentHelper.getListItemCount(paras)); + } + + @Test + public void removeBulletsFromParagraphs() throws Exception { + //ExStart + //ExFor:ListFormat.RemoveNumbers + //ExSummary:Shows how to remove list formatting from all paragraphs in the main text of a section. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getListFormat().applyNumberDefault(); + builder.writeln("Numbered list item 1"); + builder.writeln("Numbered list item 2"); + builder.writeln("Numbered list item 3"); + builder.getListFormat().removeNumbers(); + + NodeCollection paras = doc.getChildNodes(NodeType.PARAGRAPH, true); + + Assert.assertEquals(3, DocumentHelper.getListItemCount(paras)); + + for (Paragraph paragraph : doc.getFirstSection().getBody().getParagraphs()) + paragraph.getListFormat().removeNumbers(); + + paras = doc.getChildNodes(NodeType.PARAGRAPH, true); + + Assert.assertEquals(0, DocumentHelper.getListItemCount(paras)); + //ExEnd + } + + @Test + public void applyExistingListToParagraphs() throws Exception { + //ExStart + //ExFor:ListCollection.Item(Int32) + //ExSummary:Shows how to apply list formatting of an existing list to a collection of paragraphs. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Paragraph 1"); + builder.writeln("Paragraph 2"); + builder.write("Paragraph 3"); + + NodeCollection paras = doc.getChildNodes(NodeType.PARAGRAPH, true); + + Assert.assertEquals(0, DocumentHelper.getListItemCount(paras)); + + doc.getLists().add(ListTemplate.NUMBER_DEFAULT); + List docList = doc.getLists().get(0); + + for (Paragraph paragraph : doc.getFirstSection().getBody().getParagraphs()) { + paragraph.getListFormat().setList(docList); + paragraph.getListFormat().setListLevelNumber(2); + } + + paras = doc.getChildNodes(NodeType.PARAGRAPH, true); + + Assert.assertEquals(3, DocumentHelper.getListItemCount(paras)); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + paras = doc.getChildNodes(NodeType.PARAGRAPH, true); + + Assert.assertEquals(3, DocumentHelper.getListItemCount(paras)); + Assert.assertEquals(3, DocumentHelper.getListLevelNumberCount(paras, 2)); + } + + @Test + public void applyNewListToParagraphs() throws Exception { + //ExStart + //ExFor:ListCollection.Add(ListTemplate) + //ExSummary:Shows how to create a list by applying a new list format to a collection of paragraphs. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Paragraph 1"); + builder.writeln("Paragraph 2"); + builder.write("Paragraph 3"); + + NodeCollection paras = doc.getChildNodes(NodeType.PARAGRAPH, true); + + Assert.assertEquals(0, DocumentHelper.getListItemCount(paras)); + + List list = doc.getLists().add(ListTemplate.NUMBER_UPPERCASE_LETTER_DOT); + + for (Paragraph paragraph : doc.getFirstSection().getBody().getParagraphs()) { + paragraph.getListFormat().setList(list); + paragraph.getListFormat().setListLevelNumber(1); + } + + Assert.assertEquals(3, DocumentHelper.getListItemCount(paras)); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + paras = doc.getChildNodes(NodeType.PARAGRAPH, true); + + Assert.assertEquals(3, DocumentHelper.getListItemCount(paras)); + Assert.assertEquals(3, DocumentHelper.getListLevelNumberCount(paras, 1)); + } + + //ExStart + //ExFor:ListTemplate + //ExSummary:Shows how to create a document that contains all outline headings list templates. + @Test //ExSkip + public void outlineHeadingTemplates() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + List docList = doc.getLists().add(ListTemplate.OUTLINE_HEADINGS_ARTICLE_SECTION); + addOutlineHeadingParagraphs(builder, docList, "Aspose.Words Outline - \"Article Section\""); + + docList = doc.getLists().add(ListTemplate.OUTLINE_HEADINGS_LEGAL); + addOutlineHeadingParagraphs(builder, docList, "Aspose.Words Outline - \"Legal\""); + + builder.insertBreak(BreakType.PAGE_BREAK); + + docList = doc.getLists().add(ListTemplate.OUTLINE_HEADINGS_NUMBERS); + addOutlineHeadingParagraphs(builder, docList, "Aspose.Words Outline - \"Numbers\""); + + docList = doc.getLists().add(ListTemplate.OUTLINE_HEADINGS_CHAPTER); + addOutlineHeadingParagraphs(builder, docList, "Aspose.Words Outline - \"Chapters\""); + + doc.save(getArtifactsDir() + "Lists.OutlineHeadingTemplates.docx"); + testOutlineHeadingTemplates(new Document(getArtifactsDir() + "Lists.OutlineHeadingTemplates.docx")); //ExSkip + } + + private static void addOutlineHeadingParagraphs(final DocumentBuilder builder, final List docList, final String title) { + builder.getParagraphFormat().clearFormatting(); + builder.writeln(title); + + for (int i = 0; i < 9; i++) { + builder.getListFormat().setList(docList); + builder.getListFormat().setListLevelNumber(i); + + String styleName = "Heading " + (i + 1); + builder.getParagraphFormat().setStyleName(styleName); + builder.writeln(styleName); + } + + builder.getListFormat().removeNumbers(); + } + //ExEnd + + private void testOutlineHeadingTemplates(Document doc) { + List docList = doc.getLists().get(0); // Article section list template. + + TestUtil.verifyListLevel("Article \u0000.", 0.0d, NumberStyle.UPPERCASE_ROMAN, docList.getListLevels().get(0)); + TestUtil.verifyListLevel("Section \u0000.\u0001", 0.0d, NumberStyle.LEADING_ZERO, docList.getListLevels().get(1)); + TestUtil.verifyListLevel("(\u0002)", 14.4d, NumberStyle.LOWERCASE_LETTER, docList.getListLevels().get(2)); + TestUtil.verifyListLevel("(\u0003)", 36.0d, NumberStyle.LOWERCASE_ROMAN, docList.getListLevels().get(3)); + TestUtil.verifyListLevel("\u0004)", 28.8d, NumberStyle.ARABIC, docList.getListLevels().get(4)); + TestUtil.verifyListLevel("\u0005)", 36.0d, NumberStyle.LOWERCASE_LETTER, docList.getListLevels().get(5)); + TestUtil.verifyListLevel("\u0006)", 50.4d, NumberStyle.LOWERCASE_ROMAN, docList.getListLevels().get(6)); + TestUtil.verifyListLevel("\u0007.", 50.4d, NumberStyle.LOWERCASE_LETTER, docList.getListLevels().get(7)); + TestUtil.verifyListLevel("\b.", 72.0d, NumberStyle.LOWERCASE_ROMAN, docList.getListLevels().get(8)); + + docList = doc.getLists().get(1); // Legal list template. + + TestUtil.verifyListLevel("\u0000", 0.0d, NumberStyle.ARABIC, docList.getListLevels().get(0)); + TestUtil.verifyListLevel("\u0000.\u0001", 0.0d, NumberStyle.ARABIC, docList.getListLevels().get(1)); + TestUtil.verifyListLevel("\u0000.\u0001.\u0002", 0.0d, NumberStyle.ARABIC, docList.getListLevels().get(2)); + TestUtil.verifyListLevel("\u0000.\u0001.\u0002.\u0003", 0.0d, NumberStyle.ARABIC, docList.getListLevels().get(3)); + TestUtil.verifyListLevel("\u0000.\u0001.\u0002.\u0003.\u0004", 0.0d, NumberStyle.ARABIC, docList.getListLevels().get(4)); + TestUtil.verifyListLevel("\u0000.\u0001.\u0002.\u0003.\u0004.\u0005", 0.0d, NumberStyle.ARABIC, docList.getListLevels().get(5)); + TestUtil.verifyListLevel("\u0000.\u0001.\u0002.\u0003.\u0004.\u0005.\u0006", 0.0d, NumberStyle.ARABIC, docList.getListLevels().get(6)); + TestUtil.verifyListLevel("\u0000.\u0001.\u0002.\u0003.\u0004.\u0005.\u0006.\u0007", 0.0d, NumberStyle.ARABIC, docList.getListLevels().get(7)); + TestUtil.verifyListLevel("\u0000.\u0001.\u0002.\u0003.\u0004.\u0005.\u0006.\u0007.\b", 0.0d, NumberStyle.ARABIC, docList.getListLevels().get(8)); + + docList = doc.getLists().get(2); // Numbered list template. + + TestUtil.verifyListLevel("\u0000.", 0.0d, NumberStyle.UPPERCASE_ROMAN, docList.getListLevels().get(0)); + TestUtil.verifyListLevel("\u0001.", 36.0d, NumberStyle.UPPERCASE_LETTER, docList.getListLevels().get(1)); + TestUtil.verifyListLevel("\u0002.", 72.0d, NumberStyle.ARABIC, docList.getListLevels().get(2)); + TestUtil.verifyListLevel("\u0003)", 108.0d, NumberStyle.LOWERCASE_LETTER, docList.getListLevels().get(3)); + TestUtil.verifyListLevel("(\u0004)", 144.0d, NumberStyle.ARABIC, docList.getListLevels().get(4)); + TestUtil.verifyListLevel("(\u0005)", 180.0d, NumberStyle.LOWERCASE_LETTER, docList.getListLevels().get(5)); + TestUtil.verifyListLevel("(\u0006)", 216.0d, NumberStyle.LOWERCASE_ROMAN, docList.getListLevels().get(6)); + TestUtil.verifyListLevel("(\u0007)", 252.0d, NumberStyle.LOWERCASE_LETTER, docList.getListLevels().get(7)); + TestUtil.verifyListLevel("(\b)", 288.0d, NumberStyle.LOWERCASE_ROMAN, docList.getListLevels().get(8)); + + docList = doc.getLists().get(3); // Chapter list template. + + TestUtil.verifyListLevel("Chapter \u0000", 0.0d, NumberStyle.ARABIC, docList.getListLevels().get(0)); + TestUtil.verifyListLevel("", 0.0d, NumberStyle.NONE, docList.getListLevels().get(1)); + TestUtil.verifyListLevel("", 0.0d, NumberStyle.NONE, docList.getListLevels().get(2)); + TestUtil.verifyListLevel("", 0.0d, NumberStyle.NONE, docList.getListLevels().get(3)); + TestUtil.verifyListLevel("", 0.0d, NumberStyle.NONE, docList.getListLevels().get(4)); + TestUtil.verifyListLevel("", 0.0d, NumberStyle.NONE, docList.getListLevels().get(5)); + TestUtil.verifyListLevel("", 0.0d, NumberStyle.NONE, docList.getListLevels().get(6)); + TestUtil.verifyListLevel("", 0.0d, NumberStyle.NONE, docList.getListLevels().get(7)); + TestUtil.verifyListLevel("", 0.0d, NumberStyle.NONE, docList.getListLevels().get(8)); + } + + //ExStart + //ExFor:ListCollection + //ExFor:ListCollection.AddCopy(List) + //ExFor:ListCollection.GetEnumerator + //ExSummary:Shows how to create a document with a sample of all the lists from another document. + @Test //ExSkip + public void printOutAllLists() throws Exception { + Document srcDoc = new Document(getMyDir() + "Rendering.docx"); + + Document dstDoc = new Document(); + DocumentBuilder builder = new DocumentBuilder(dstDoc); + + for (List srcList : srcDoc.getLists()) { + List dstList = dstDoc.getLists().addCopy(srcList); + addListSample(builder, dstList); + } + + dstDoc.save(getArtifactsDir() + "Lists.PrintOutAllLists.docx"); + testPrintOutAllLists(srcDoc, new Document(getArtifactsDir() + "Lists.PrintOutAllLists.docx")); //ExSkip + } + + private static void addListSample(final DocumentBuilder builder, final List docList) { + builder.writeln("Sample formatting of list with ListId:" + docList.getListId()); + builder.getListFormat().setList(docList); + for (int i = 0; i < docList.getListLevels().getCount(); i++) { + builder.getListFormat().setListLevelNumber(i); + builder.writeln("Level " + i); + } + builder.getListFormat().removeNumbers(); + builder.writeln(); + } + //ExEnd + + private void testPrintOutAllLists(Document listSourceDoc, Document outDoc) { + for (List docList : outDoc.getLists()) { + for (int i = 0; i < docList.getListLevels().getCount(); i++) { + for (List sourceList : listSourceDoc.getLists()) { + if (sourceList.getListId() == docList.getListId()) { + ListLevel expectedListLevel = sourceList.getListLevels().get(i); + + Assert.assertEquals(expectedListLevel.getNumberFormat(), docList.getListLevels().get(i).getNumberFormat()); + Assert.assertEquals(expectedListLevel.getNumberPosition(), docList.getListLevels().get(i).getNumberPosition()); + Assert.assertEquals(expectedListLevel.getNumberStyle(), docList.getListLevels().get(i).getNumberStyle()); + } + } + } + } + } + + @Test + public void listDocument() throws Exception { + //ExStart + //ExFor:ListCollection.Document + //ExFor:ListCollection.Count + //ExFor:ListCollection.Item(Int32) + //ExFor:ListCollection.GetListByListId + //ExFor:List.Document + //ExFor:List.ListId + //ExSummary:Shows how to verify owner document properties of lists. + Document doc = new Document(); + + ListCollection lists = doc.getLists(); + + Assert.assertEquals(doc, lists.getDocument()); + + List docList = lists.add(ListTemplate.BULLET_DEFAULT); + Assert.assertEquals(doc, docList.getDocument()); + + System.out.println("Current list count: " + lists.getCount()); + System.out.println("Is the first document list: " + (lists.get(0).equals(docList))); + System.out.println("ListId: " + docList.getListId()); + System.out.println("List is the same by ListId: " + (lists.getListByListId(1).equals(docList))); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + lists = doc.getLists(); + + Assert.assertEquals(doc, lists.getDocument()); + Assert.assertEquals(1, lists.getCount()); + Assert.assertEquals(1, lists.get(0).getListId()); + Assert.assertEquals(lists.get(0), lists.getListByListId(1)); + } + + @Test + public void createListRestartAfterHigher() throws Exception { + //ExStart + //ExFor:ListLevel.NumberStyle + //ExFor:ListLevel.NumberFormat + //ExFor:ListLevel.IsLegal + //ExFor:ListLevel.RestartAfterLevel + //ExFor:ListLevel.LinkedStyle + //ExSummary:Shows advances ways of customizing list labels. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // A list allows us to organize and decorate sets of paragraphs with prefix symbols and indents. + // We can create nested lists by increasing the indent level. + // We can begin and end a list by using a document builder's "ListFormat" property. + // Each paragraph that we add between a list's start and the end will become an item in the list. + List docList = doc.getLists().add(ListTemplate.NUMBER_DEFAULT); + + // Level 1 labels will be formatted according to the "Heading 1" paragraph style and will have a prefix. + // These will look like "Appendix A", "Appendix B"... + docList.getListLevels().get(0).setNumberFormat("Appendix \u0000"); + docList.getListLevels().get(0).setNumberStyle(NumberStyle.UPPERCASE_LETTER); + docList.getListLevels().get(0).setLinkedStyle(doc.getStyles().get("Heading 1")); + + // Level 2 labels will display the current numbers of the first and the second list levels and have leading zeroes. + // If the first list level is at 1, then the list labels from these will look like "Section (1.01)", "Section (1.02)"... + docList.getListLevels().get(1).setNumberFormat("Section (\u0000.\u0001)"); + docList.getListLevels().get(1).setNumberStyle(NumberStyle.LEADING_ZERO); + + // Note that the higher-level uses UppercaseLetter numbering. + // We can set the "IsLegal" property to use Arabic numbers for the higher list levels. + docList.getListLevels().get(1).isLegal(true); + docList.getListLevels().get(1).setRestartAfterLevel(0); + + // Level 3 labels will be upper case Roman numerals with a prefix and a suffix and will restart at each List level 1 item. + // These list labels will look like "-I-", "-II-"... + docList.getListLevels().get(2).setNumberFormat("-\u0002-"); + docList.getListLevels().get(2).setNumberStyle(NumberStyle.UPPERCASE_ROMAN); + docList.getListLevels().get(2).setRestartAfterLevel(1); + + // Make labels of all list levels bold. + for (ListLevel level : docList.getListLevels()) + level.getFont().setBold(true); + + // Apply list formatting to the current paragraph. + builder.getListFormat().setList(docList); + + // Create list items that will display all three of our list levels. + for (int n = 0; n < 2; n++) { + for (int i = 0; i < 3; i++) { + builder.getListFormat().setListLevelNumber(i); + builder.writeln("Level " + i); + } + } + + builder.getListFormat().removeNumbers(); + + doc.save(getArtifactsDir() + "Lists.CreateListRestartAfterHigher.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Lists.CreateListRestartAfterHigher.docx"); + + ListLevel listLevel = doc.getLists().get(0).getListLevels().get(0); + + TestUtil.verifyListLevel("Appendix \u0000", 18.0d, NumberStyle.UPPERCASE_LETTER, listLevel); + Assert.assertFalse(listLevel.isLegal()); + Assert.assertEquals(-1, listLevel.getRestartAfterLevel()); + Assert.assertEquals("Heading 1", listLevel.getLinkedStyle().getName()); + + listLevel = doc.getLists().get(0).getListLevels().get(1); + + TestUtil.verifyListLevel("Section (\u0000.\u0001)", 54.0d, NumberStyle.LEADING_ZERO, listLevel); + Assert.assertTrue(listLevel.isLegal()); + Assert.assertEquals(0, listLevel.getRestartAfterLevel()); + Assert.assertNull(listLevel.getLinkedStyle()); + } + + @Test + public void getListLabels() throws Exception { + //ExStart + //ExFor:Document.UpdateListLabels() + //ExFor:Node.ToString(SaveFormat) + //ExFor:ListLabel + //ExFor:Paragraph.ListLabel + //ExFor:ListLabel.LabelValue + //ExFor:ListLabel.LabelString + //ExSummary:Shows how to extract the list labels of all paragraphs that are list items. + Document doc = new Document(getMyDir() + "Rendering.docx"); + doc.updateListLabels(); + int listParaCount = 1; + + for (Paragraph paragraph : (Iterable) doc.getChildNodes(NodeType.PARAGRAPH, true)) { + // Find if we have the paragraph list. In our document, our list uses plain Arabic numbers, + // which start at three and ends at six. + if (paragraph.getListFormat().isListItem()) { + System.out.println(MessageFormat.format("List item paragraph #{0}", listParaCount)); + + // This is the text we get when getting when we output this node to text format. + // This text output will omit list labels. Trim any paragraph formatting characters. + String paragraphText = paragraph.toString(SaveFormat.TEXT).trim(); + System.out.println("Exported Text: " + paragraphText); + + ListLabel label = paragraph.getListLabel(); + + // This gets the position of the paragraph in the current level of the list. If we have a list with multiple levels, + // this will tell us what position it is on that level. + System.out.println("\tNumerical Id: {label.LabelValue}"); + + // Combine them together to include the list label with the text in the output. + System.out.println("\tList label combined with text: {label.LabelString} {paragraphText}"); + } + //ExEnd + + Assert.assertEquals(10, DocumentHelper.getListItemCount(doc.getChildNodes(NodeType.PARAGRAPH, true))); + } + } + + @Test + public void createPictureBullet() throws Exception { + //ExStart + //ExFor:ListLevel.CreatePictureBullet + //ExFor:ListLevel.DeletePictureBullet + //ExSummary:Shows how to set a custom image icon for list item labels. + Document doc = new Document(); + + List docList = doc.getLists().add(ListTemplate.BULLET_CIRCLE); + + // Create a picture bullet for the current list level, and set an image from a local file system + // as the icon that the bullets for this list level will display. + docList.getListLevels().get(0).createPictureBullet(); + docList.getListLevels().get(0).getImageData().setImage(getImageDir() + "Logo icon.ico"); + + Assert.assertTrue(docList.getListLevels().get(0).getImageData().hasImage()); + + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getListFormat().setList(docList); + builder.writeln("Hello world!"); + builder.write("Hello again!"); + + doc.save(getArtifactsDir() + "Lists.CreatePictureBullet.docx"); + + docList.getListLevels().get(0).deletePictureBullet(); + + Assert.assertNull(docList.getListLevels().get(0).getImageData()); + //ExEnd + + doc = new Document(getArtifactsDir() + "Lists.CreatePictureBullet.docx"); + + Assert.assertTrue(doc.getLists().get(0).getListLevels().get(0).getImageData().hasImage()); + } + + @Test + public void getCustomNumberStyleFormat() throws Exception { + //ExStart + //ExFor:ListLevel.CustomNumberStyleFormat + //ExFor:ListLevel.GetEffectiveValue(Int32, NumberStyle, String) + //ExSummary:Shows how to get the format for a list with the custom number style. + Document doc = new Document(getMyDir() + "List with leading zero.docx"); + + ListLevel listLevel = doc.getFirstSection().getBody().getParagraphs().get(0).getListFormat().getListLevel(); + + String customNumberStyleFormat = ""; + + if (listLevel.getNumberStyle() == NumberStyle.CUSTOM) + customNumberStyleFormat = listLevel.getCustomNumberStyleFormat(); + + Assert.assertEquals("001, 002, 003, ...", customNumberStyleFormat); + + // We can get value for the specified index of the list item. + Assert.assertEquals("iv", ListLevel.getEffectiveValue(4, NumberStyle.LOWERCASE_ROMAN, null)); + Assert.assertEquals("005", ListLevel.getEffectiveValue(5, NumberStyle.CUSTOM, customNumberStyleFormat)); + //ExEnd + + String finalCustomNumberStyleFormat = customNumberStyleFormat; + Assert.assertThrows(IllegalArgumentException.class, () -> ListLevel.getEffectiveValue(5, NumberStyle.LOWERCASE_ROMAN, finalCustomNumberStyleFormat)); + Assert.assertThrows(IllegalArgumentException.class, () -> ListLevel.getEffectiveValue(5, NumberStyle.CUSTOM, null)); + Assert.assertThrows((IllegalArgumentException.class), () -> ListLevel.getEffectiveValue(5, NumberStyle.CUSTOM, "....")); + } + + @Test + public void hasSameTemplate() throws Exception + { + //ExStart + //ExFor:List.HasSameTemplate(List) + //ExSummary:Shows how to define lists with the same ListDefId. + Document doc = new Document(getMyDir() + "Different lists.docx"); + + Assert.assertTrue(doc.getLists().get(0).hasSameTemplate(doc.getLists().get(1))); + Assert.assertFalse(doc.getLists().get(1).hasSameTemplate(doc.getLists().get(2))); + //ExEnd + } + + @Test + public void setCustomNumberStyleFormat() throws Exception + { + //ExStart:SetCustomNumberStyleFormat + //GistId:67585b023474b7f73b0066dd022cf938 + //ExFor:ListLevel.CustomNumberStyleFormat + //ExSummary:Shows how to set customer number style format. + Document doc = new Document(getMyDir() + "List with leading zero.docx"); + + doc.updateListLabels(); + + ParagraphCollection paras = doc.getFirstSection().getBody().getParagraphs(); + Assert.assertEquals("001.", paras.get(0).getListLabel().getLabelString()); + Assert.assertEquals("0001.", paras.get(1).getListLabel().getLabelString()); + Assert.assertEquals("0002.", paras.get(2).getListLabel().getLabelString()); + + paras.get(1).getListFormat().getListLevel().setCustomNumberStyleFormat("001, 002, 003, ..."); + + doc.updateListLabels(); + + Assert.assertEquals("001.", paras.get(0).getListLabel().getLabelString()); + Assert.assertEquals("001.", paras.get(1).getListLabel().getLabelString()); + Assert.assertEquals("002.", paras.get(2).getListLabel().getLabelString()); + //ExEnd:SetCustomNumberStyleFormat + } + + @Test + public void addSingleLevelList() throws Exception + { + //ExStart:AddSingleLevelList + //GistId:8c0f38c5965151e1cdf79c1c8f9e4640 + //ExFor:ListCollection.AddSingleLevelList(ListTemplate) + //ExSummary:Shows how to create a new single level list based on the predefined template. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + ListCollection listCollection = doc.getLists(); + + // Creates the bulleted list from BulletCircle template. + List bulletedList = listCollection.addSingleLevelList(ListTemplate.BULLET_CIRCLE); + + // Writes the bulleted list to the resulting document. + builder.writeln("Bulleted list starts below:"); + builder.getListFormat().setList(bulletedList); + builder.writeln("Item 1"); + builder.writeln("Item 2"); + builder.getListFormat().removeNumbers(); + + // Creates the numbered list from NumberUppercaseLetterDot template. + List numberedList = listCollection.addSingleLevelList(ListTemplate.NUMBER_UPPERCASE_LETTER_DOT); + + // Writes the numbered list to the resulting document. + builder.writeln("Numbered list starts below:"); + builder.getListFormat().setList(numberedList); + builder.writeln("Item 1"); + builder.writeln("Item 2"); + + doc.save(getArtifactsDir() + "Lists.AddSingleLevelList.docx"); + //ExEnd:AddSingleLevelList + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExLoadOptions.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExLoadOptions.java new file mode 100644 index 00000000..e0437cff --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExLoadOptions.java @@ -0,0 +1,419 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.pdf.TextAbsorber; +import com.aspose.words.*; +import org.apache.commons.io.FileUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +public class ExLoadOptions extends ApiExampleBase { + //ExStart + //ExFor:LoadOptions.ResourceLoadingCallback + //ExSummary:Shows how to handle external resources when loading Html documents. + @Test //ExSkip + public void loadOptionsCallback() throws Exception { + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setResourceLoadingCallback(new HtmlLinkedResourceLoadingCallback()); + + // When we load the document, our callback will handle linked resources such as CSS stylesheets and images. + Document doc = new Document(getMyDir() + "Images.html", loadOptions); + doc.save(getArtifactsDir() + "LoadOptions.LoadOptionsCallback.pdf"); + } + + /// + /// Prints the filenames of all external stylesheets and substitutes all images of a loaded html document. + /// + private static class HtmlLinkedResourceLoadingCallback implements IResourceLoadingCallback { + public int resourceLoading(ResourceLoadingArgs args) throws IOException { + switch (args.getResourceType()) { + case ResourceType.CSS_STYLE_SHEET: + System.out.println(MessageFormat.format("External CSS Stylesheet found upon loading: {0}", args.getOriginalUri())); + return ResourceLoadingAction.DEFAULT; + case ResourceType.IMAGE: + System.out.println(MessageFormat.format("External Image found upon loading: {0}", args.getOriginalUri())); + + final String newImageFilename = "Logo.jpg"; + System.out.println(MessageFormat.format("\tImage will be substituted with: {0}", newImageFilename)); + + byte[] imageBytes = FileUtils.readFileToByteArray(new File(getImageDir() + newImageFilename)); + args.setData(imageBytes); + + return ResourceLoadingAction.USER_PROVIDED; + } + + return ResourceLoadingAction.DEFAULT; + } + } + //ExEnd + + @Test(dataProvider = "convertShapeToOfficeMathDataProvider") + public void convertShapeToOfficeMath(boolean isConvertShapeToOfficeMath) throws Exception { + //ExStart + //ExFor:LoadOptions.ConvertShapeToOfficeMath + //ExSummary:Shows how to convert EquationXML shapes to Office Math objects. + LoadOptions loadOptions = new LoadOptions(); + + // Use this flag to specify whether to convert the shapes with EquationXML attributes + // to Office Math objects and then load the document. + loadOptions.setConvertShapeToOfficeMath(isConvertShapeToOfficeMath); + + Document doc = new Document(getMyDir() + "Math shapes.docx", loadOptions); + + if (isConvertShapeToOfficeMath) { + Assert.assertEquals(16, doc.getChildNodes(NodeType.SHAPE, true).getCount()); + Assert.assertEquals(34, doc.getChildNodes(NodeType.OFFICE_MATH, true).getCount()); + } else { + Assert.assertEquals(24, doc.getChildNodes(NodeType.SHAPE, true).getCount()); + Assert.assertEquals(0, doc.getChildNodes(NodeType.OFFICE_MATH, true).getCount()); + } + //ExEnd + } + + @DataProvider(name = "convertShapeToOfficeMathDataProvider") + public static Object[][] convertShapeToOfficeMathDataProvider() { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test + public void setEncoding() throws Exception + { + //ExStart + //ExFor:LoadOptions.Encoding + //ExSummary:Shows how to set the encoding with which to open a document. + LoadOptions loadOptions = new LoadOptions(); + { + loadOptions.setEncoding(StandardCharsets.US_ASCII); + } + + // Load the document while passing the LoadOptions object, then verify the document's contents. + Document doc = new Document(getMyDir() + "English text.txt", loadOptions); + + Assert.assertTrue(doc.toString(SaveFormat.TEXT).contains("This is a sample text in English.")); + //ExEnd + } + + @Test + public void fontSettings() throws Exception + { + //ExStart + //ExFor:LoadOptions.FontSettings + //ExSummary:Shows how to apply font substitution settings while loading a document. + // Create a FontSettings object that will substitute the "Times New Roman" font + // with the font "Arvo" from our "MyFonts" folder. + FontSettings fontSettings = new FontSettings(); + fontSettings.setFontsFolder(getFontsDir(), false); + fontSettings.getSubstitutionSettings().getTableSubstitution().addSubstitutes("Times New Roman", "Arvo"); + + // Set that FontSettings object as a property of a newly created LoadOptions object. + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setFontSettings(fontSettings); + + // Load the document, then render it as a PDF with the font substitution. + Document doc = new Document(getMyDir() + "Document.docx", loadOptions); + + doc.save(getArtifactsDir() + "LoadOptions.FontSettings.pdf"); + //ExEnd + } + + @Test + public void loadOptionsMswVersion() throws Exception { + //ExStart + //ExFor:LoadOptions.MswVersion + //ExSummary:Shows how to emulate the loading procedure of a specific Microsoft Word version during document loading. + // By default, Aspose.Words load documents according to Microsoft Word 2019 specification. + LoadOptions loadOptions = new LoadOptions(); + + Assert.assertEquals(MsWordVersion.WORD_2019, loadOptions.getMswVersion()); + + // This document is missing the default paragraph formatting style. + // This default style will be regenerated when we load the document either with Microsoft Word or Aspose.Words. + loadOptions.setMswVersion(MsWordVersion.WORD_2007); + Document doc = new Document(getMyDir() + "Document.docx", loadOptions); + + // The style's line spacing will have this value when loaded by Microsoft Word 2007 specification. + Assert.assertEquals(12.95d, doc.getStyles().getDefaultParagraphFormat().getLineSpacing(), 0.01d); + //ExEnd + } + + //ExStart + //ExFor:LoadOptions.WarningCallback + //ExSummary:Shows how to print and store warnings that occur during document loading. + @Test //ExSkip + public void loadOptionsWarningCallback() throws Exception { + // Create a new LoadOptions object and set its WarningCallback attribute + // as an instance of our IWarningCallback implementation. + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setWarningCallback(new DocumentLoadingWarningCallback()); + + // Our callback will print all warnings that come up during the load operation. + Document doc = new Document(getMyDir() + "Document.docx", loadOptions); + + ArrayList warnings = ((DocumentLoadingWarningCallback) loadOptions.getWarningCallback()).getWarnings(); + Assert.assertEquals(3, warnings.size()); + testLoadOptionsWarningCallback(warnings); //ExSkip + } + + /// + /// IWarningCallback that prints warnings and their details as they arise during document loading. + /// + private static class DocumentLoadingWarningCallback implements IWarningCallback { + public void warning(WarningInfo info) { + System.out.println(MessageFormat.format("Warning: {0}", info.getWarningType())); + System.out.println(MessageFormat.format("\tSource: {0}", info.getSource())); + System.out.println(MessageFormat.format("\tDescription: {0}", info.getDescription())); + mWarnings.add(info); + } + + public ArrayList getWarnings() { + return mWarnings; + } + + private final /*final*/ ArrayList mWarnings = new ArrayList(); + } + //ExEnd + + private static void testLoadOptionsWarningCallback(ArrayList warnings) { + Assert.assertEquals(WarningType.UNEXPECTED_CONTENT, warnings.get(0).getWarningType()); + Assert.assertEquals(WarningSource.DOCX, warnings.get(0).getSource()); + Assert.assertEquals("3F01", warnings.get(0).getDescription()); + + Assert.assertEquals(WarningType.MINOR_FORMATTING_LOSS, warnings.get(1).getWarningType()); + Assert.assertEquals(WarningSource.DOCX, warnings.get(1).getSource()); + Assert.assertEquals("Import of element 'shapedefaults' is not supported in Docx format by Aspose.Words.", warnings.get(1).getDescription()); + + Assert.assertEquals(WarningType.MINOR_FORMATTING_LOSS, warnings.get(2).getWarningType()); + Assert.assertEquals(WarningSource.DOCX, warnings.get(2).getSource()); + Assert.assertEquals("Import of element 'extraClrSchemeLst' is not supported in Docx format by Aspose.Words.", warnings.get(2).getDescription()); + } + + @Test + public void tempFolder() throws Exception { + //ExStart + //ExFor:LoadOptions.TempFolder + //ExSummary:Shows how to use the hard drive instead of memory when loading a document. + // When we load a document, various elements are temporarily stored in memory as the save operation occurs. + // We can use this option to use a temporary folder in the local file system instead, + // which will reduce our application's memory overhead. + LoadOptions options = new LoadOptions(); + options.setTempFolder(getArtifactsDir() + "TempFiles"); + + // The specified temporary folder must exist in the local file system before the load operation. + Files.createDirectory(Paths.get(options.getTempFolder())); + + Document doc = new Document(getMyDir() + "Document.docx", options); + + // The folder will persist with no residual contents from the load operation. + Assert.assertTrue(DocumentHelper.directoryGetFiles(options.getTempFolder(), "*.*").size() == 0); + //ExEnd + } + + @Test + public void addEditingLanguage() throws Exception { + //ExStart + //ExFor:LanguagePreferences + //ExFor:LanguagePreferences.AddEditingLanguage(EditingLanguage) + //ExFor:LoadOptions.LanguagePreferences + //ExFor:EditingLanguage + //ExSummary:Shows how to apply language preferences when loading a document. + LoadOptions loadOptions = new LoadOptions(); + loadOptions.getLanguagePreferences().addEditingLanguage(EditingLanguage.JAPANESE); + + Document doc = new Document(getMyDir() + "No default editing language.docx", loadOptions); + + int localeIdFarEast = doc.getStyles().getDefaultFont().getLocaleIdFarEast(); + System.out.println(localeIdFarEast == EditingLanguage.JAPANESE + ? "The document either has no any FarEast language set in defaults or it was set to Japanese originally." + : "The document default FarEast language was set to another than Japanese language originally, so it is not overridden."); + //ExEnd + + Assert.assertEquals(EditingLanguage.JAPANESE, doc.getStyles().getDefaultFont().getLocaleIdFarEast()); + + doc = new Document(getMyDir() + "No default editing language.docx"); + + Assert.assertEquals(EditingLanguage.ENGLISH_US, doc.getStyles().getDefaultFont().getLocaleIdFarEast()); + } + + @Test + public void setEditingLanguageAsDefault() throws Exception { + //ExStart + //ExFor:LanguagePreferences.DefaultEditingLanguage + //ExSummary:Shows how set a default language when loading a document. + LoadOptions loadOptions = new LoadOptions(); + loadOptions.getLanguagePreferences().setDefaultEditingLanguage(EditingLanguage.RUSSIAN); + + Document doc = new Document(getMyDir() + "No default editing language.docx", loadOptions); + + int localeId = doc.getStyles().getDefaultFont().getLocaleId(); + System.out.println(localeId == EditingLanguage.RUSSIAN + ? "The document either has no any language set in defaults or it was set to Russian originally." + : "The document default language was set to another than Russian language originally, so it is not overridden."); + //ExEnd + + Assert.assertEquals(EditingLanguage.RUSSIAN, doc.getStyles().getDefaultFont().getLocaleId()); + + doc = new Document(getMyDir() + "No default editing language.docx"); + + Assert.assertEquals(EditingLanguage.ENGLISH_US, doc.getStyles().getDefaultFont().getLocaleId()); + } + + @Test + public void convertMetafilesToPng() throws Exception { + //ExStart + //ExFor:LoadOptions.ConvertMetafilesToPng + //ExSummary:Shows how to convert WMF/EMF to PNG during loading document. + Document doc = new Document(); + + Shape shape = new Shape(doc, ShapeType.IMAGE); + shape.getImageData().setImage(getImageDir() + "Windows MetaFile.wmf"); + shape.setWidth(100.0); + shape.setHeight(100.0); + + doc.getFirstSection().getBody().getFirstParagraph().appendChild(shape); + + doc.save(getArtifactsDir() + "Image.CreateImageDirectly.docx"); + + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(1600, 1600, ImageType.WMF, shape); + + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setConvertMetafilesToPng(true); + + doc = new Document(getArtifactsDir() + "Image.CreateImageDirectly.docx", loadOptions); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(1600, 1600, ImageType.PNG, shape); + //ExEnd + } + + @Test + public void openChmFile() throws Exception { + FileFormatInfo info = FileFormatUtil.detectFileFormat(getMyDir() + "HTML help.chm"); + Assert.assertEquals(info.getLoadFormat(), LoadFormat.CHM); + + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setEncoding(Charset.forName("Windows-1251")); + + Document doc = new Document(getMyDir() + "HTML help.chm", loadOptions); + } + + //ExStart + //ExFor:LoadOptions.ProgressCallback + //ExFor:IDocumentLoadingCallback + //ExFor:IDocumentLoadingCallback.Notify + //ExFor:DocumentLoadingArgs + //ExFor:DocumentLoadingArgs.EstimatedProgress + //ExSummary:Shows how to notify the user if document loading exceeded expected loading time. + @Test//ExSkip + public void progressCallback() throws Exception + { + LoadingProgressCallback progressCallback = new LoadingProgressCallback(); + + LoadOptions loadOptions = new LoadOptions(); { loadOptions.setProgressCallback(progressCallback); } + + try + { + new Document(getMyDir() + "Big document.docx", loadOptions); + } + catch (IllegalStateException exception) + { + System.out.println(exception.getMessage()); + // Handle loading duration issue. + } + } + + /// + /// Cancel a document loading after the "MaxDuration" seconds. + /// + public static class LoadingProgressCallback implements IDocumentLoadingCallback + { + /// + /// Ctr. + /// + public LoadingProgressCallback() + { + mLoadingStartedAt = new Date(); + } + + /// + /// Callback method which called during document loading. + /// + /// Loading arguments. + public void notify(DocumentLoadingArgs args) + { + Date canceledAt = new Date(); + long diff = canceledAt.getTime() - mLoadingStartedAt.getTime(); + long ellapsedSeconds = TimeUnit.MILLISECONDS.toSeconds(diff); + + if (ellapsedSeconds > MAX_DURATION) + throw new IllegalStateException(MessageFormat.format("EstimatedProgress = {0}; CanceledAt = {1}", args.getEstimatedProgress(), canceledAt)); + } + + /// + /// Date and time when document loading is started. + /// + private Date mLoadingStartedAt; + + /// + /// Maximum allowed duration in sec. + /// + private static final double MAX_DURATION = 0.5; + } + //ExEnd + + @Test + public void ignoreOleData() throws Exception + { + //ExStart + //ExFor:LoadOptions.IgnoreOleData + //ExSummary:Shows how to ingore OLE data while loading. + // Ignoring OLE data may reduce memory consumption and increase performance + // without data lost in a case when destination format does not support OLE objects. + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setIgnoreOleData(true); + Document doc = new Document(getMyDir() + "OLE objects.docx", loadOptions); + + doc.save(getArtifactsDir() + "LoadOptions.IgnoreOleData.docx"); + //ExEnd + } + + @Test + public void recoveryMode() throws Exception + { + //ExStart:RecoveryMode + //GistId:045648ef22da6b384ebcf0344717bfb5 + //ExFor:LoadOptions.RecoveryMode + //ExFor:DocumentRecoveryMode + //ExSummary:Shows how to try to recover a document if errors occurred during loading. + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setRecoveryMode(DocumentRecoveryMode.TRY_RECOVER); + + Document doc = new Document(getMyDir() + "Corrupted footnotes.docx", loadOptions); + //ExEnd:RecoveryMode + } +} + diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExLowCode.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExLowCode.java new file mode 100644 index 00000000..53b12ccc --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExLowCode.java @@ -0,0 +1,2298 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import com.aspose.words.net.System.Data.DataRow; +import com.aspose.words.net.System.Data.DataSet; +import com.aspose.words.net.System.Data.DataTable; +import org.testng.Assert; +import org.testng.annotations.Test; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Date; +import java.util.regex.Pattern; +import java.util.stream.Stream; + +public class ExLowCode extends ApiExampleBase { + @Test + public void mergeDocuments() throws Exception { + //ExStart + //ExFor:Merger.Merge(String, String[]) + //ExFor:Merger.Merge(String[], MergeFormatMode) + //ExFor:Merger.Merge(String[], LoadOptions[], MergeFormatMode) + //ExFor:Merger.Merge(String, String[], SaveOptions, MergeFormatMode) + //ExFor:Merger.Merge(String, String[], SaveFormat, MergeFormatMode) + //ExFor:Merger.Merge(String, String[], LoadOptions[], SaveOptions, MergeFormatMode) + //ExFor:LowCode.MergeFormatMode + //ExFor:LowCode.Merger + //ExSummary:Shows how to merge documents into a single output document. + //There is a several ways to merge documents: + String inputDoc1 = getMyDir() + "Big document.docx"; + String inputDoc2 = getMyDir() + "Tables.docx"; + + Merger.merge(getArtifactsDir() + "LowCode.MergeDocument.1.docx", new String[]{inputDoc1, inputDoc2}); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + { + saveOptions.setPassword("Aspose.Words"); + } + Merger.merge(getArtifactsDir() + "LowCode.MergeDocument.2.docx", new String[]{inputDoc1, inputDoc2}, saveOptions, MergeFormatMode.KEEP_SOURCE_FORMATTING); + + Merger.merge(getArtifactsDir() + "LowCode.MergeDocument.3.pdf", new String[]{inputDoc1, inputDoc2}, SaveFormat.PDF, MergeFormatMode.KEEP_SOURCE_LAYOUT); + + LoadOptions firstLoadOptions = new LoadOptions(); + { + firstLoadOptions.setIgnoreOleData(true); + } + LoadOptions secondLoadOptions = new LoadOptions(); + { + secondLoadOptions.setIgnoreOleData(false); + } + Merger.merge(getArtifactsDir() + "LowCode.MergeDocument.4.docx", new String[]{inputDoc1, inputDoc2}, new LoadOptions[]{firstLoadOptions, secondLoadOptions}, + saveOptions, MergeFormatMode.KEEP_SOURCE_FORMATTING); + + Document doc = Merger.merge(new String[]{inputDoc1, inputDoc2}, MergeFormatMode.MERGE_FORMATTING); + doc.save(getArtifactsDir() + "LowCode.MergeDocument.5.docx"); + + doc = Merger.merge(new String[]{inputDoc1, inputDoc2}, new LoadOptions[]{firstLoadOptions, secondLoadOptions}, MergeFormatMode.MERGE_FORMATTING); + doc.save(getArtifactsDir() + "LowCode.MergeDocument.6.docx"); + //ExEnd + } + + @Test + public void mergeContextDocuments() throws Exception { + //ExStart:MergeContextDocuments + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Processor + //ExFor:Processor.From(String, LoadOptions) + //ExFor:Processor.To(String, SaveOptions) + //ExFor:Processor.To(String, SaveFormat) + //ExFor:Processor.Execute + //ExFor:Merger.Create(MergerContext) + //ExFor:MergerContext + //ExSummary:Shows how to merge documents into a single output document using context. + //There is a several ways to merge documents: + String inputDoc1 = getMyDir() + "Big document.docx"; + String inputDoc2 = getMyDir() + "Tables.docx"; + + MergerContext mergerContext = new MergerContext(); + mergerContext.setMergeFormatMode(MergeFormatMode.KEEP_SOURCE_FORMATTING); + + Merger.create(mergerContext) + .from(inputDoc1) + .from(inputDoc2) + .to(getArtifactsDir() + "LowCode.MergeContextDocuments.1.docx") + .execute(); + + LoadOptions firstLoadOptions = new LoadOptions(); + { + firstLoadOptions.setIgnoreOleData(true); + } + LoadOptions secondLoadOptions = new LoadOptions(); + { + secondLoadOptions.setIgnoreOleData(false); + } + Merger.create(mergerContext) + .from(inputDoc1, firstLoadOptions) + .from(inputDoc2, secondLoadOptions) + .to(getArtifactsDir() + "LowCode.MergeContextDocuments.2.docx", SaveFormat.DOCX) + .execute(); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + { + saveOptions.setPassword("Aspose.Words"); + } + Merger.create(mergerContext) + .from(inputDoc1) + .from(inputDoc2) + .to(getArtifactsDir() + "LowCode.MergeContextDocuments.3.docx", saveOptions) + .execute(); + //ExEnd:MergeContextDocuments + } + + @Test + public void mergeStreamDocument() throws Exception { + //ExStart + //ExFor:Merger.Merge(Stream[], MergeFormatMode) + //ExFor:Merger.Merge(Stream[], LoadOptions[], MergeFormatMode) + //ExFor:Merger.Merge(Stream, Stream[], SaveOptions, MergeFormatMode) + //ExFor:Merger.Merge(Stream, Stream[], LoadOptions[], SaveOptions, MergeFormatMode) + //ExFor:Merger.Merge(Stream, Stream[], SaveFormat) + //ExSummary:Shows how to merge documents from stream into a single output document. + //There is a several ways to merge documents from stream: + try (FileInputStream firstStreamIn = new FileInputStream(getMyDir() + "Big document.docx")) { + try (FileInputStream secondStreamIn = new FileInputStream(getMyDir() + "Tables.docx")) { + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + { + saveOptions.setPassword("Aspose.Words"); + } + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.MergeStreamDocument.1.docx")) { + Merger.merge(streamOut, new FileInputStream[]{firstStreamIn, secondStreamIn}, saveOptions, MergeFormatMode.KEEP_SOURCE_FORMATTING); + } + + try (FileOutputStream streamOut1 = new FileOutputStream(getArtifactsDir() + "LowCode.MergeStreamDocument.2.docx")) { + Merger.merge(streamOut1, new FileInputStream[]{firstStreamIn, secondStreamIn}, SaveFormat.DOCX); + } + + LoadOptions firstLoadOptions = new LoadOptions(); + { + firstLoadOptions.setIgnoreOleData(true); + } + LoadOptions secondLoadOptions = new LoadOptions(); + { + secondLoadOptions.setIgnoreOleData(false); + } + try (FileOutputStream streamOut2 = new FileOutputStream(getArtifactsDir() + "LowCode.MergeStreamDocument.3.docx")) { + Merger.merge(streamOut2, new FileInputStream[]{firstStreamIn, secondStreamIn}, new LoadOptions[]{firstLoadOptions, secondLoadOptions}, saveOptions, MergeFormatMode.KEEP_SOURCE_FORMATTING); + } + + Document firstDoc = Merger.merge(new FileInputStream[]{firstStreamIn, secondStreamIn}, MergeFormatMode.MERGE_FORMATTING); + firstDoc.save(getArtifactsDir() + "LowCode.MergeStreamDocument.4.docx"); + + Document secondDoc = Merger.merge(new FileInputStream[]{firstStreamIn, secondStreamIn}, new LoadOptions[]{firstLoadOptions, secondLoadOptions}, MergeFormatMode.MERGE_FORMATTING); + secondDoc.save(getArtifactsDir() + "LowCode.MergeStreamDocument.5.docx"); + } + } + //ExEnd + } + + @Test + public void mergeStreamContextDocuments() throws Exception { + //ExStart:MergeStreamContextDocuments + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Processor + //ExFor:Processor.From(Stream, LoadOptions) + //ExFor:Processor.To(Stream, SaveFormat) + //ExFor:Processor.To(Stream, SaveOptions) + //ExFor:Processor.Execute + //ExFor:Merger.Create(MergerContext) + //ExFor:MergerContext + //ExSummary:Shows how to merge documents from stream into a single output document using context. + //There is a several ways to merge documents: + String inputDoc1 = getMyDir() + "Big document.docx"; + String inputDoc2 = getMyDir() + "Tables.docx"; + + MergerContext mergerContext = new MergerContext(); + mergerContext.setMergeFormatMode(MergeFormatMode.KEEP_SOURCE_FORMATTING); + + try (FileInputStream firstStreamIn = new FileInputStream(inputDoc1)) { + try (FileInputStream secondStreamIn = new FileInputStream(inputDoc2)) { + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + { + saveOptions.setPassword("Aspose.Words"); + } + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.MergeStreamContextDocuments.1.docx")) { + Merger.create(mergerContext) + .from(firstStreamIn) + .from(secondStreamIn) + .to(streamOut, saveOptions) + .execute(); + } + + LoadOptions firstLoadOptions = new LoadOptions(); + { + firstLoadOptions.setIgnoreOleData(true); + } + LoadOptions secondLoadOptions = new LoadOptions(); + { + secondLoadOptions.setIgnoreOleData(false); + } + try (FileOutputStream streamOut1 = new FileOutputStream(getArtifactsDir() + "LowCode.MergeStreamContextDocuments.2.docx")) { + Merger.create(mergerContext) + .from(firstStreamIn, firstLoadOptions) + .from(secondStreamIn, secondLoadOptions) + .to(streamOut1, SaveFormat.DOCX) + .execute(); + } + } + } + //ExEnd:MergeStreamContextDocuments + } + + @Test + public void mergeDocumentInstances() throws Exception { + //ExStart:MergeDocumentInstances + //GistId:f0964b777330b758f6b82330b040b24c + //ExFor:Merger.Merge(Document[], MergeFormatMode) + //ExSummary:Shows how to merge input documents to a single document instance. + DocumentBuilder firstDoc = new DocumentBuilder(); + firstDoc.getFont().setSize(16.0); + firstDoc.getFont().setColor(Color.BLUE); + firstDoc.write("Hello first word!"); + + DocumentBuilder secondDoc = new DocumentBuilder(); + secondDoc.write("Hello second word!"); + + Document mergedDoc = Merger.merge(new Document[]{firstDoc.getDocument(), secondDoc.getDocument()}, MergeFormatMode.KEEP_SOURCE_LAYOUT); + Assert.assertEquals("Hello first word!\fHello second word!\f", mergedDoc.getText()); + //ExEnd:MergeDocumentInstances + } + + @Test + public void convert() throws Exception { + //ExStart:Convert + //GistId:0ede368e82d1e97d02e615a76923846b + //ExFor:Converter.Convert(String, String) + //ExFor:Converter.Convert(String, String, SaveFormat) + //ExFor:Converter.Convert(String, String, SaveOptions) + //ExFor:Converter.Convert(String, LoadOptions, String, SaveOptions) + //ExSummary:Shows how to convert documents with a single line of code. + String doc = getMyDir() + "Document.docx"; + + Converter.convert(doc, getArtifactsDir() + "LowCode.Convert.pdf"); + + Converter.convert(doc, getArtifactsDir() + "LowCode.Convert.SaveFormat.rtf", SaveFormat.RTF); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + { + saveOptions.setPassword("Aspose.Words"); + } + LoadOptions loadOptions = new LoadOptions(); + { + loadOptions.setIgnoreOleData(true); + } + Converter.convert(doc, loadOptions, getArtifactsDir() + "LowCode.Convert.LoadOptions.docx", saveOptions); + + Converter.convert(doc, getArtifactsDir() + "LowCode.Convert.SaveOptions.docx", saveOptions); + //ExEnd:Convert + } + + @Test + public void convertContext() throws Exception { + //ExStart:ConvertContext + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Processor + //ExFor:Processor.From(String, LoadOptions) + //ExFor:Processor.To(String, SaveOptions) + //ExFor:Processor.Execute + //ExFor:Converter.Create(ConverterContext) + //ExFor:ConverterContext + //ExSummary:Shows how to convert documents with a single line of code using context. + String doc = getMyDir() + "Big document.docx"; + + ConverterContext converterContext = new ConverterContext(); + + Converter.create(converterContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.ConvertContext.1.pdf") + .execute(); + + Converter.create(converterContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.ConvertContext.2.pdf", SaveFormat.RTF) + .execute(); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + { + saveOptions.setPassword("Aspose.Words"); + } + LoadOptions loadOptions = new LoadOptions(); + { + loadOptions.setIgnoreOleData(true); + } + Converter.create(converterContext) + .from(doc, loadOptions) + .to(getArtifactsDir() + "LowCode.ConvertContext.3.docx", saveOptions) + .execute(); + + Converter.create(converterContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.ConvertContext.4.png", new ImageSaveOptions(SaveFormat.PNG)) + .execute(); + //ExEnd:ConvertContext + } + + @Test + public void convertStream() throws Exception { + //ExStart:ConvertStream + //GistId:0ede368e82d1e97d02e615a76923846b + //ExFor:Converter.Convert(Stream, Stream, SaveFormat) + //ExFor:Converter.Convert(Stream, Stream, SaveOptions) + //ExFor:Converter.Convert(Stream, LoadOptions, Stream, SaveOptions) + //ExSummary:Shows how to convert documents with a single line of code (Stream). + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Big document.docx")) { + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.ConvertStream.1.docx")) { + Converter.convert(streamIn, streamOut, SaveFormat.DOCX); + } + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + { + saveOptions.setPassword("Aspose.Words"); + } + LoadOptions loadOptions = new LoadOptions(); + { + loadOptions.setIgnoreOleData(true); + } + try (FileOutputStream streamOut1 = new FileOutputStream(getArtifactsDir() + "LowCode.ConvertStream.2.docx")) { + Converter.convert(streamIn, loadOptions, streamOut1, saveOptions); + } + + try (FileOutputStream streamOut2 = new FileOutputStream(getArtifactsDir() + "LowCode.ConvertStream.3.docx")) { + Converter.convert(streamIn, streamOut2, saveOptions); + } + } + //ExEnd:ConvertStream + } + + @Test + public void convertContextStream() throws Exception { + //ExStart:ConvertContextStream + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Processor + //ExFor:Processor.From(Stream, LoadOptions) + //ExFor:Processor.To(Stream, SaveFormat) + //ExFor:Processor.To(Stream, SaveOptions) + //ExFor:Processor.Execute + //ExFor:Converter.Create(ConverterContext) + //ExFor:ConverterContext + //ExSummary:Shows how to convert documents from a stream with a single line of code using context. + String doc = getMyDir() + "Document.docx"; + ConverterContext converterContext = new ConverterContext(); + + try (FileInputStream streamIn = new FileInputStream(doc)) { + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.ConvertContextStream.1.docx")) { + Converter.create(converterContext) + .from(streamIn) + .to(streamOut, SaveFormat.RTF) + .execute(); + } + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + { + saveOptions.setPassword("Aspose.Words"); + } + LoadOptions loadOptions = new LoadOptions(); + { + loadOptions.setIgnoreOleData(true); + } + try (FileOutputStream streamOut1 = new FileOutputStream(getArtifactsDir() + "LowCode.ConvertContextStream.2.docx")) { + Converter.create(converterContext) + .from(streamIn, loadOptions) + .to(streamOut1, saveOptions) + .execute(); + } + } + //ExEnd:ConvertContextStream + } + + @Test + public void convertToImages() throws Exception { + //ExStart:ConvertToImages + //GistId:0ede368e82d1e97d02e615a76923846b + //ExFor:Converter.ConvertToImages(String, String) + //ExFor:Converter.ConvertToImages(String, String, SaveFormat) + //ExFor:Converter.ConvertToImages(String, String, ImageSaveOptions) + //ExFor:Converter.ConvertToImages(String, LoadOptions, String, ImageSaveOptions) + //ExSummary:Shows how to convert document to images. + String doc = getMyDir() + "Big document.docx"; + + Converter.convertToImages(doc, getArtifactsDir() + "LowCode.ConvertToImages.1.png"); + + Converter.convertToImages(doc, getArtifactsDir() + "LowCode.ConvertToImages.2.jpeg", SaveFormat.JPEG); + + LoadOptions loadOptions = new LoadOptions(); + { + loadOptions.setIgnoreOleData(false); + } + ImageSaveOptions imageSaveOptions = new ImageSaveOptions(SaveFormat.PNG); + imageSaveOptions.setPageSet(new PageSet(1)); + Converter.convertToImages(doc, loadOptions, getArtifactsDir() + "LowCode.ConvertToImages.3.png", imageSaveOptions); + + Converter.convertToImages(doc, getArtifactsDir() + "LowCode.ConvertToImages.4.png", imageSaveOptions); + //ExEnd:ConvertToImages + } + + @Test + public void convertToImagesStream() throws Exception { + //ExStart:ConvertToImagesStream + //GistId:0ede368e82d1e97d02e615a76923846b + //ExFor:Converter.ConvertToImages(String, SaveFormat) + //ExFor:Converter.ConvertToImages(String, ImageSaveOptions) + //ExFor:Converter.ConvertToImages(Document, SaveFormat) + //ExFor:Converter.ConvertToImages(Document, ImageSaveOptions) + //ExSummary:Shows how to convert document to images stream. + String doc = getMyDir() + "Big document.docx"; + + OutputStream[] streams = Converter.convertToImages(doc, SaveFormat.PNG); + + ImageSaveOptions imageSaveOptions = new ImageSaveOptions(SaveFormat.PNG); + imageSaveOptions.setPageSet(new PageSet(1)); + streams = Converter.convertToImages(doc, imageSaveOptions); + + streams = Converter.convertToImages(new Document(doc), SaveFormat.PNG); + + streams = Converter.convertToImages(new Document(doc), imageSaveOptions); + //ExEnd:ConvertToImagesStream + } + + @Test + public void convertToImagesFromStream() throws Exception { + //ExStart:ConvertToImagesFromStream + //GistId:0ede368e82d1e97d02e615a76923846b + //ExFor:Converter.ConvertToImages(Stream, SaveFormat) + //ExFor:Converter.ConvertToImages(Stream, ImageSaveOptions) + //ExFor:Converter.ConvertToImages(Stream, LoadOptions, ImageSaveOptions) + //ExSummary:Shows how to convert document to images from stream. + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Big document.docx")) { + OutputStream[] streams = Converter.convertToImages(streamIn, SaveFormat.JPEG); + + ImageSaveOptions imageSaveOptions = new ImageSaveOptions(SaveFormat.PNG); + imageSaveOptions.setPageSet(new PageSet(1)); + streams = Converter.convertToImages(streamIn, imageSaveOptions); + + LoadOptions loadOptions = new LoadOptions(); + { + loadOptions.setIgnoreOleData(false); + } + Converter.convertToImages(streamIn, loadOptions, imageSaveOptions); + } + //ExEnd:ConvertToImagesFromStream + } + + @Test + public void compareDocuments() throws Exception { + //ExStart:CompareDocuments + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:Comparer.Compare(String, String, String, String, DateTime, CompareOptions) + //ExFor:Comparer.Compare(String, String, String, SaveFormat, String, DateTime, CompareOptions) + //ExSummary:Shows how to simple compare documents. + // There is a several ways to compare documents: + String firstDoc = getMyDir() + "Table column bookmarks.docx"; + String secondDoc = getMyDir() + "Table column bookmarks.doc"; + + Comparer.compare(firstDoc, secondDoc, getArtifactsDir() + "LowCode.CompareDocuments.1.docx", "Author", new Date()); + Comparer.compare(firstDoc, secondDoc, getArtifactsDir() + "LowCode.CompareDocuments.2.docx", SaveFormat.DOCX, "Author", new Date()); + CompareOptions options = new CompareOptions(); + options.setIgnoreCaseChanges(true); + Comparer.compare(firstDoc, secondDoc, getArtifactsDir() + "LowCode.CompareDocuments.3.docx", "Author", new Date(), options); + Comparer.compare(firstDoc, secondDoc, getArtifactsDir() + "LowCode.CompareDocuments.4.docx", SaveFormat.DOCX, "Author", new Date(), options); + //ExEnd:CompareDocuments + } + + @Test + public void compareContextDocuments() throws Exception { + //ExStart:CompareContextDocuments + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Comparer.Create(ComparerContext) + //ExFor:ComparerContext + //ExFor:ComparerContext.CompareOptions + //ExSummary:Shows how to simple compare documents using context. + // There is a several ways to compare documents: + String firstDoc = getMyDir() + "Table column bookmarks.docx"; + String secondDoc = getMyDir() + "Table column bookmarks.doc"; + + ComparerContext comparerContext = new ComparerContext(); + comparerContext.getCompareOptions().setIgnoreCaseChanges(true); + comparerContext.setAuthor("Author"); + comparerContext.setDateTime(new Date()); + + Comparer.create(comparerContext) + .from(firstDoc) + .from(secondDoc) + .to(getArtifactsDir() + "LowCode.CompareContextDocuments.docx") + .execute(); + //ExEnd:CompareContextDocuments + } + + @Test + public void compareStreamDocuments() throws Exception { + //ExStart:CompareStreamDocuments + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:Comparer.Compare(Stream, Stream, Stream, SaveFormat, String, DateTime, CompareOptions) + //ExSummary:Shows how to compare documents from the stream. + // There is a several ways to compare documents from the stream: + try (FileInputStream firstStreamIn = new FileInputStream(getMyDir() + "Table column bookmarks.docx")) { + try (FileInputStream secondStreamIn = new FileInputStream(getMyDir() + "Table column bookmarks.doc")) { + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.CompareStreamDocuments.1.docx")) { + Comparer.compare(firstStreamIn, secondStreamIn, streamOut, SaveFormat.DOCX, "Author", new Date()); + } + + try (FileOutputStream streamOut1 = new FileOutputStream(getArtifactsDir() + "LowCode.CompareStreamDocuments.2.docx")) { + CompareOptions options = new CompareOptions(); + options.setIgnoreCaseChanges(true); + Comparer.compare(firstStreamIn, secondStreamIn, streamOut1, SaveFormat.DOCX, "Author", new Date(), options); + } + } + } + //ExEnd:CompareStreamDocuments + } + + @Test + public void compareContextStreamDocuments() throws Exception { + //ExStart:CompareContextStreamDocuments + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Comparer.Create(ComparerContext) + //ExFor:ComparerContext + //ExFor:ComparerContext.CompareOptions + //ExSummary:Shows how to compare documents from the stream using context. + // There is a several ways to compare documents from the stream: + try (FileInputStream firstStreamIn = new FileInputStream(getMyDir() + "Table column bookmarks.docx")) { + try (FileInputStream secondStreamIn = new FileInputStream(getMyDir() + "Table column bookmarks.doc")) { + ComparerContext comparerContext = new ComparerContext(); + comparerContext.getCompareOptions().setIgnoreCaseChanges(true); + comparerContext.setAuthor("Author"); + comparerContext.setDateTime(new Date()); + + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.CompareContextStreamDocuments.docx")) { + Comparer.create(comparerContext) + .from(firstStreamIn) + .from(secondStreamIn) + .to(streamOut, SaveFormat.DOCX) + .execute(); + } + } + } + //ExEnd:CompareContextStreamDocuments + } + + @Test + public void compareDocumentsToimages() throws Exception { + //ExStart:CompareDocumentsToimages + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Comparer.CompareToImages(Stream, Stream, ImageSaveOptions, String, DateTime, CompareOptions) + //ExSummary:Shows how to compare documents and save results as images. + // There is a several ways to compare documents: + String firstDoc = getMyDir() + "Table column bookmarks.docx"; + String secondDoc = getMyDir() + "Table column bookmarks.doc"; + + OutputStream[] pages = Comparer.compareToImages(firstDoc, secondDoc, new ImageSaveOptions(SaveFormat.PNG), "Author", new Date()); + + try (FileInputStream firstStreamIn = new FileInputStream(firstDoc)) { + try (FileInputStream secondStreamIn = new FileInputStream(secondDoc)) { + CompareOptions compareOptions = new CompareOptions(); + compareOptions.setIgnoreCaseChanges(true); + pages = Comparer.compareToImages(firstStreamIn, secondStreamIn, new ImageSaveOptions(SaveFormat.PNG), "Author", new Date(), compareOptions); + } + } + //ExEnd:CompareDocumentsToimages + } + + @Test + public void mailMerge() throws Exception { + //ExStart:MailMerge + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:MailMergeOptions + //ExFor:MailMergeOptions.TrimWhitespaces + //ExFor:MailMerger.Execute(String, String, String[], Object[]) + //ExFor:MailMerger.Execute(String, String, SaveFormat, String[], Object[], MailMergeOptions) + //ExSummary:Shows how to do mail merge operation for a single record. + // There is a several ways to do mail merge operation: + String doc = getMyDir() + "Mail merge.doc"; + + String[] fieldNames = new String[]{"FirstName", "Location", "SpecialCharsInName()"}; + String[] fieldValues = new String[]{"James Bond", "London", "Classified"}; + + MailMerger.execute(doc, getArtifactsDir() + "LowCode.MailMerge.1.docx", fieldNames, fieldValues); + MailMerger.execute(doc, getArtifactsDir() + "LowCode.MailMerge.2.docx", SaveFormat.DOCX, fieldNames, fieldValues); + MailMergeOptions options = new MailMergeOptions(); + options.setTrimWhitespaces(true); + MailMerger.execute(doc, getArtifactsDir() + "LowCode.MailMerge.3.docx", SaveFormat.DOCX, fieldNames, fieldValues, options); + //ExEnd:MailMerge + } + + @Test + public void mailMergeContext() throws Exception { + //ExStart:MailMergeContext + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:MailMerger.Create(MailMergerContext) + //ExFor:MailMergerContext + //ExFor:MailMergerContext.SetSimpleDataSource(String[], Object[]) + //ExFor:MailMergerContext.MailMergeOptions + //ExSummary:Shows how to do mail merge operation for a single record using context. + // There is a several ways to do mail merge operation: + String doc = getMyDir() + "Mail merge.doc"; + + String[] fieldNames = new String[]{"FirstName", "Location", "SpecialCharsInName()"}; + String[] fieldValues = new String[]{"James Bond", "London", "Classified"}; + + MailMergerContext mailMergerContext = new MailMergerContext(); + mailMergerContext.setSimpleDataSource(fieldNames, fieldValues); + mailMergerContext.getMailMergeOptions().setTrimWhitespaces(true); + + MailMerger.create(mailMergerContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.MailMergeContext.docx") + .execute(); + //ExEnd:MailMergeContext + } + + @Test + public void mailMergeToImages() throws Exception { + //ExStart:MailMergeToImages + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:MailMerger.ExecuteToImages(String, ImageSaveOptions, String[], Object[], MailMergeOptions) + //ExSummary:Shows how to do mail merge operation for a single record and save result to images. + // There is a several ways to do mail merge operation: + String doc = getMyDir() + "Mail merge.doc"; + + String[] fieldNames = new String[]{"FirstName", "Location", "SpecialCharsInName()"}; + String[] fieldValues = new String[]{"James Bond", "London", "Classified"}; + + OutputStream[] images = MailMerger.executeToImages(doc, new ImageSaveOptions(SaveFormat.PNG), fieldNames, fieldValues); + MailMergeOptions mailMergeOptions = new MailMergeOptions(); + mailMergeOptions.setTrimWhitespaces(true); + images = MailMerger.executeToImages(doc, new ImageSaveOptions(SaveFormat.PNG), fieldNames, fieldValues, mailMergeOptions); + //ExEnd:MailMergeToImages + } + + @Test + public void mailMergeStream() throws Exception { + //ExStart:MailMergeStream + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:MailMerger.Execute(Stream, Stream, SaveFormat, String[], Object[], MailMergeOptions) + //ExSummary:Shows how to do mail merge operation for a single record from the stream. + // There is a several ways to do mail merge operation using documents from the stream: + String[] fieldNames = new String[]{"FirstName", "Location", "SpecialCharsInName()"}; + String[] fieldValues = new String[]{"James Bond", "London", "Classified"}; + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Mail merge.doc")) { + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.MailMergeStream.1.docx")) { + MailMerger.execute(streamIn, streamOut, SaveFormat.DOCX, fieldNames, fieldValues); + } + + try (FileOutputStream streamOut1 = new FileOutputStream(getArtifactsDir() + "LowCode.MailMergeStream.2.docx")) { + MailMergeOptions options = new MailMergeOptions(); + options.setTrimWhitespaces(true); + MailMerger.execute(streamIn, streamOut1, SaveFormat.DOCX, fieldNames, fieldValues, options); + } + } + //ExEnd:MailMergeStream + } + + @Test + public void mailMergeContextStream() throws Exception { + //ExStart:MailMergeContextStream + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:MailMerger.Create(MailMergerContext) + //ExFor:MailMergerContext + //ExFor:MailMergerContext.SetSimpleDataSource(String[], Object[]) + //ExFor:MailMergerContext.MailMergeOptions + //ExSummary:Shows how to do mail merge operation for a single record from the stream using context. + // There is a several ways to do mail merge operation using documents from the stream: + String[] fieldNames = new String[]{"FirstName", "Location", "SpecialCharsInName()"}; + String[] fieldValues = new String[]{"James Bond", "London", "Classified"}; + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Mail merge.doc")) { + MailMergerContext mailMergerContext = new MailMergerContext(); + mailMergerContext.setSimpleDataSource(fieldNames, fieldValues); + mailMergerContext.getMailMergeOptions().setTrimWhitespaces(true); + + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.MailMergeContextStream.docx")) { + MailMerger.create(mailMergerContext) + .from(streamIn) + .to(streamOut, SaveFormat.DOCX) + .execute(); + } + } + //ExEnd:MailMergeContextStream + } + + @Test + public void mailMergeStreamToImages() throws Exception { + //ExStart:MailMergeStreamToImages + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:MailMerger.ExecuteToImages(Stream, ImageSaveOptions, String[], Object[], MailMergeOptions) + //ExSummary:Shows how to do mail merge operation for a single record from the stream and save result to images. + // There is a several ways to do mail merge operation using documents from the stream: + String[] fieldNames = new String[]{"FirstName", "Location", "SpecialCharsInName()"}; + String[] fieldValues = new String[]{"James Bond", "London", "Classified"}; + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Mail merge.doc")) { + OutputStream[] images = MailMerger.executeToImages(streamIn, new ImageSaveOptions(SaveFormat.PNG), fieldNames, fieldValues); + + MailMergeOptions mailMergeOptions = new MailMergeOptions(); + mailMergeOptions.setTrimWhitespaces(true); + images = MailMerger.executeToImages(streamIn, new ImageSaveOptions(SaveFormat.PNG), fieldNames, fieldValues, mailMergeOptions); + } + //ExEnd:MailMergeStreamToImages + } + + @Test + public void mailMergeDataRow() throws Exception { + //ExStart:MailMergeDataRow + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:MailMerger.Execute(String, String, DataRow) + //ExFor:MailMerger.Execute(String, String, SaveFormat, DataRow, MailMergeOptions) + //ExSummary:Shows how to do mail merge operation from a DataRow. + // There is a several ways to do mail merge operation from a DataRow: + String doc = getMyDir() + "Mail merge.doc"; + + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + dataTable.getRows().add(new String[]{"James Bond", "London", "Classified"}); + DataRow dataRow = dataTable.getRows().get(0); + + MailMerger.execute(doc, getArtifactsDir() + "LowCode.MailMergeDataRow.1.docx", dataRow); + MailMerger.execute(doc, getArtifactsDir() + "LowCode.MailMergeDataRow.2.docx", SaveFormat.DOCX, dataRow); + MailMergeOptions options = new MailMergeOptions(); + options.setTrimWhitespaces(true); + MailMerger.execute(doc, getArtifactsDir() + "LowCode.MailMergeDataRow.3.docx", SaveFormat.DOCX, dataRow, options); + //ExEnd:MailMergeDataRow + } + + @Test + public void mailMergeContextDataRow() throws Exception { + //ExStart:MailMergeContextDataRow + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:MailMerger.Create(MailMergerContext) + //ExFor:MailMergerContext + //ExFor:MailMergerContext.SetSimpleDataSource(DataRow) + //ExSummary:Shows how to do mail merge operation from a DataRow using context. + // There is a several ways to do mail merge operation from a DataRow: + String doc = getMyDir() + "Mail merge.doc"; + + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + dataTable.getRows().add(new String[]{"James Bond", "London", "Classified"}); + DataRow dataRow = dataTable.getRows().get(0); + + MailMergerContext mailMergerContext = new MailMergerContext(); + mailMergerContext.setSimpleDataSource(dataRow); + mailMergerContext.getMailMergeOptions().setTrimWhitespaces(true); + + MailMerger.create(mailMergerContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.MailMergeContextDataRow.docx") + .execute(); + //ExEnd:MailMergeContextDataRow + } + + @Test + public void mailMergeToImagesDataRow() throws Exception { + //ExStart:MailMergeToImagesDataRow + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:MailMerger.ExecuteToImages(String, ImageSaveOptions, DataRow, MailMergeOptions) + //ExSummary:Shows how to do mail merge operation from a DataRow and save result to images. + // There is a several ways to do mail merge operation from a DataRow: + String doc = getMyDir() + "Mail merge.doc"; + + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + dataTable.getRows().add(new String[]{"James Bond", "London", "Classified"}); + DataRow dataRow = dataTable.getRows().get(0); + + OutputStream[] images = MailMerger.executeToImages(doc, new ImageSaveOptions(SaveFormat.PNG), dataRow); + MailMergeOptions options = new MailMergeOptions(); + options.setTrimWhitespaces(true); + images = MailMerger.executeToImages(doc, new ImageSaveOptions(SaveFormat.PNG), dataRow, options); + //ExEnd:MailMergeToImagesDataRow + } + + @Test + public void mailMergeStreamDataRow() throws Exception { + //ExStart:MailMergeStreamDataRow + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:MailMerger.Execute(Stream, Stream, SaveFormat, DataRow, MailMergeOptions) + //ExSummary:Shows how to do mail merge operation from a DataRow using documents from the stream. + // There is a several ways to do mail merge operation from a DataRow using documents from the stream: + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + dataTable.getRows().add(new String[]{"James Bond", "London", "Classified"}); + DataRow dataRow = dataTable.getRows().get(0); + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Mail merge.doc")) { + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.MailMergeStreamDataRow.1.docx")) + { + MailMerger.execute(streamIn, streamOut, SaveFormat.DOCX, dataRow); + } + + try (FileOutputStream streamOut1 = new FileOutputStream(getArtifactsDir() + "LowCode.MailMergeStreamDataRow.2.docx")) + { + MailMergeOptions options = new MailMergeOptions(); + options.setTrimWhitespaces(true); + MailMerger.execute(streamIn, streamOut1, SaveFormat.DOCX, dataRow, options); + } + } + //ExEnd:MailMergeStreamDataRow + } + + @Test + public void mailMergeContextStreamDataRow() throws Exception { + //ExStart:MailMergeContextStreamDataRow + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:MailMerger.Create(MailMergerContext) + //ExFor:MailMergerContext + //ExFor:MailMergerContext.SetSimpleDataSource(DataRow) + //ExSummary:Shows how to do mail merge operation from a DataRow using documents from the stream using context. + // There is a several ways to do mail merge operation from a DataRow using documents from the stream: + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + dataTable.getRows().add(new String[]{"James Bond", "London", "Classified"}); + DataRow dataRow = dataTable.getRows().get(0); + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Mail merge.doc")) { + MailMergerContext mailMergerContext = new MailMergerContext(); + mailMergerContext.setSimpleDataSource(dataRow); + mailMergerContext.getMailMergeOptions().setTrimWhitespaces(true); + + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.MailMergeContextStreamDataRow.docx")) { + MailMerger.create(mailMergerContext) + .from(streamIn) + .to(streamOut, SaveFormat.DOCX) + .execute(); + } + } + //ExEnd:MailMergeContextStreamDataRow + } + + @Test + public void mailMergeStreamToImagesDataRow() throws Exception { + //ExStart:MailMergeStreamToImagesDataRow + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:MailMerger.ExecuteToImages(Stream, ImageSaveOptions, DataRow, MailMergeOptions) + //ExSummary:Shows how to do mail merge operation from a DataRow using documents from the stream and save result to images. + // There is a several ways to do mail merge operation from a DataRow using documents from the stream: + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + dataTable.getRows().add(new String[]{"James Bond", "London", "Classified"}); + DataRow dataRow = dataTable.getRows().get(0); + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Mail merge.doc")) { + OutputStream[] images = MailMerger.executeToImages(streamIn, new ImageSaveOptions(SaveFormat.PNG), dataRow); + MailMergeOptions options = new MailMergeOptions(); + options.setTrimWhitespaces(true); + images = MailMerger.executeToImages(streamIn, new ImageSaveOptions(SaveFormat.PNG), dataRow, options); + } + //ExEnd:MailMergeStreamToImagesDataRow + } + + @Test + public void mailMergeDataTable() throws Exception { + //ExStart:MailMergeDataTable + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:MailMerger.Execute(String, String, DataTable) + //ExFor:MailMerger.Execute(String, String, SaveFormat, DataTable, MailMergeOptions) + //ExSummary:Shows how to do mail merge operation from a DataTable. + // There is a several ways to do mail merge operation from a DataTable: + String doc = getMyDir() + "Mail merge.doc"; + + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + dataTable.getRows().add(new String[]{"James Bond", "London", "Classified"}); + + MailMerger.execute(doc, getArtifactsDir() + "LowCode.MailMergeDataTable.1.docx", dataTable); + MailMerger.execute(doc, getArtifactsDir() + "LowCode.MailMergeDataTable.2.docx", SaveFormat.DOCX, dataTable); + MailMergeOptions options = new MailMergeOptions(); + options.setTrimWhitespaces(true); + MailMerger.execute(doc, getArtifactsDir() + "LowCode.MailMergeDataTable.3.docx", SaveFormat.DOCX, dataTable, options); + //ExEnd:MailMergeDataTable + } + + @Test + public void mailMergeContextDataTable() throws Exception { + //ExStart:MailMergeContextDataTable + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:MailMerger.Create(MailMergerContext) + //ExFor:MailMergerContext + //ExFor:MailMergerContext.SetSimpleDataSource(DataTable) + //ExSummary:Shows how to do mail merge operation from a DataTable using context. + // There is a several ways to do mail merge operation from a DataTable: + String doc = getMyDir() + "Mail merge.doc"; + + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + dataTable.getRows().add(new String[]{"James Bond", "London", "Classified"}); + + MailMergerContext mailMergerContext = new MailMergerContext(); + mailMergerContext.setSimpleDataSource(dataTable); + mailMergerContext.getMailMergeOptions().setTrimWhitespaces(true); + + MailMerger.create(mailMergerContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.MailMergeContextDataTable.docx") + .execute(); + //ExEnd:MailMergeContextDataTable + } + + @Test + public void mailMergeToImagesDataTable() throws Exception { + //ExStart:MailMergeToImagesDataTable + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:MailMerger.ExecuteToImages(String, ImageSaveOptions, DataTable, MailMergeOptions) + //ExSummary:Shows how to do mail merge operation from a DataTable and save result to images. + // There is a several ways to do mail merge operation from a DataTable: + String doc = getMyDir() + "Mail merge.doc"; + + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + dataTable.getRows().add(new String[]{"James Bond", "London", "Classified"}); + + OutputStream[] images = MailMerger.executeToImages(doc, new ImageSaveOptions(SaveFormat.PNG), dataTable); + MailMergeOptions options = new MailMergeOptions(); + options.setTrimWhitespaces(true); + images = MailMerger.executeToImages(doc, new ImageSaveOptions(SaveFormat.PNG), dataTable, options); + //ExEnd:MailMergeToImagesDataTable + } + + @Test + public void mailMergeStreamDataTable() throws Exception { + //ExStart:MailMergeStreamDataTable + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:MailMerger.Execute(Stream, Stream, SaveFormat, DataTable, MailMergeOptions) + //ExSummary:Shows how to do mail merge operation from a DataTable using documents from the stream. + // There is a several ways to do mail merge operation from a DataTable using documents from the stream: + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + dataTable.getRows().add(new String[]{"James Bond", "London", "Classified"}); + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Mail merge.doc")) { + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.MailMergeDataTable.1.docx")) { + MailMerger.execute(streamIn, streamOut, SaveFormat.DOCX, dataTable); + } + + try (FileOutputStream streamOut1 = new FileOutputStream(getArtifactsDir() + "LowCode.MailMergeDataTable.2.docx")) { + MailMergeOptions options = new MailMergeOptions(); + options.setTrimWhitespaces(true); + MailMerger.execute(streamIn, streamOut1, SaveFormat.DOCX, dataTable, options); + } + } + //ExEnd:MailMergeStreamDataTable + } + + @Test + public void mailMergeContextStreamDataTable() throws Exception { + //ExStart:MailMergeContextStreamDataTable + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Processor + //ExFor:MailMerger.Create(MailMergerContext) + //ExFor:MailMergerContext + //ExFor:MailMergerContext.SetSimpleDataSource(DataTable) + //ExSummary:Shows how to do mail merge operation from a DataTable using documents from the stream using context. + // There is a several ways to do mail merge operation from a DataTable using documents from the stream: + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + dataTable.getRows().add(new String[]{"James Bond", "London", "Classified"}); + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Mail merge.doc")) { + MailMergerContext mailMergerContext = new MailMergerContext(); + mailMergerContext.setSimpleDataSource(dataTable); + mailMergerContext.getMailMergeOptions().setTrimWhitespaces(true); + + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.MailMergeContextStreamDataTable.docx")) { + MailMerger.create(mailMergerContext) + .from(streamIn) + .to(streamOut, SaveFormat.DOCX) + .execute(); + } + } + //ExEnd:MailMergeContextStreamDataTable + } + + @Test + public void mailMergeStreamToImagesDataTable() throws Exception { + //ExStart:MailMergeStreamToImagesDataTable + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:MailMerger.ExecuteToImages(Stream, ImageSaveOptions, DataTable, MailMergeOptions) + //ExSummary:Shows how to do mail merge operation from a DataTable using documents from the stream and save to images. + // There is a several ways to do mail merge operation from a DataTable using documents from the stream and save result to images: + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + dataTable.getRows().add(new String[]{"James Bond", "London", "Classified"}); + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Mail merge.doc")) { + OutputStream[] images = MailMerger.executeToImages(streamIn, new ImageSaveOptions(SaveFormat.PNG), dataTable); + MailMergeOptions options = new MailMergeOptions(); + options.setTrimWhitespaces(true); + images = MailMerger.executeToImages(streamIn, new ImageSaveOptions(SaveFormat.PNG), dataTable, options); + } + //ExEnd:MailMergeStreamToImagesDataTable + } + + @Test + public void mailMergeWithRegionsDataTable() throws Exception { + //ExStart:MailMergeWithRegionsDataTable + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:MailMerger.ExecuteWithRegions(String, String, DataTable) + //ExFor:MailMerger.ExecuteWithRegions(String, String, SaveFormat, DataTable, MailMergeOptions) + //ExSummary:Shows how to do mail merge with regions operation from a DataTable. + // There is a several ways to do mail merge with regions operation from a DataTable: + String doc = getMyDir() + "Mail merge with regions.docx"; + + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("LastName"); + dataTable.getRows().add(new Object[]{"John", "Doe"}); + dataTable.getRows().add(new Object[]{"", ""}); + dataTable.getRows().add(new Object[]{"Jane", "Doe"}); + + MailMerger.executeWithRegions(doc, getArtifactsDir() + "LowCode.MailMergeWithRegionsDataTable.1.docx", dataTable); + MailMerger.executeWithRegions(doc, getArtifactsDir() + "LowCode.MailMergeWithRegionsDataTable.2.docx", SaveFormat.DOCX, dataTable); + MailMergeOptions options = new MailMergeOptions(); + options.setTrimWhitespaces(true); + MailMerger.executeWithRegions(doc, getArtifactsDir() + "LowCode.MailMergeWithRegionsDataTable.3.docx", SaveFormat.DOCX, dataTable, options); + //ExEnd:MailMergeWithRegionsDataTable + } + + @Test + public void mailMergeContextWithRegionsDataTable() throws Exception { + //ExStart:MailMergeContextWithRegionsDataTable + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:MailMerger.Create(MailMergerContext) + //ExFor:MailMergerContext + //ExFor:MailMergerContext.SetRegionsDataSource(DataTable) + //ExSummary:Shows how to do mail merge with regions operation from a DataTable using context. + // There is a several ways to do mail merge with regions operation from a DataTable: + String doc = getMyDir() + "Mail merge with regions.docx"; + + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("LastName"); + dataTable.getRows().add(new Object[]{"John", "Doe"}); + dataTable.getRows().add(new Object[]{"", ""}); + dataTable.getRows().add(new Object[]{"Jane", "Doe"}); + + MailMergerContext mailMergerContext = new MailMergerContext(); + mailMergerContext.setRegionsDataSource(dataTable); + mailMergerContext.getMailMergeOptions().setTrimWhitespaces(true); + + MailMerger.create(mailMergerContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.MailMergeContextWithRegionsDataTable.docx") + .execute(); + //ExEnd:MailMergeContextWithRegionsDataTable + } + + @Test + public void mailMergeWithRegionsToImagesDataTable() throws Exception { + //ExStart:MailMergeWithRegionsToImagesDataTable + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:MailMerger.ExecuteWithRegionsToImages(String, ImageSaveOptions, DataTable, MailMergeOptions) + //ExSummary:Shows how to do mail merge with regions operation from a DataTable and save result to images. + // There is a several ways to do mail merge with regions operation from a DataTable: + String doc = getMyDir() + "Mail merge with regions.docx"; + + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("LastName"); + dataTable.getRows().add(new Object[]{"John", "Doe"}); + dataTable.getRows().add(new Object[]{"", ""}); + dataTable.getRows().add(new Object[]{"Jane", "Doe"}); + + OutputStream[] images = MailMerger.executeWithRegionsToImages(doc, new ImageSaveOptions(SaveFormat.PNG), dataTable); + MailMergeOptions options = new MailMergeOptions(); + options.setTrimWhitespaces(true); + images = MailMerger.executeWithRegionsToImages(doc, new ImageSaveOptions(SaveFormat.PNG), dataTable, options); + //ExEnd:MailMergeWithRegionsToImagesDataTable + } + + @Test + public void mailMergeStreamWithRegionsDataTable() throws Exception { + //ExStart:MailMergeStreamWithRegionsDataTable + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:MailMerger.ExecuteWithRegions(Stream, Stream, SaveFormat, DataTable, MailMergeOptions) + //ExSummary:Shows how to do mail merge with regions operation from a DataTable using documents from the stream. + // There is a several ways to do mail merge with regions operation from a DataTable using documents from the stream: + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("LastName"); + dataTable.getRows().add(new Object[]{"John", "Doe"}); + dataTable.getRows().add(new Object[]{"", ""}); + dataTable.getRows().add(new Object[]{"Jane", "Doe"}); + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Mail merge.doc")) { + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.MailMergeStreamWithRegionsDataTable.1.docx")) { + MailMerger.executeWithRegions(streamIn, streamOut, SaveFormat.DOCX, dataTable); + } + + try (FileOutputStream streamOut1 = new FileOutputStream(getArtifactsDir() + "LowCode.MailMergeStreamWithRegionsDataTable.2.docx")) { + MailMergeOptions options = new MailMergeOptions(); + options.setTrimWhitespaces(true); + MailMerger.executeWithRegions(streamIn, streamOut1, SaveFormat.DOCX, dataTable, options); + } + } + //ExEnd:MailMergeStreamWithRegionsDataTable + } + + @Test + public void mailMergeContextStreamWithRegionsDataTable() throws Exception { + //ExStart:MailMergeContextStreamWithRegionsDataTable + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:MailMerger.Create(MailMergerContext) + //ExFor:MailMergerContext + //ExFor:MailMergerContext.SetRegionsDataSource(DataTable) + //ExSummary:Shows how to do mail merge with regions operation from a DataTable using documents from the stream using context. + // There is a several ways to do mail merge with regions operation from a DataTable using documents from the stream: + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("LastName"); + dataTable.getRows().add(new Object[]{"John", "Doe"}); + dataTable.getRows().add(new Object[]{"", ""}); + dataTable.getRows().add(new Object[]{"Jane", "Doe"}); + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Mail merge.doc")) { + MailMergerContext mailMergerContext = new MailMergerContext(); + mailMergerContext.setRegionsDataSource(dataTable); + mailMergerContext.getMailMergeOptions().setTrimWhitespaces(true); + + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.MailMergeContextStreamWithRegionsDataTable.docx")) { + MailMerger.create(mailMergerContext) + .from(streamIn) + .to(streamOut, SaveFormat.DOCX) + .execute(); + } + } + //ExEnd:MailMergeContextStreamWithRegionsDataTable + } + + @Test + public void mailMergeStreamWithRegionsToImagesDataTable() throws Exception { + //ExStart:MailMergeStreamWithRegionsToImagesDataTable + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:MailMerger.ExecuteWithRegionsToImages(Stream, ImageSaveOptions, DataTable, MailMergeOptions) + //ExSummary:Shows how to do mail merge with regions operation from a DataTable using documents from the stream and save result to images. + // There is a several ways to do mail merge with regions operation from a DataTable using documents from the stream: + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("LastName"); + dataTable.getRows().add(new Object[]{"John", "Doe"}); + dataTable.getRows().add(new Object[]{"", ""}); + dataTable.getRows().add(new Object[]{"Jane", "Doe"}); + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Mail merge.doc")) { + OutputStream[] images = MailMerger.executeWithRegionsToImages(streamIn, new ImageSaveOptions(SaveFormat.PNG), dataTable); + MailMergeOptions options = new MailMergeOptions(); + options.setTrimWhitespaces(true); + images = MailMerger.executeWithRegionsToImages(streamIn, new ImageSaveOptions(SaveFormat.PNG), dataTable, options); + } + //ExEnd:MailMergeStreamWithRegionsToImagesDataTable + } + + @Test + public void mailMergeWithRegionsDataSet() throws Exception { + //ExStart:MailMergeWithRegionsDataSet + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:MailMerger.ExecuteWithRegions(String, String, DataSet) + //ExFor:MailMerger.ExecuteWithRegions(String, String, SaveFormat, DataSet, MailMergeOptions) + //ExSummary:Shows how to do mail merge with regions operation from a DataSet. + // There is a several ways to do mail merge with regions operation from a DataSet: + String doc = getMyDir() + "Mail merge with regions data set.docx"; + + DataTable tableCustomers = new DataTable("Customers"); + tableCustomers.getColumns().add("CustomerID"); + tableCustomers.getColumns().add("CustomerName"); + tableCustomers.getRows().add(new Object[]{1, "John Doe"}); + tableCustomers.getRows().add(new Object[]{2, "Jane Doe"}); + + DataTable tableOrders = new DataTable("Orders"); + tableOrders.getColumns().add("CustomerID"); + tableOrders.getColumns().add("ItemName"); + tableOrders.getColumns().add("Quantity"); + tableOrders.getRows().add(new Object[]{1, "Hawaiian", 2}); + tableOrders.getRows().add(new Object[]{2, "Pepperoni", 1}); + tableOrders.getRows().add(new Object[]{2, "Chicago", 1}); + + DataSet dataSet = new DataSet(); + dataSet.getTables().add(tableCustomers); + dataSet.getTables().add(tableOrders); + dataSet.getRelations().add(tableCustomers.getColumns().get("CustomerID"), tableOrders.getColumns().get("CustomerID")); + + MailMerger.executeWithRegions(doc, getArtifactsDir() + "LowCode.MailMergeWithRegionsDataSet.1.docx", dataSet); + MailMerger.executeWithRegions(doc, getArtifactsDir() + "LowCode.MailMergeWithRegionsDataSet.2.docx", SaveFormat.DOCX, dataSet); + MailMergeOptions options = new MailMergeOptions(); + options.setTrimWhitespaces(true); + MailMerger.executeWithRegions(doc, getArtifactsDir() + "LowCode.MailMergeWithRegionsDataSet.3.docx", SaveFormat.DOCX, dataSet, options); + //ExEnd:MailMergeWithRegionsDataSet + } + + @Test + public void mailMergeContextWithRegionsDataSet() throws Exception { + //ExStart:MailMergeContextWithRegionsDataSet + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:MailMerger.Create(MailMergerContext) + //ExFor:MailMergerContext + //ExFor:MailMergerContext.SetRegionsDataSource(DataSet) + //ExSummary:Shows how to do mail merge with regions operation from a DataSet using context. + // There is a several ways to do mail merge with regions operation from a DataSet: + String doc = getMyDir() + "Mail merge with regions data set.docx"; + + DataTable tableCustomers = new DataTable("Customers"); + tableCustomers.getColumns().add("CustomerID"); + tableCustomers.getColumns().add("CustomerName"); + tableCustomers.getRows().add(new Object[]{1, "John Doe"}); + tableCustomers.getRows().add(new Object[]{2, "Jane Doe"}); + + DataTable tableOrders = new DataTable("Orders"); + tableOrders.getColumns().add("CustomerID"); + tableOrders.getColumns().add("ItemName"); + tableOrders.getColumns().add("Quantity"); + tableOrders.getRows().add(new Object[]{1, "Hawaiian", 2}); + tableOrders.getRows().add(new Object[]{2, "Pepperoni", 1}); + tableOrders.getRows().add(new Object[]{2, "Chicago", 1}); + + DataSet dataSet = new DataSet(); + dataSet.getTables().add(tableCustomers); + dataSet.getTables().add(tableOrders); + dataSet.getRelations().add(tableCustomers.getColumns().get("CustomerID"), tableOrders.getColumns().get("CustomerID")); + + MailMergerContext mailMergerContext = new MailMergerContext(); + mailMergerContext.setRegionsDataSource(dataSet); + mailMergerContext.getMailMergeOptions().setTrimWhitespaces(true); + + MailMerger.create(mailMergerContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.MailMergeContextWithRegionsDataTable.docx") + .execute(); + //ExEnd:MailMergeContextWithRegionsDataSet + } + + @Test + public void mailMergeWithRegionsToImagesDataSet() throws Exception { + //ExStart:MailMergeWithRegionsToImagesDataSet + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:MailMerger.ExecuteWithRegionsToImages(String, ImageSaveOptions, DataSet, MailMergeOptions) + //ExSummary:Shows how to do mail merge with regions operation from a DataSet and save result to images. + // There is a several ways to do mail merge with regions operation from a DataSet: + String doc = getMyDir() + "Mail merge with regions data set.docx"; + + DataTable tableCustomers = new DataTable("Customers"); + tableCustomers.getColumns().add("CustomerID"); + tableCustomers.getColumns().add("CustomerName"); + tableCustomers.getRows().add(new Object[]{1, "John Doe"}); + tableCustomers.getRows().add(new Object[]{2, "Jane Doe"}); + + DataTable tableOrders = new DataTable("Orders"); + tableOrders.getColumns().add("CustomerID"); + tableOrders.getColumns().add("ItemName"); + tableOrders.getColumns().add("Quantity"); + tableOrders.getRows().add(new Object[]{1, "Hawaiian", 2}); + tableOrders.getRows().add(new Object[]{2, "Pepperoni", 1}); + tableOrders.getRows().add(new Object[]{2, "Chicago", 1}); + + DataSet dataSet = new DataSet(); + dataSet.getTables().add(tableCustomers); + dataSet.getTables().add(tableOrders); + dataSet.getRelations().add(tableCustomers.getColumns().get("CustomerID"), tableOrders.getColumns().get("CustomerID")); + + OutputStream[] images = MailMerger.executeWithRegionsToImages(doc, new ImageSaveOptions(SaveFormat.PNG), dataSet); + MailMergeOptions options = new MailMergeOptions(); + options.setTrimWhitespaces(true); + images = MailMerger.executeWithRegionsToImages(doc, new ImageSaveOptions(SaveFormat.PNG), dataSet, options); + //ExEnd:MailMergeWithRegionsToImagesDataSet + } + + @Test + public void mailMergeStreamWithRegionsDataSet() throws Exception { + //ExStart:MailMergeStreamWithRegionsDataSet + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:MailMerger.ExecuteWithRegions(Stream, Stream, SaveFormat, DataSet, MailMergeOptions) + //ExSummary:Shows how to do mail merge with regions operation from a DataSet using documents from the stream. + // There is a several ways to do mail merge with regions operation from a DataSet using documents from the stream: + DataTable tableCustomers = new DataTable("Customers"); + tableCustomers.getColumns().add("CustomerID"); + tableCustomers.getColumns().add("CustomerName"); + tableCustomers.getRows().add(new Object[]{1, "John Doe"}); + tableCustomers.getRows().add(new Object[]{2, "Jane Doe"}); + + DataTable tableOrders = new DataTable("Orders"); + tableOrders.getColumns().add("CustomerID"); + tableOrders.getColumns().add("ItemName"); + tableOrders.getColumns().add("Quantity"); + tableOrders.getRows().add(new Object[]{1, "Hawaiian", 2}); + tableOrders.getRows().add(new Object[]{2, "Pepperoni", 1}); + tableOrders.getRows().add(new Object[]{2, "Chicago", 1}); + + DataSet dataSet = new DataSet(); + dataSet.getTables().add(tableCustomers); + dataSet.getTables().add(tableOrders); + dataSet.getRelations().add(tableCustomers.getColumns().get("CustomerID"), tableOrders.getColumns().get("CustomerID")); + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Mail merge.doc")) { + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.MailMergeStreamWithRegionsDataTable.1.docx")) { + MailMerger.executeWithRegions(streamIn, streamOut, SaveFormat.DOCX, dataSet); + } + + try (FileOutputStream streamOut1 = new FileOutputStream(getArtifactsDir() + "LowCode.MailMergeStreamWithRegionsDataTable.2.docx")) { + MailMergeOptions options = new MailMergeOptions(); + options.setTrimWhitespaces(true); + MailMerger.executeWithRegions(streamIn, streamOut1, SaveFormat.DOCX, dataSet, options); + } + } + //ExEnd:MailMergeStreamWithRegionsDataSet + } + + @Test + public void mailMergeContextStreamWithRegionsDataSet() throws Exception { + //ExStart:MailMergeContextStreamWithRegionsDataSet + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:MailMerger.Create(MailMergerContext) + //ExFor:MailMergerContext + //ExFor:MailMergerContext.SetRegionsDataSource(DataSet) + //ExSummary:Shows how to do mail merge with regions operation from a DataSet using documents from the stream using context. + // There is a several ways to do mail merge with regions operation from a DataSet using documents from the stream: + DataTable tableCustomers = new DataTable("Customers"); + tableCustomers.getColumns().add("CustomerID"); + tableCustomers.getColumns().add("CustomerName"); + tableCustomers.getRows().add(new Object[]{1, "John Doe"}); + tableCustomers.getRows().add(new Object[]{2, "Jane Doe"}); + + DataTable tableOrders = new DataTable("Orders"); + tableOrders.getColumns().add("CustomerID"); + tableOrders.getColumns().add("ItemName"); + tableOrders.getColumns().add("Quantity"); + tableOrders.getRows().add(new Object[]{1, "Hawaiian", 2}); + tableOrders.getRows().add(new Object[]{2, "Pepperoni", 1}); + tableOrders.getRows().add(new Object[]{2, "Chicago", 1}); + + DataSet dataSet = new DataSet(); + dataSet.getTables().add(tableCustomers); + dataSet.getTables().add(tableOrders); + dataSet.getRelations().add(tableCustomers.getColumns().get("CustomerID"), tableOrders.getColumns().get("CustomerID")); + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Mail merge.doc")) { + MailMergerContext mailMergerContext = new MailMergerContext(); + mailMergerContext.setRegionsDataSource(dataSet); + mailMergerContext.getMailMergeOptions().setTrimWhitespaces(true); + + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.MailMergeContextStreamWithRegionsDataSet.docx")) { + MailMerger.create(mailMergerContext) + .from(streamIn) + .to(streamOut, SaveFormat.DOCX) + .execute(); + } + } + //ExEnd:MailMergeContextStreamWithRegionsDataSet + } + + @Test + public void mailMergeStreamWithRegionsToImagesDataSet() throws Exception { + //ExStart:MailMergeStreamWithRegionsToImagesDataSet + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:MailMerger.ExecuteWithRegionsToImages(Stream, ImageSaveOptions, DataSet, MailMergeOptions) + //ExSummary:Shows how to do mail merge with regions operation from a DataSet using documents from the stream and save result to images. + // There is a several ways to do mail merge with regions operation from a DataSet using documents from the stream: + DataTable tableCustomers = new DataTable("Customers"); + tableCustomers.getColumns().add("CustomerID"); + tableCustomers.getColumns().add("CustomerName"); + tableCustomers.getRows().add(new Object[]{1, "John Doe"}); + tableCustomers.getRows().add(new Object[]{2, "Jane Doe"}); + + DataTable tableOrders = new DataTable("Orders"); + tableOrders.getColumns().add("CustomerID"); + tableOrders.getColumns().add("ItemName"); + tableOrders.getColumns().add("Quantity"); + tableOrders.getRows().add(new Object[]{1, "Hawaiian", 2}); + tableOrders.getRows().add(new Object[]{2, "Pepperoni", 1}); + tableOrders.getRows().add(new Object[]{2, "Chicago", 1}); + + DataSet dataSet = new DataSet(); + dataSet.getTables().add(tableCustomers); + dataSet.getTables().add(tableOrders); + dataSet.getRelations().add(tableCustomers.getColumns().get("CustomerID"), tableOrders.getColumns().get("CustomerID")); + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Mail merge.doc")) { + OutputStream[] images = MailMerger.executeWithRegionsToImages(streamIn, new ImageSaveOptions(SaveFormat.PNG), dataSet); + MailMergeOptions options = new MailMergeOptions(); + options.setTrimWhitespaces(true); + images = MailMerger.executeWithRegionsToImages(streamIn, new ImageSaveOptions(SaveFormat.PNG), dataSet, options); + } + //ExEnd:MailMergeStreamWithRegionsToImagesDataSet + } + + @Test + public void replace() throws Exception { + //ExStart:Replace + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:Replacer.Replace(String, String, String, String) + //ExFor:Replacer.Replace(String, String, SaveFormat, String, String, FindReplaceOptions) + //ExSummary:Shows how to replace string in the document. + // There is a several ways to replace string in the document: + String doc = getMyDir() + "Footer.docx"; + String pattern = "(C)2006 Aspose Pty Ltd."; + String replacement = "Copyright (C) 2024 by Aspose Pty Ltd."; + + FindReplaceOptions options = new FindReplaceOptions(); + options.setFindWholeWordsOnly(false); + Replacer.replace(doc, getArtifactsDir() + "LowCode.Replace.1.docx", pattern, replacement); + Replacer.replace(doc, getArtifactsDir() + "LowCode.Replace.2.docx", SaveFormat.DOCX, pattern, replacement); + Replacer.replace(doc, getArtifactsDir() + "LowCode.Replace.3.docx", SaveFormat.DOCX, pattern, replacement, options); + //ExEnd:Replace + } + + @Test + public void replaceContext() throws Exception { + //ExStart:ReplaceContext + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Replacer.Create(ReplacerContext) + //ExFor:ReplacerContext + //ExFor:ReplacerContext.SetReplacement(String, String) + //ExFor:ReplacerContext.FindReplaceOptions + //ExSummary:Shows how to replace string in the document using context. + // There is a several ways to replace string in the document: + String doc = getMyDir() + "Footer.docx"; + String pattern = "(C)2006 Aspose Pty Ltd."; + String replacement = "Copyright (C) 2024 by Aspose Pty Ltd."; + + ReplacerContext replacerContext = new ReplacerContext(); + replacerContext.setReplacement(pattern, replacement); + replacerContext.getFindReplaceOptions().setFindWholeWordsOnly(false); + + Replacer.create(replacerContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.ReplaceContext.docx") + .execute(); + //ExEnd:ReplaceContext + } + + @Test + public void replaceToImages() throws Exception { + //ExStart:ReplaceToImages + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Replacer.ReplaceToImages(String, ImageSaveOptions, String, String, FindReplaceOptions) + //ExSummary:Shows how to replace string in the document and save result to images. + // There is a several ways to replace string in the document: + String doc = getMyDir() + "Footer.docx"; + String pattern = "(C)2006 Aspose Pty Ltd."; + String replacement = "Copyright (C) 2024 by Aspose Pty Ltd."; + + OutputStream[] images = Replacer.replaceToImages(doc, new ImageSaveOptions(SaveFormat.PNG), pattern, replacement); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setFindWholeWordsOnly(false); + images = Replacer.replaceToImages(doc, new ImageSaveOptions(SaveFormat.PNG), pattern, replacement, options); + //ExEnd:ReplaceToImages + } + + @Test + public void replaceStream() throws Exception { + //ExStart:ReplaceStream + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:Replacer.Replace(Stream, Stream, SaveFormat, String, String, FindReplaceOptions) + //ExSummary:Shows how to replace string in the document using documents from the stream. + // There is a several ways to replace string in the document using documents from the stream: + String pattern = "(C)2006 Aspose Pty Ltd."; + String replacement = "Copyright (C) 2024 by Aspose Pty Ltd."; + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Footer.docx")) { + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.ReplaceStream.1.docx")) { + Replacer.replace(streamIn, streamOut, SaveFormat.DOCX, pattern, replacement); + } + + try (FileOutputStream streamOut1 = new FileOutputStream(getArtifactsDir() + "LowCode.ReplaceStream.2.docx")) { + FindReplaceOptions options = new FindReplaceOptions(); + options.setFindWholeWordsOnly(false); + Replacer.replace(streamIn, streamOut1, SaveFormat.DOCX, pattern, replacement, options); + } + } + //ExEnd:ReplaceStream + } + + @Test + public void replaceContextStream() throws Exception { + //ExStart:ReplaceContextStream + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Replacer.Create(ReplacerContext) + //ExFor:ReplacerContext + //ExFor:ReplacerContext.SetReplacement(String, String) + //ExFor:ReplacerContext.FindReplaceOptions + //ExSummary:Shows how to replace string in the document using documents from the stream using context. + // There is a several ways to replace string in the document using documents from the stream: + String pattern = "(C)2006 Aspose Pty Ltd."; + String replacement = "Copyright (C) 2024 by Aspose Pty Ltd."; + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Footer.docx")) { + ReplacerContext replacerContext = new ReplacerContext(); + replacerContext.setReplacement(pattern, replacement); + replacerContext.getFindReplaceOptions().setFindWholeWordsOnly(false); + + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.ReplaceContextStream.docx")) { + Replacer.create(replacerContext) + .from(streamIn) + .to(streamOut, SaveFormat.DOCX) + .execute(); + } + } + //ExEnd:ReplaceContextStream + } + + @Test + public void replaceToImagesStream() throws Exception { + //ExStart:ReplaceToImagesStream + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Replacer.ReplaceToImages(Stream, ImageSaveOptions, String, String, FindReplaceOptions) + //ExSummary:Shows how to replace string in the document using documents from the stream and save result to images. + // There is a several ways to replace string in the document using documents from the stream: + String pattern = "(C)2006 Aspose Pty Ltd."; + String replacement = "Copyright (C) 2024 by Aspose Pty Ltd."; + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Footer.docx")) { + OutputStream[] images = Replacer.replaceToImages(streamIn, new ImageSaveOptions(SaveFormat.PNG), pattern, replacement); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setFindWholeWordsOnly(false); + images = Replacer.replaceToImages(streamIn, new ImageSaveOptions(SaveFormat.PNG), pattern, replacement, options); + } + //ExEnd:ReplaceToImagesStream + } + + @Test + public void replaceRegex() throws Exception { + //ExStart:ReplaceRegex + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:Replacer.Replace(String, String, Regex, String) + //ExFor:Replacer.Replace(String, String, SaveFormat, Regex, String, FindReplaceOptions) + //ExSummary:Shows how to replace string with regex in the document. + // There is a several ways to replace string with regex in the document: + String doc = getMyDir() + "Footer.docx"; + String pattern = "gr(a|e)y"; + String replacement = "lavender"; + + Replacer.replace(doc, getArtifactsDir() + "LowCode.ReplaceRegex.1.docx", pattern, replacement); + Replacer.replace(doc, getArtifactsDir() + "LowCode.ReplaceRegex.2.docx", SaveFormat.DOCX, pattern, replacement); + FindReplaceOptions options = new FindReplaceOptions(); + options.setFindWholeWordsOnly(false); + Replacer.replace(doc, getArtifactsDir() + "LowCode.ReplaceRegex.3.docx", SaveFormat.DOCX, pattern, replacement, options); + //ExEnd:ReplaceRegex + } + + @Test + public void replaceContextRegex() throws Exception { + //ExStart:ReplaceContextRegex + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Replacer.Create(ReplacerContext) + //ExFor:ReplacerContext + //ExFor:ReplacerContext.SetReplacement(Regex, String) + //ExFor:ReplacerContext.FindReplaceOptions + //ExSummary:Shows how to replace string with regex in the document using context. + // There is a several ways to replace string with regex in the document: + String doc = getMyDir() + "Footer.docx"; + Pattern pattern = Pattern.compile("gr(a|e)y"); + String replacement = "lavender"; + + ReplacerContext replacerContext = new ReplacerContext(); + replacerContext.setReplacement(pattern, replacement); + replacerContext.getFindReplaceOptions().setFindWholeWordsOnly(false); + + Replacer.create(replacerContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.ReplaceContextRegex.docx") + .execute(); + //ExEnd:ReplaceContextRegex + } + + @Test + public void replaceToImagesRegex() throws Exception { + //ExStart:ReplaceToImagesRegex + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Replacer.ReplaceToImages(String, ImageSaveOptions, Regex, String, FindReplaceOptions) + //ExSummary:Shows how to replace string with regex in the document and save result to images. + // There is a several ways to replace string with regex in the document: + String doc = getMyDir() + "Footer.docx"; + Pattern pattern = Pattern.compile("gr(a|e)y"); + String replacement = "lavender"; + + OutputStream[] images = Replacer.replaceToImages(doc, new ImageSaveOptions(SaveFormat.PNG), pattern, replacement); + FindReplaceOptions options = new FindReplaceOptions(); + options.setFindWholeWordsOnly(false); + images = Replacer.replaceToImages(doc, new ImageSaveOptions(SaveFormat.PNG), pattern, replacement, options); + //ExEnd:ReplaceToImagesRegex + } + + @Test + public void replaceStreamRegex() throws Exception { + //ExStart:ReplaceStreamRegex + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:Replacer.Replace(Stream, Stream, SaveFormat, Regex, String, FindReplaceOptions) + //ExSummary:Shows how to replace string with regex in the document using documents from the stream. + // There is a several ways to replace string with regex in the document using documents from the stream: + Pattern pattern = Pattern.compile("gr(a|e)y"); + String replacement = "lavender"; + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Replace regex.docx")) { + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.ReplaceStreamRegex.1.docx")) { + Replacer.replace(streamIn, streamOut, SaveFormat.DOCX, pattern, replacement); + } + + try (FileOutputStream streamOut1 = new FileOutputStream(getArtifactsDir() + "LowCode.ReplaceStreamRegex.2.docx")) { + FindReplaceOptions options = new FindReplaceOptions(); + options.setFindWholeWordsOnly(false); + Replacer.replace(streamIn, streamOut1, SaveFormat.DOCX, pattern, replacement, options); + } + } + //ExEnd:ReplaceStreamRegex + } + + @Test + public void replaceContextStreamRegex() throws Exception { + //ExStart:ReplaceContextStreamRegex + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Replacer.Create(ReplacerContext) + //ExFor:ReplacerContext + //ExFor:ReplacerContext.SetReplacement(Regex, String) + //ExFor:ReplacerContext.FindReplaceOptions + //ExSummary:Shows how to replace string with regex in the document using documents from the stream using context. + // There is a several ways to replace string with regex in the document using documents from the stream: + Pattern pattern = Pattern.compile("gr(a|e)y"); + String replacement = "lavender"; + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Replace regex.docx")) { + ReplacerContext replacerContext = new ReplacerContext(); + replacerContext.setReplacement(pattern, replacement); + replacerContext.getFindReplaceOptions().setFindWholeWordsOnly(false); + + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.ReplaceContextStreamRegex.docx")) { + Replacer.create(replacerContext) + .from(streamIn) + .to(streamOut, SaveFormat.DOCX) + .execute(); + } + } + //ExEnd:ReplaceContextStreamRegex + } + + @Test + public void replaceToImagesStreamRegex() throws Exception { + //ExStart:ReplaceToImagesStreamRegex + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Replacer.ReplaceToImages(Stream, ImageSaveOptions, Regex, String, FindReplaceOptions) + //ExSummary:Shows how to replace string with regex in the document using documents from the stream and save result to images. + // There is a several ways to replace string with regex in the document using documents from the stream: + Pattern pattern = Pattern.compile("gr(a|e)y"); + String replacement = "lavender"; + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Replace regex.docx")) { + OutputStream[] images = Replacer.replaceToImages(streamIn, new ImageSaveOptions(SaveFormat.PNG), pattern, replacement); + FindReplaceOptions options = new FindReplaceOptions(); + options.setFindWholeWordsOnly(false); + images = Replacer.replaceToImages(streamIn, new ImageSaveOptions(SaveFormat.PNG), pattern, replacement, options); + } + //ExEnd:ReplaceToImagesStreamRegex + } + + //ExStart:BuildReportData + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:ReportBuilderOptions + //ExFor:ReportBuilderOptions.Options + //ExFor:ReportBuilder.BuildReport(String, String, Object, ReportBuilderOptions) + //ExFor:ReportBuilder.BuildReport(String, String, SaveFormat, Object, ReportBuilderOptions) + //ExSummary:Shows how to populate document with data. + @Test //ExSkip + public void buildReportData() throws Exception { + // There is a several ways to populate document with data: + String doc = getMyDir() + "Reporting engine template - If greedy (Java).docx"; + + AsposeData obj = new AsposeData(); + { + obj.setList(new ArrayList<>()); + { + obj.getList().add("abc"); + } + } + + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportWithObject.1.docx", obj); + ReportBuilderOptions options = new ReportBuilderOptions(); + options.setOptions(ReportBuildOptions.ALLOW_MISSING_MEMBERS); + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportWithObject.2.docx", obj, options); + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportWithObject.3.docx", SaveFormat.DOCX, obj); + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportWithObject.4.docx", SaveFormat.DOCX, obj, options); + } + + public static class AsposeData { + public ArrayList getList() { + return mList; + } + + ; + + public void setList(ArrayList value) { + mList = value; + } + + ; + + private ArrayList mList; + } + //ExEnd:BuildReportData + + @Test + public void buildReportDataStream() throws Exception { + //ExStart:BuildReportDataStream + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:ReportBuilder.BuildReport(Stream, Stream, SaveFormat, Object, ReportBuilderOptions) + //ExFor:ReportBuilder.BuildReport(Stream, Stream, SaveFormat, Object[], String[], ReportBuilderOptions) + //ExSummary:Shows how to populate document with data using documents from the stream. + // There is a several ways to populate document with data using documents from the stream: + AsposeData obj = new AsposeData(); + { + obj.setList(new ArrayList<>()); + { + obj.getList().add("abc"); + } + } + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Reporting engine template - If greedy (Java).docx")) { + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.BuildReportDataStream.1.docx")) { + ReportBuilder.buildReport(streamIn, streamOut, SaveFormat.DOCX, obj); + } + + ReportBuilderOptions options = new ReportBuilderOptions(); + options.setOptions(ReportBuildOptions.ALLOW_MISSING_MEMBERS); + try (FileOutputStream streamOut1 = new FileOutputStream(getArtifactsDir() + "LowCode.BuildReportDataStream.2.docx")) { + ReportBuilder.buildReport(streamIn, streamOut1, SaveFormat.DOCX, obj, options); + } + + MessageTestClass sender = new MessageTestClass("LINQ Reporting Engine", "Hello World"); + try (FileOutputStream streamOut2 = new FileOutputStream(getArtifactsDir() + "LowCode.BuildReportDataStream.3.docx")) { + ReportBuilder.buildReport(streamIn, streamOut2, SaveFormat.DOCX, new Object[]{sender}, new String[]{"s"}, options); + } + } + //ExEnd:BuildReportDataStream + } + + //ExStart:BuildReportDataSource + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:ReportBuilder.BuildReport(String, String, Object, String, ReportBuilderOptions) + //ExFor:ReportBuilder.BuildReport(String, String, SaveFormat, Object, String, ReportBuilderOptions) + //ExFor:ReportBuilder.BuildReport(String, String, Object[], String[], ReportBuilderOptions) + //ExFor:ReportBuilder.BuildReport(String, String, SaveFormat, Object[], String[], ReportBuilderOptions) + //ExFor:ReportBuilder.BuildReportToImages(String, ImageSaveOptions, Object[], String[], ReportBuilderOptions) + //ExFor:ReportBuilder.Create(ReportBuilderContext) + //ExFor:ReportBuilderContext + //ExFor:ReportBuilderContext.ReportBuilderOptions + //ExFor:ReportBuilderContext.DataSources + //ExSummary:Shows how to populate document with data sources. + @Test //ExSkip + public void buildReportDataSource() throws Exception { + // There is a several ways to populate document with data sources: + String doc = getMyDir() + "Report building.docx"; + + MessageTestClass sender = new MessageTestClass("LINQ Reporting Engine", "Hello World"); + + ReportBuilderOptions options = new ReportBuilderOptions(); + options.setOptions(ReportBuildOptions.ALLOW_MISSING_MEMBERS); + + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportDataSource.1.docx", sender, "s"); + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportDataSource.2.docx", new Object[]{sender}, new String[]{"s"}); + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportDataSource.3.docx", sender, "s", options); + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportDataSource.4.docx", SaveFormat.DOCX, sender, "s"); + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportDataSource.5.docx", SaveFormat.DOCX, new Object[]{sender}, new String[]{"s"}); + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportDataSource.6.docx", SaveFormat.DOCX, sender, "s", options); + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportDataSource.7.docx", SaveFormat.DOCX, new Object[]{sender}, new String[]{"s"}, options); + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportDataSource.8.docx", new Object[]{sender}, new String[]{"s"}, options); + + options = new ReportBuilderOptions(); + options.setOptions(ReportBuildOptions.ALLOW_MISSING_MEMBERS); + OutputStream[] images = ReportBuilder.buildReportToImages(doc, new ImageSaveOptions(SaveFormat.PNG), new Object[]{sender}, new String[]{"s"}, options); + + ReportBuilderContext reportBuilderContext = new ReportBuilderContext(); + reportBuilderContext.getReportBuilderOptions().setMissingMemberMessage("Missed members"); + reportBuilderContext.getDataSources().put(sender, "s"); + + ReportBuilder.create(reportBuilderContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.BuildReportDataSource.9.docx") + .execute(); + } + + public static class MessageTestClass { + public String getName() { + return mName; + } + + public void setName(String value) { + mName = value; + } + + private String mName; + + public String getMessage() { + return mMessage; + } + + public void setMessage(String value) { + mMessage = value; + } + + private String mMessage; + + public MessageTestClass(String name, String message) { + setName(name); + setMessage(message); + } + } + //ExEnd:BuildReportDataSource + + @Test + public void buildReportDataSourceStream() throws Exception { + //ExStart:BuildReportDataSourceStream + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:ReportBuilder.BuildReport(Stream, Stream, SaveFormat, Object, String, ReportBuilderOptions) + //ExFor:ReportBuilder.BuildReportToImages(Stream, ImageSaveOptions, Object[], String[], ReportBuilderOptions) + //ExFor:ReportBuilder.Create(ReportBuilderContext) + //ExFor:ReportBuilderContext + //ExFor:ReportBuilderContext.ReportBuilderOptions + //ExFor:ReportBuilderContext.DataSources + //ExSummary:Shows how to populate document with data sources using documents from the stream. + // There is a several ways to populate document with data sources using documents from the stream: + MessageTestClass sender = new MessageTestClass("LINQ Reporting Engine", "Hello World"); + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Report building.docx")) { + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.BuildReportDataSourceStream.1.docx")) { + ReportBuilder.buildReport(streamIn, streamOut, SaveFormat.DOCX, new Object[]{sender}, new String[]{"s"}); + } + + try (FileOutputStream streamOut1 = new FileOutputStream(getArtifactsDir() + "LowCode.BuildReportDataSourceStream.2.docx")) { + ReportBuilder.buildReport(streamIn, streamOut1, SaveFormat.DOCX, sender, "s"); + } + + try (FileOutputStream streamOut2 = new FileOutputStream(getArtifactsDir() + "LowCode.BuildReportDataSourceStream.3.docx")) { + ReportBuilderOptions options = new ReportBuilderOptions(); + options.setOptions(ReportBuildOptions.ALLOW_MISSING_MEMBERS); + ReportBuilder.buildReport(streamIn, streamOut2, SaveFormat.DOCX, sender, "s", options); + } + + ReportBuilderOptions options = new ReportBuilderOptions(); + options.setOptions(ReportBuildOptions.ALLOW_MISSING_MEMBERS); + OutputStream[] images = ReportBuilder.buildReportToImages(streamIn, new ImageSaveOptions(SaveFormat.PNG), new Object[]{sender}, new String[]{"s"}, options); + + ReportBuilderContext reportBuilderContext = new ReportBuilderContext(); + reportBuilderContext.getReportBuilderOptions().setMissingMemberMessage("Missed members"); + reportBuilderContext.getDataSources().put(sender, "s"); + + try (FileOutputStream streamOut3 = new FileOutputStream(getArtifactsDir() + "LowCode.BuildReportDataSourceStream.4.docx")) { + ReportBuilder.create(reportBuilderContext) + .from(streamIn) + .to(streamOut3, SaveFormat.DOCX) + .execute(); + } + } + //ExEnd:BuildReportDataSourceStream + } + + @Test + public void removeBlankPages() throws Exception { + //ExStart:RemoveBlankPages + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:Splitter.RemoveBlankPages(String, String) + //ExFor:Splitter.RemoveBlankPages(String, String, SaveFormat) + //ExSummary:Shows how to remove empty pages from the document. + // There is a several ways to remove empty pages from the document: + String doc = getMyDir() + "Blank pages.docx"; + + Splitter.removeBlankPages(doc, getArtifactsDir() + "LowCode.RemoveBlankPages.1.docx"); + Splitter.removeBlankPages(doc, getArtifactsDir() + "LowCode.RemoveBlankPages.2.docx", SaveFormat.DOCX); + //ExEnd:RemoveBlankPages + } + + @Test + public void removeBlankPagesStream() throws Exception { + //ExStart:RemoveBlankPagesStream + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:Splitter.RemoveBlankPages(Stream, Stream, SaveFormat) + //ExSummary:Shows how to remove empty pages from the document from the stream. + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Blank pages.docx")) { + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.RemoveBlankPagesStream.docx")) { + Splitter.removeBlankPages(streamIn, streamOut, SaveFormat.DOCX); + } + } + //ExEnd:RemoveBlankPagesStream + } + + @Test + public void extractPages() throws Exception { + //ExStart:ExtractPages + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:Splitter.ExtractPages(String, String, int, int) + //ExFor:Splitter.ExtractPages(String, String, SaveFormat, int, int) + //ExSummary:Shows how to extract pages from the document. + // There is a several ways to extract pages from the document: + String doc = getMyDir() + "Big document.docx"; + + Splitter.extractPages(doc, getArtifactsDir() + "LowCode.ExtractPages.1.docx", 0, 2); + Splitter.extractPages(doc, getArtifactsDir() + "LowCode.ExtractPages.2.docx", SaveFormat.DOCX, 0, 2); + //ExEnd:ExtractPages + } + + @Test + public void extractPagesStream() throws Exception { + //ExStart:ExtractPagesStream + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:Splitter.ExtractPages(Stream, Stream, SaveFormat, int, int) + //ExSummary:Shows how to extract pages from the document from the stream. + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Big document.docx")) { + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.ExtractPagesStream.docx")) { + Splitter.extractPages(streamIn, streamOut, SaveFormat.DOCX, 0, 2); + } + } + //ExEnd:ExtractPagesStream + } + + @Test + public void splitDocument() throws Exception { + //ExStart:SplitDocument + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:SplitCriteria + //ExFor:SplitOptions.SplitCriteria + //ExFor:Splitter.Split(String, String, SplitOptions) + //ExFor:Splitter.Split(String, String, SaveFormat, SplitOptions) + //ExSummary:Shows how to split document by pages. + String doc = getMyDir() + "Big document.docx"; + + SplitOptions options = new SplitOptions(); + options.setSplitCriteria(SplitCriteria.PAGE); + Splitter.split(doc, getArtifactsDir() + "LowCode.SplitDocument.1.docx", options); + Splitter.split(doc, getArtifactsDir() + "LowCode.SplitDocument.2.docx", SaveFormat.DOCX, options); + //ExEnd:SplitDocument + } + + @Test + public void splitContextDocument() throws Exception { + //ExStart:SplitContextDocument + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Splitter.Create(SplitterContext) + //ExFor:SplitterContext + //ExFor:SplitterContext.SplitOptions + //ExSummary:Shows how to split document by pages using context. + String doc = getMyDir() + "Big document.docx"; + + SplitterContext splitterContext = new SplitterContext(); + splitterContext.getSplitOptions().setSplitCriteria(SplitCriteria.PAGE); + + Splitter.create(splitterContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.SplitContextDocument.docx") + .execute(); + //ExEnd:SplitContextDocument + } + + @Test + public void splitDocumentStream() throws Exception { + //ExStart:SplitDocumentStream + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:Splitter.Split(Stream, SaveFormat, SplitOptions) + //ExSummary:Shows how to split document from the stream by pages. + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Big document.docx")) { + SplitOptions options = new SplitOptions(); + options.setSplitCriteria(SplitCriteria.PAGE); + OutputStream[] stream = Splitter.split(streamIn, SaveFormat.DOCX, options); + } + //ExEnd:SplitDocumentStream + } + + @Test + public void splitContextDocumentStream() throws Exception { + //ExStart:SplitContextDocumentStream + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Splitter.Create(SplitterContext) + //ExFor:SplitterContext + //ExFor:SplitterContext.SplitOptions + //ExSummary:Shows how to split document from the stream by pages using context. + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Big document.docx")) { + SplitterContext splitterContext = new SplitterContext(); + splitterContext.getSplitOptions().setSplitCriteria(SplitCriteria.PAGE); + + ArrayList pages = new ArrayList<>(); + Splitter.create(splitterContext) + .from(streamIn) + .toOutput(pages, SaveFormat.DOCX) + .execute(); + } + //ExEnd:SplitContextDocumentStream + } + + @Test + public void watermarkText() throws Exception { + //ExStart:WatermarkText + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:Watermarker.SetText(String, String, String, TextWatermarkOptions) + //ExFor:Watermarker.SetText(String, String, SaveFormat, String, TextWatermarkOptions) + //ExSummary:Shows how to insert watermark text to the document. + String doc = getMyDir() + "Big document.docx"; + String watermarkText = "This is a watermark"; + + Watermarker.setText(doc, getArtifactsDir() + "LowCode.WatermarkText.1.docx", watermarkText); + Watermarker.setText(doc, getArtifactsDir() + "LowCode.WatermarkText.2.docx", SaveFormat.DOCX, watermarkText); + TextWatermarkOptions options = new TextWatermarkOptions(); + options.setColor(Color.RED); + Watermarker.setText(doc, getArtifactsDir() + "LowCode.WatermarkText.3.docx", watermarkText, options); + Watermarker.setText(doc, getArtifactsDir() + "LowCode.WatermarkText.4.docx", SaveFormat.DOCX, watermarkText, options); + //ExEnd:WatermarkText + } + + @Test + public void watermarkContextText() throws Exception { + //ExStart:WatermarkContextText + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Watermarker.Create(WatermarkerContext) + //ExFor:WatermarkerContext + //ExFor:WatermarkerContext.TextWatermark + //ExFor:WatermarkerContext.TextWatermarkOptions + //ExSummary:Shows how to insert watermark text to the document using context. + String doc = getMyDir() + "Big document.docx"; + String watermarkText = "This is a watermark"; + + WatermarkerContext watermarkerContext = new WatermarkerContext(); + watermarkerContext.setTextWatermark(watermarkText); + + watermarkerContext.getTextWatermarkOptions().setColor(Color.RED); + + Watermarker.create(watermarkerContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.WatermarkContextText.docx") + .execute(); + //ExEnd:WatermarkContextText + } + + @Test + public void watermarkTextStream() throws Exception { + //ExStart:WatermarkTextStream + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:Watermarker.SetText(Stream, Stream, SaveFormat, String, TextWatermarkOptions) + //ExSummary:Shows how to insert watermark text to the document from the stream. + String watermarkText = "This is a watermark"; + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Document.docx")) { + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.WatermarkTextStream.1.docx")) { + Watermarker.setText(streamIn, streamOut, SaveFormat.DOCX, watermarkText); + } + + try (FileOutputStream streamOut1 = new FileOutputStream(getArtifactsDir() + "LowCode.WatermarkTextStream.2.docx")) { + TextWatermarkOptions options = new TextWatermarkOptions(); + options.setColor(Color.RED); + Watermarker.setText(streamIn, streamOut1, SaveFormat.DOCX, watermarkText, options); + } + } + //ExEnd:WatermarkTextStream + } + + @Test + public void watermarkContextTextStream() throws Exception { + //ExStart:WatermarkContextTextStream + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Watermarker.Create(WatermarkerContext) + //ExFor:WatermarkerContext + //ExFor:WatermarkerContext.TextWatermark + //ExFor:WatermarkerContext.TextWatermarkOptions + //ExSummary:Shows how to insert watermark text to the document from the stream using context. + String watermarkText = "This is a watermark"; + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Document.docx")) { + WatermarkerContext watermarkerContext = new WatermarkerContext(); + watermarkerContext.setTextWatermark(watermarkText); + + watermarkerContext.getTextWatermarkOptions().setColor(Color.RED); + + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.WatermarkContextTextStream.docx")) { + Watermarker.create(watermarkerContext) + .from(streamIn) + .to(streamOut, SaveFormat.DOCX) + .execute(); + } + } + //ExEnd:WatermarkContextTextStream + } + + @Test + public void watermarkImage() throws Exception { + //ExStart:WatermarkImage + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:Watermarker.SetImage(String, String, String, ImageWatermarkOptions) + //ExFor:Watermarker.SetImage(String, String, SaveFormat, String, ImageWatermarkOptions) + //ExSummary:Shows how to insert watermark image to the document. + String doc = getMyDir() + "Document.docx"; + String watermarkImage = getImageDir() + "Logo.jpg"; + + Watermarker.setImage(doc, getArtifactsDir() + "LowCode.SetWatermarkImage.1.docx", watermarkImage); + Watermarker.setImage(doc, getArtifactsDir() + "LowCode.SetWatermarkText.2.docx", SaveFormat.DOCX, watermarkImage); + ImageWatermarkOptions options = new ImageWatermarkOptions(); + options.setScale(50.0); + Watermarker.setImage(doc, getArtifactsDir() + "LowCode.SetWatermarkText.3.docx", watermarkImage, options); + Watermarker.setImage(doc, getArtifactsDir() + "LowCode.SetWatermarkText.4.docx", SaveFormat.DOCX, watermarkImage, options); + //ExEnd:WatermarkImage + } + + @Test + public void watermarkContextImage() throws Exception { + //ExStart:WatermarkContextImage + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Watermarker.Create(WatermarkerContext) + //ExFor:WatermarkerContext + //ExFor:WatermarkerContext.ImageWatermark + //ExFor:WatermarkerContext.ImageWatermarkOptions + //ExSummary:Shows how to insert watermark image to the document using context. + String doc = getMyDir() + "Document.docx"; + String watermarkImage = getImageDir() + "Logo.jpg"; + + WatermarkerContext watermarkerContext = new WatermarkerContext(); + watermarkerContext.setImageWatermark(Files.readAllBytes(Paths.get(watermarkImage))); + + watermarkerContext.getImageWatermarkOptions().setScale(50.0); + + Watermarker.create(watermarkerContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.WatermarkContextImage.docx") + .execute(); + //ExEnd:WatermarkContextImage + } + + @Test + public void watermarkImageStream() throws Exception { + //ExStart:WatermarkImageStream + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:Watermarker.SetImage(Stream, Stream, SaveFormat, Image, ImageWatermarkOptions) + //ExSummary:Shows how to insert watermark image to the document from a stream. + BufferedImage image = ImageIO.read(new File(getImageDir() + "Logo.jpg")); + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Document.docx")) { + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.SetWatermarkText.1.docx")) { + Watermarker.setImage(streamIn, streamOut, SaveFormat.DOCX, image); + } + + try (FileOutputStream streamOut1 = new FileOutputStream(getArtifactsDir() + "LowCode.SetWatermarkText.2.docx")) { + ImageWatermarkOptions options = new ImageWatermarkOptions(); + options.setScale(50.0); + Watermarker.setImage(streamIn, streamOut1, SaveFormat.DOCX, image, options); + } + } + //ExEnd:WatermarkImageStream + } + + @Test + public void watermarkContextImageStream() throws Exception { + //ExStart:WatermarkContextImageStream + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Watermarker.Create(WatermarkerContext) + //ExFor:WatermarkerContext + //ExFor:WatermarkerContext.ImageWatermark + //ExFor:WatermarkerContext.ImageWatermarkOptions + //ExSummary:Shows how to insert watermark image to the document from a stream using context. + String watermarkImage = getImageDir() + "Logo.jpg"; + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Document.docx")) { + WatermarkerContext watermarkerContext = new WatermarkerContext(); + watermarkerContext.setImageWatermark(Files.readAllBytes(Paths.get(watermarkImage))); + + watermarkerContext.getImageWatermarkOptions().setScale(50.0); + + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "LowCode.WatermarkContextImageStream.docx")) { + Watermarker.create(watermarkerContext) + .from(streamIn) + .to(streamOut, SaveFormat.DOCX) + .execute(); + } + } + //ExEnd:WatermarkContextImageStream + } + + @Test + public void watermarkTextToImages() throws Exception { + //ExStart:WatermarkTextToImages + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Watermarker.SetWatermarkToImages(String, ImageSaveOptions, String, TextWatermarkOptions) + //ExSummary:Shows how to insert watermark text to the document and save result to images. + String doc = getMyDir() + "Big document.docx"; + String watermarkText = "This is a watermark"; + + OutputStream[] images = Watermarker.setWatermarkToImages(doc, new ImageSaveOptions(SaveFormat.PNG), watermarkText); + + TextWatermarkOptions watermarkOptions = new TextWatermarkOptions(); + watermarkOptions.setColor(Color.RED); + images = Watermarker.setWatermarkToImages(doc, new ImageSaveOptions(SaveFormat.PNG), watermarkText, watermarkOptions); + //ExEnd:WatermarkTextToImages + } + + @Test + public void watermarkTextToImagesStream() throws Exception { + //ExStart:WatermarkTextToImagesStream + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Watermarker.SetWatermarkToImages(Stream, ImageSaveOptions, String, TextWatermarkOptions) + //ExSummary:Shows how to insert watermark text to the document from the stream and save result to images. + String watermarkText = "This is a watermark"; + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Document.docx")) { + OutputStream[] images = Watermarker.setWatermarkToImages(streamIn, new ImageSaveOptions(SaveFormat.PNG), watermarkText); + + TextWatermarkOptions watermarkOptions = new TextWatermarkOptions(); + watermarkOptions.setColor(Color.RED); + images = Watermarker.setWatermarkToImages(streamIn, new ImageSaveOptions(SaveFormat.PNG), watermarkText, watermarkOptions); + } + //ExEnd:WatermarkTextToImagesStream + } + + @Test + public void watermarkImageToImages() throws Exception { + //ExStart:WatermarkImageToImages + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Watermarker.SetWatermarkToImages(String, ImageSaveOptions, Byte[], ImageWatermarkOptions) + //ExSummary:Shows how to insert watermark image to the document and save result to images. + String doc = getMyDir() + "Document.docx"; + String watermarkImage = getImageDir() + "Logo.jpg"; + Path watermarkImagePath = Paths.get(watermarkImage); + + Watermarker.setWatermarkToImages(doc, new ImageSaveOptions(SaveFormat.PNG), Files.readAllBytes(watermarkImagePath)); + + ImageWatermarkOptions options = new ImageWatermarkOptions(); + options.setScale(50.0); + Watermarker.setWatermarkToImages(doc, new ImageSaveOptions(SaveFormat.PNG), Files.readAllBytes(watermarkImagePath), options); + //ExEnd:WatermarkImageToImages + } + + @Test + public void watermarkImageToImagesStream() throws Exception { + //ExStart:WatermarkImageToImagesStream + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:Watermarker.SetWatermarkToImages(Stream, ImageSaveOptions, Stream, ImageWatermarkOptions) + //ExSummary:Shows how to insert watermark image to the document from a stream and save result to images. + String watermarkImage = getImageDir() + "Logo.jpg"; + + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Document.docx")) { + try (FileInputStream imageStream = new FileInputStream(watermarkImage)) { + Watermarker.setWatermarkToImages(streamIn, new ImageSaveOptions(SaveFormat.PNG), imageStream); + ImageWatermarkOptions options = new ImageWatermarkOptions(); + options.setScale(50.0); + Watermarker.setWatermarkToImages(streamIn, new ImageSaveOptions(SaveFormat.PNG), imageStream, options); + } + } + //ExEnd:WatermarkImageToImagesStream + } +} + diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExMailMerge.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExMailMerge.java new file mode 100644 index 00000000..40958229 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExMailMerge.java @@ -0,0 +1,1168 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import com.aspose.words.net.System.Data.*; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.sql.ResultSet; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Map; + +public class ExMailMerge extends ApiExampleBase { + @Test + public void executeArray() throws Exception { + //ExStart + //ExFor:MailMerge.Execute(String[], Object[]) + //ExFor:ContentDisposition + //ExSummary:Shows how to perform a mail merge, and then save the document to the client browser. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField(" MERGEFIELD FullName "); + builder.insertParagraph(); + builder.insertField(" MERGEFIELD Company "); + builder.insertParagraph(); + builder.insertField(" MERGEFIELD Address "); + builder.insertParagraph(); + builder.insertField(" MERGEFIELD City "); + + doc.getMailMerge().execute(new String[]{"FullName", "Company", "Address", "City"}, + new Object[]{"James Bond", "MI5 Headquarters", "Milbank", "London"}); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + + TestUtil.mailMergeMatchesArray(new String[][]{new String[]{"James Bond", "MI5 Headquarters", "Milbank", "London"}}, doc, true); + } + + @Test + public void executeDataReader() throws Exception { + //ExStart + //ExFor:MailMerge.Execute(IDataReader) + //ExSummary:Shows how to run a mail merge using data from a data reader. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Product:\t"); + builder.insertField(" MERGEFIELD ProductName"); + builder.write("\nSupplier:\t"); + builder.insertField(" MERGEFIELD CompanyName"); + builder.writeln(); + builder.insertField(" MERGEFIELD QuantityPerUnit"); + builder.write(" for $"); + builder.insertField(" MERGEFIELD UnitPrice"); + + // "DocumentHelper.executeDataTable" is utility function that creates a connection, command, + // executes the command and return the result in a DataTable. + ResultSet resultSet = DocumentHelper.executeDataTable( + "SELECT Products.ProductName, Suppliers.CompanyName, Products.QuantityPerUnit, " + + "{fn ROUND(Products.UnitPrice,2)} as UnitPrice " + + "FROM Products INNER JOIN Suppliers ON Products.SupplierID = Suppliers.SupplierID"); + DataTable dataTable = new DataTable(resultSet, "OrderDetails"); + IDataReader dataReader = new DataTableReader(dataTable); + + // Now we can take the data from the reader and use it in the mail merge. + doc.getMailMerge().execute(dataReader); + + doc.save(getArtifactsDir() + "MailMerge.ExecuteDataReader.docx"); + //ExEnd + } + + @Test + public void executeDataTable() throws Exception { + //ExStart + //ExFor:Document + //ExFor:MailMerge + //ExFor:MailMerge.Execute(DataTable) + //ExFor:MailMerge.Execute(DataRow) + //ExFor:Document.MailMerge + //ExSummary:Shows how to execute a mail merge with data from a DataTable. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertField(" MERGEFIELD CustomerName "); + builder.insertParagraph(); + builder.insertField(" MERGEFIELD Address "); + + // This example creates a table, but you would normally load table from a database + DataTable table = new DataTable("Test"); + table.getColumns().add("CustomerName"); + table.getColumns().add("Address"); + table.getRows().add("Thomas Hardy", "120 Hanover Sq., London"); + table.getRows().add("Paolo Accorti", "Via Monte Bianco 34, Torino"); + + // Field values from the table are inserted into the mail merge fields found in the document + doc.getMailMerge().execute(table); + + doc.save(getArtifactsDir() + "MailMerge.ExecuteDataTable.docx"); + + // Create a copy of our document to perform another mail merge + doc = new Document(); + builder = new DocumentBuilder(doc); + builder.insertField(" MERGEFIELD CustomerName "); + builder.insertParagraph(); + builder.insertField(" MERGEFIELD Address "); + + // We can also source values for a mail merge from a single row in the table + doc.getMailMerge().execute(table.getRows().get(1)); + + doc.save(getArtifactsDir() + "MailMerge.ExecuteDataTable.OneRow.docx"); + //ExEnd + } + + //ExStart + //ExFor:MailMerge.ExecuteWithRegions(DataSet) + //ExSummary:Shows how to execute a nested mail merge with two merge regions and two data tables. + @Test//ExSkip + public void executeWithRegionsNested() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Normally, MERGEFIELDs contain the name of a column of a mail merge data source. + // Instead, we can use "TableStart:" and "TableEnd:" prefixes to begin/end a mail merge region. + // Each region will belong to a table with a name that matches the string immediately after the prefix's colon. + builder.insertField(" MERGEFIELD TableStart:Customers"); + + // This MERGEFIELD is inside the mail merge region of the "Customers" table. + // When we execute the mail merge, this field will receive data from rows in a data source named "Customers". + builder.write("Orders for "); + builder.insertField(" MERGEFIELD CustomerName"); + builder.write(":"); + + // Create column headers for a table that will contain values from a second inner region. + builder.startTable(); + builder.insertCell(); + builder.write("Item"); + builder.insertCell(); + builder.write("Quantity"); + builder.endRow(); + + // Create a second mail merge region inside the outer region for a table named "Orders". + // The "Orders" table has a many-to-one relationship with the "Customers" table on the "CustomerID" column. + builder.insertCell(); + builder.insertField(" MERGEFIELD TableStart:Orders"); + builder.insertField(" MERGEFIELD ItemName"); + builder.insertCell(); + builder.insertField(" MERGEFIELD Quantity"); + + // End the inner region + // One stipulation of using regions and tables is that the opening and closing of a mail merge region must + // only happen over one row of a document's table + builder.insertField(" MERGEFIELD TableEnd:Orders"); + builder.endTable(); + + builder.insertField(" MERGEFIELD TableEnd:Customers"); + + // Create a dataset that contains the two tables with the required names and relationships. + // Each merge document for each row of the "Customers" table of the outer merge region will perform its mail merge on the "Orders" table. + // Each merge document will display all rows of the latter table whose "CustomerID" column values match the current "Customers" table row. + DataSet customersAndOrders = createDataSet(); + doc.getMailMerge().executeWithRegions(customersAndOrders); + + doc.save(getArtifactsDir() + "MailMerge.ExecuteWithRegionsNested.docx"); + } + + /// + /// Generates a data set which has two data tables named "Customers" and "Orders", + /// with a one-to-many relationship between the former and latter on the "CustomerID" column. + /// + private static DataSet createDataSet() { + // Create the outer mail merge + DataTable tableCustomers = new DataTable("Customers"); + tableCustomers.getColumns().add("CustomerID"); + tableCustomers.getColumns().add("CustomerName"); + tableCustomers.getRows().add(1, "John Doe"); + tableCustomers.getRows().add(2, "Jane Doe"); + + // Create the table for the inner merge + DataTable tableOrders = new DataTable("Orders"); + tableOrders.getColumns().add("CustomerID"); + tableOrders.getColumns().add("ItemName"); + tableOrders.getColumns().add("Quantity"); + tableOrders.getRows().add(1, "Hawaiian", 2); + tableOrders.getRows().add(2, "Pepperoni", 1); + tableOrders.getRows().add(2, "Chicago", 1); + + // Add both tables to a data set + DataSet dataSet = new DataSet(); + dataSet.getTables().add(tableCustomers); + dataSet.getTables().add(tableOrders); + + // The "CustomerID" column, also the primary key of the customers table is the foreign key for the Orders table + dataSet.getRelations().add(tableCustomers.getColumns().get("CustomerID"), tableOrders.getColumns().get("CustomerID")); + + return dataSet; + } + //ExEnd + + @Test + public void executeWithRegionsConcurrent() throws Exception { + //ExStart + //ExFor:MailMerge.ExecuteWithRegions(DataTable) + //ExFor:MailMerge.ExecuteWithRegions(DataView) + //ExSummary:Shows how to use regions to execute two separate mail merges in one document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // If we want to perform two consecutive mail merges on one document while taking data from two tables + // related to each other in any way, we can separate the mail merges with regions. + // Normally, MERGEFIELDs contain the name of a column of a mail merge data source. + // Instead, we can use "TableStart:" and "TableEnd:" prefixes to begin/end a mail merge region. + // Each region will belong to a table with a name that matches the string immediately after the prefix's colon. + // These regions are separate for unrelated data, while they can be nested for hierarchical data. + builder.writeln("\tCities: "); + builder.insertField(" MERGEFIELD TableStart:Cities"); + builder.insertField(" MERGEFIELD Name"); + builder.insertField(" MERGEFIELD TableEnd:Cities"); + builder.insertParagraph(); + + // Both MERGEFIELDs refer to the same column name, but values for each will come from different data tables. + builder.writeln("\tFruit: "); + builder.insertField(" MERGEFIELD TableStart:Fruit"); + builder.insertField(" MERGEFIELD Name"); + builder.insertField(" MERGEFIELD TableEnd:Fruit"); + + // Create two unrelated data tables. + DataTable tableCities = new DataTable("Cities"); + tableCities.getColumns().add("Name"); + tableCities.getRows().add("Washington"); + tableCities.getRows().add("London"); + tableCities.getRows().add("New York"); + + DataTable tableFruit = new DataTable("Fruit"); + tableFruit.getColumns().add("Name"); + tableFruit.getRows().add("Cherry"); + tableFruit.getRows().add("Apple"); + tableFruit.getRows().add("Watermelon"); + tableFruit.getRows().add("Banana"); + + // We will need to run one mail merge per table. The first mail merge will populate the MERGEFIELDs + // in the "Cities" range while leaving the fields the "Fruit" range unfilled. + doc.getMailMerge().executeWithRegions(tableCities); + + doc.save(getArtifactsDir() + "MailMerge.ExecuteWithRegionsConcurrent.docx"); + //ExEnd + } + + @Test + public void mailMergeRegionInfo() throws Exception { + //ExStart + //ExFor:MailMerge.GetFieldNamesForRegion(String) + //ExFor:MailMerge.GetFieldNamesForRegion(String,Int32) + //ExFor:MailMerge.GetRegionsByName(String) + //ExFor:MailMerge.RegionEndTag + //ExFor:MailMerge.RegionStartTag + //ExFor:MailMergeRegionInfo.ParentRegion + //ExSummary:Shows how to create, list, and read mail merge regions. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // These tags, which go inside MERGEFIELDs, denote the strings that signify the starts and ends of mail merge regions + Assert.assertEquals(doc.getMailMerge().getRegionStartTag(), "TableStart"); + Assert.assertEquals(doc.getMailMerge().getRegionEndTag(), "TableEnd"); + + // By using these tags, we will start and end a "MailMergeRegion1", which will contain MERGEFIELDs for two columns + builder.insertField(" MERGEFIELD TableStart:MailMergeRegion1"); + builder.insertField(" MERGEFIELD Column1"); + builder.write(", "); + builder.insertField(" MERGEFIELD Column2"); + builder.insertField(" MERGEFIELD TableEnd:MailMergeRegion1"); + + // We can keep track of merge regions and their columns by looking at these collections + ArrayList regions = doc.getMailMerge().getRegionsByName("MailMergeRegion1"); + Assert.assertEquals(regions.size(), 1); + Assert.assertEquals(regions.get(0).getName(), "MailMergeRegion1"); + + String[] mergeFieldNames = doc.getMailMerge().getFieldNamesForRegion("MailMergeRegion1"); + Assert.assertEquals(mergeFieldNames[0], "Column1"); + Assert.assertEquals(mergeFieldNames[1], "Column2"); + + // Insert a region with the same name inside the existing region, which will make it a parent. + // Now a "Column2" field will be inside a new region. + builder.moveToField(regions.get(0).getFields().get(1), false); + builder.insertField(" MERGEFIELD TableStart:MailMergeRegion1"); + builder.moveToField(regions.get(0).getFields().get(1), true); + builder.insertField(" MERGEFIELD TableEnd:MailMergeRegion1"); + + // Regions that share the same name are still accounted for and can be accessed by index + regions = doc.getMailMerge().getRegionsByName("MailMergeRegion1"); + Assert.assertEquals(regions.size(), 2); + // Check that the second region now has a parent region. + Assert.assertEquals("MailMergeRegion1", regions.get(1).getParentRegion().getName()); + + mergeFieldNames = doc.getMailMerge().getFieldNamesForRegion("MailMergeRegion1", 1); + Assert.assertEquals(mergeFieldNames[0], "Column2"); + //ExEnd + } + + //ExStart + //ExFor:MailMerge.MergeDuplicateRegions + //ExSummary:Shows how to work with duplicate mail merge regions. + @Test(dataProvider = "mergeDuplicateRegionsDataProvider") //ExSkip + public void mergeDuplicateRegions(boolean isMergeDuplicateRegions) throws Exception { + // Create a document and table that we will merge + Document doc = createSourceDocMergeDuplicateRegions(); + DataTable dataTable = createSourceTableMergeDuplicateRegions(); + + // If this property is false, the first region will be merged + // while the MERGEFIELDs of the second one will be left in the pre-merge state + // To get both regions merged we would have to execute the mail merge twice, on a table of the same name + // If this is set to true, both regions will be affected by the merge + doc.getMailMerge().setMergeDuplicateRegions(isMergeDuplicateRegions); + + doc.getMailMerge().executeWithRegions(dataTable); + doc.save(getArtifactsDir() + "MailMerge.MergeDuplicateRegions.docx"); + } + + @DataProvider(name = "mergeDuplicateRegionsDataProvider") //ExSkip + public static Object[][] mergeDuplicateRegionsDataProvider() { + return new Object[][] + { + {true}, + {false}, + }; + } + + /// + /// Return a document that contains two duplicate mail merge regions (sharing the same name in the "TableStart/End" tags). + /// + private static Document createSourceDocMergeDuplicateRegions() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField(" MERGEFIELD TableStart:MergeRegion"); + builder.insertField(" MERGEFIELD Column1"); + builder.insertField(" MERGEFIELD TableEnd:MergeRegion"); + builder.insertParagraph(); + + builder.insertField(" MERGEFIELD TableStart:MergeRegion"); + builder.insertField(" MERGEFIELD Column2"); + builder.insertField(" MERGEFIELD TableEnd:MergeRegion"); + + return doc; + } + + /// + /// Create a data table with one row and two columns. + /// + private static DataTable createSourceTableMergeDuplicateRegions() { + DataTable dataTable = new DataTable("MergeRegion"); + dataTable.getColumns().add("Column1"); + dataTable.getColumns().add("Column2"); + dataTable.getRows().add("Value 1", "Value 2"); + + return dataTable; + } + //ExEnd + + //ExStart + //ExFor:MailMerge.PreserveUnusedTags + //ExSummary:Shows how to preserve the appearance of alternative mail merge tags that go unused during a mail merge. + @Test(dataProvider = "preserveUnusedTagsDataProvider") //ExSkip + public void preserveUnusedTags(boolean doPreserveUnusedTags) throws Exception { + // Create a document and table that we will merge + Document doc = createSourceDocWithAlternativeMergeFields(); + DataTable dataTable = createSourceTablePreserveUnusedTags(); + + // By default, alternative merge tags that can't receive data because the data source has no columns with their name + // are converted to and left on display as MERGEFIELDs after the mail merge + // We can preserve their original appearance setting this attribute to true + doc.getMailMerge().setPreserveUnusedTags(doPreserveUnusedTags); + doc.getMailMerge().execute(dataTable); + + doc.save(getArtifactsDir() + "MailMerge.PreserveUnusedTags.docx"); + + Assert.assertEquals(doc.getText().contains("{{ Column2 }}"), doPreserveUnusedTags); + } + + @DataProvider(name = "preserveUnusedTagsDataProvider") //ExSkip + public static Object[][] preserveUnusedTagsDataProvider() throws Exception { + return new Object[][] + { + {false}, + {true}, + }; + } + + /// + /// Create a document and add two tags that can accept mail merge data that are not the traditional MERGEFIELDs. + /// + private static Document createSourceDocWithAlternativeMergeFields() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("{{ Column1 }}"); + builder.writeln("{{ Column2 }}"); + + // Our tags will only register as destinations for mail merge data if we set this to true + doc.getMailMerge().setUseNonMergeFields(true); + + return doc; + } + + /// + /// Create a simple data table with one column. + /// + private static DataTable createSourceTablePreserveUnusedTags() { + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("Column1"); + dataTable.getRows().add("Value1"); + + return dataTable; + } + //ExEnd + + //ExStart + //ExFor:MailMerge.MergeWholeDocument + //ExSummary:Shows the relationship between mail merges with regions and field updating. + @Test(dataProvider = "mergeWholeDocumentDataProvider") //ExSkip + public void mergeWholeDocument(boolean doMergeWholeDocument) throws Exception { + // Create a document and data table that will both be merged + Document doc = createSourceDocMergeWholeDocument(); + DataTable dataTable = createSourceTableMergeWholeDocument(); + + // A regular mail merge will update all fields in the document as part of the procedure, + // which will happen if this property is set to true + // Otherwise, a mail merge with regions will only update fields + // within a mail merge region which matches the name of the DataTable + doc.getMailMerge().setMergeWholeDocument(doMergeWholeDocument); + doc.getMailMerge().executeWithRegions(dataTable); + + // If true, all fields in the document will be updated upon merging + // In this case that property is false, so the first QUOTE field will not be updated and will not show a value, + // but the second one inside the region designated by the data table name will show the correct value + doc.save(getArtifactsDir() + "MailMerge.MergeWholeDocument.docx"); + + Assert.assertEquals(doMergeWholeDocument, doc.getText().contains("This QUOTE field is outside of the \"MyTable\" merge region.")); + } + + @DataProvider(name = "mergeWholeDocumentDataProvider") //ExSkip + public static Object[][] mergeWholeDocumentDataProvider() throws Exception { + return new Object[][] + { + {false}, + {true}, + }; + } + + /// + /// Create a document with a QUOTE field outside and one more inside a mail merge region called "MyTable" + /// + private static Document createSourceDocMergeWholeDocument() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert QUOTE field outside of any mail merge regions + FieldQuote field = (FieldQuote) builder.insertField(FieldType.FIELD_QUOTE, true); + field.setText("This QUOTE field is outside of the \"MyTable\" merge region."); + + // Start "MyTable" merge region + builder.insertParagraph(); + builder.insertField(" MERGEFIELD TableStart:MyTable"); + + // Insert QUOTE field inside "MyTable" merge region + field = (FieldQuote) builder.insertField(FieldType.FIELD_QUOTE, true); + field.setText("This QUOTE field is inside the \"MyTable\" merge region."); + builder.insertParagraph(); + + // Add a MERGEFIELD for a column in the data table, end the "MyTable" region and return the document + builder.insertField(" MERGEFIELD MyColumn"); + builder.insertField(" MERGEFIELD TableEnd:MyTable"); + + return doc; + } + + /// + /// Create a simple data table that will be used in a mail merge. + /// + private static DataTable createSourceTableMergeWholeDocument() { + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("MyColumn"); + dataTable.getRows().add("MyValue"); + + return dataTable; + } + //ExEnd + + //ExStart + //ExFor:MailMerge.UseWholeParagraphAsRegion + //ExSummary:Shows the relationship between mail merge regions and paragraphs. + @Test //ExSkip + public void useWholeParagraphAsRegion() throws Exception { + // Create a document with 2 mail merge regions in one paragraph and a table to which can fill one of the regions during a mail merge + Document doc = createSourceDocWithNestedMergeRegions(); + DataTable dataTable = createSourceTableDataTableForOneRegion(); + + // By default, a paragraph can belong to no more than one mail merge region + // Our document breaks this rule so executing a mail merge with regions now will cause an exception to be thrown + Assert.assertTrue(doc.getMailMerge().getUseWholeParagraphAsRegion()); + Assert.assertThrows(IllegalStateException.class, () -> doc.getMailMerge().executeWithRegions(dataTable)); + + // If we set this variable to false, paragraphs and mail merge regions are independent so we can safely run our mail merge + doc.getMailMerge().setUseWholeParagraphAsRegion(false); + doc.getMailMerge().executeWithRegions(dataTable); + + // Our first region is populated, while our second is safely displayed as unused all across one paragraph + doc.save(getArtifactsDir() + "MailMerge.UseWholeParagraphAsRegion.docx"); + } + + /// + /// Create a document with two mail merge regions sharing one paragraph. + /// + private static Document createSourceDocWithNestedMergeRegions() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Region 1: "); + builder.insertField(" MERGEFIELD TableStart:MyTable"); + builder.insertField(" MERGEFIELD Column1"); + builder.write(", "); + builder.insertField(" MERGEFIELD Column2"); + builder.insertField(" MERGEFIELD TableEnd:MyTable"); + + builder.write(", Region 2: "); + builder.insertField(" MERGEFIELD TableStart:MyOtherTable"); + builder.insertField(" MERGEFIELD TableEnd:MyOtherTable"); + + return doc; + } + + /// + /// Create a data table that can populate one region during a mail merge. + /// + private static DataTable createSourceTableDataTableForOneRegion() { + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("Column1"); + dataTable.getColumns().add("Column2"); + dataTable.getRows().add("Value 1", "Value 2"); + + return dataTable; + } + //ExEnd + + @Test(dataProvider = "trimWhiteSpacesDataProvider") + public void trimWhiteSpaces(boolean doTrimWhitespaces) throws Exception { + //ExStart + //ExFor:MailMerge.TrimWhitespaces + //ExSummary:Shows how to trimmed whitespaces from mail merge values. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField("MERGEFIELD myMergeField", null); + + doc.getMailMerge().setTrimWhitespaces(doTrimWhitespaces); + doc.getMailMerge().execute(new String[]{"myMergeField"}, new Object[]{"\t hello world! "}); + + if (doTrimWhitespaces) + Assert.assertEquals("hello world!\f", doc.getText()); + else + Assert.assertEquals("\t hello world! \f", doc.getText()); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "trimWhiteSpacesDataProvider") + public static Object[][] trimWhiteSpacesDataProvider() throws Exception { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void mailMergeGetFieldNames() throws Exception { + Document doc = new Document(); + //ExStart + //ExFor:MailMerge.GetFieldNames + //ExSummary:Shows how to get names of all merge fields in a document. + String[] fieldNames = doc.getMailMerge().getFieldNames(); + //ExEnd + } + + @Test + public void deleteFields() throws Exception { + Document doc = new Document(); + //ExStart + //ExFor:MailMerge.DeleteFields + //ExSummary:Shows how to delete all merge fields from a document without executing mail merge. + doc.getMailMerge().deleteFields(); + //ExEnd + } + + @Test + public void removeContainingFields() throws Exception { + Document doc = new Document(); + //ExStart + //ExFor:MailMerge.CleanupOptions + //ExFor:MailMergeCleanupOptions + //ExSummary:Shows how to instruct the mail merge engine to remove any containing fields from around a merge field during mail merge. + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_CONTAINING_FIELDS); + //ExEnd + } + + @Test + public void removeUnusedFields() throws Exception { + Document doc = new Document(); + //ExStart + //ExFor:MailMerge.CleanupOptions + //ExFor:MailMergeCleanupOptions + //ExSummary:Shows how to automatically remove unmerged merge fields during mail merge. + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_UNUSED_FIELDS); + //ExEnd + } + + @Test + public void removeEmptyParagraphs() throws Exception { + Document doc = new Document(); + //ExStart + //ExFor:MailMerge.CleanupOptions + //ExFor:MailMergeCleanupOptions + //ExSummary:Shows how to make sure empty paragraphs that result from merging fields with no data are removed from the document. + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_EMPTY_PARAGRAPHS); + //ExEnd + } + + @Test(enabled = false, description = "WORDSNET-17733", dataProvider = "removeColonBetweenEmptyMergeFieldsDataProvider") + public void removeColonBetweenEmptyMergeFields(final String punctuationMark, + final boolean isCleanupParagraphsWithPunctuationMarks, final String resultText) throws Exception { + //ExStart + //ExFor:MailMerge.CleanupParagraphsWithPunctuationMarks + //ExSummary:Shows how to remove paragraphs with punctuation marks after mail merge operation. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + FieldMergeField mergeFieldOption1 = (FieldMergeField) builder.insertField("MERGEFIELD", "Option_1"); + mergeFieldOption1.setFieldName("Option_1"); + + // Here is the complete list of cleanable punctuation marks: + // ! + // , + // . + // : + // ; + // ? + // ¡ + // ¿ + builder.write(punctuationMark); + + FieldMergeField mergeFieldOption2 = (FieldMergeField) builder.insertField("MERGEFIELD", "Option_2"); + mergeFieldOption2.setFieldName("Option_2"); + + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_EMPTY_PARAGRAPHS); + // The default value of the option is true which means that the behavior was changed to mimic MS Word + // If you rely on the old behavior are able to revert it by setting the option to false + doc.getMailMerge().setCleanupParagraphsWithPunctuationMarks(isCleanupParagraphsWithPunctuationMarks); + + doc.getMailMerge().execute(new String[]{"Option_1", "Option_2"}, new Object[]{null, null}); + + doc.save(getArtifactsDir() + "MailMerge.RemoveColonBetweenEmptyMergeFields.docx"); + //ExEnd + + Assert.assertEquals(doc.getText(), resultText); + } + + @DataProvider(name = "removeColonBetweenEmptyMergeFieldsDataProvider") + public static Object[][] removeColonBetweenEmptyMergeFieldsDataProvider() { + return new Object[][] + { + {"!", false, ""}, + {", ", false, ""}, + {" . ", false, ""}, + {" :", false, ""}, + {" ; ", false, ""}, + {" ? ", false, ""}, + {" ¡ ", false, ""}, + {" ¿ ", false, ""}, + {"!", true, "!\f"}, + {", ", true, ", \f"}, + {" . ", true, " . \f"}, + {" :", true, " :\f"}, + {" ; ", true, " ; \f"}, + {" ? ", true, " ? \f"}, + {" ¡ ", true, " ¡ \f"}, + {" ¿ ", true, " ¿ \f"}, + }; + } + + //ExStart + //ExFor:MailMerge.MappedDataFields + //ExFor:MappedDataFieldCollection + //ExFor:MappedDataFieldCollection.Add + //ExFor:MappedDataFieldCollection.Clear + //ExFor:MappedDataFieldCollection.ContainsKey(String) + //ExFor:MappedDataFieldCollection.ContainsValue(String) + //ExFor:MappedDataFieldCollection.Count + //ExFor:MappedDataFieldCollection.GetEnumerator + //ExFor:MappedDataFieldCollection.Item(String) + //ExFor:MappedDataFieldCollection.Remove(String) + //ExSummary:Shows how to map data columns and MERGEFIELDs with different names so the data is transferred between them during a mail merge. + @Test //ExSkip + public void mappedDataFieldCollection() throws Exception { + // Create a document and table that we will merge + Document doc = createSourceDocMappedDataFields(); + DataTable dataTable = createSourceTableMappedDataFields(); + + // We have a column "Column2" in the data table that doesn't have a respective MERGEFIELD in the document + // Also, we have a MERGEFIELD named "Column3" that does not exist as a column in the data source + // If data from "Column2" is suitable for the "Column3" MERGEFIELD, + // we can map that column name to the MERGEFIELD in the "MappedDataFields" key/value pair + MappedDataFieldCollection mappedDataFields = doc.getMailMerge().getMappedDataFields(); + + // A data source column name is linked to a MERGEFIELD name by adding an element like this + mappedDataFields.add("MergeFieldName", "DataSourceColumnName"); + + // So, values from "Column2" will now go into MERGEFIELDs named "Column3" as well as "Column2", if there are any + mappedDataFields.add("Column3", "Column2"); + + // The MERGEFIELD name is the "key" to the respective data source column name "value" + Assert.assertEquals(mappedDataFields.get("MergeFieldName"), "DataSourceColumnName"); + Assert.assertTrue(mappedDataFields.containsKey("MergeFieldName")); + Assert.assertTrue(mappedDataFields.containsValue("DataSourceColumnName")); + + // Now if we run this mail merge, the "Column3" MERGEFIELDs will take data from "Column2" of the table + doc.getMailMerge().execute(dataTable); + + // We can count and iterate over the mapped columns/fields + Assert.assertEquals(mappedDataFields.getCount(), 2); + + Iterator> enumerator = mappedDataFields.iterator(); + try { + while (enumerator.hasNext()) { + Map.Entry dataField = enumerator.next(); + System.out.println(MessageFormat.format("Column named {0} is mapped to MERGEFIELDs named {1}", dataField.getValue(), dataField.getKey())); + } + } finally { + if (enumerator != null) enumerator.remove(); + } + + // We can also remove some or all of the elements + mappedDataFields.remove("MergeFieldName"); + Assert.assertFalse(mappedDataFields.containsKey("MergeFieldName")); + Assert.assertFalse(mappedDataFields.containsValue("DataSourceColumnName")); + + mappedDataFields.clear(); + Assert.assertEquals(mappedDataFields.getCount(), 0); + + // Removing the mapped key/value pairs has no effect on the document because the merge was already done with them in place + doc.save(getArtifactsDir() + "MailMerge.MappedDataFieldCollection.docx"); + } + + /// + /// Create a document with 2 MERGEFIELDs, one of which does not have a corresponding column in the data table. + /// + private static Document createSourceDocMappedDataFields() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert two MERGEFIELDs that will accept data from that table + builder.insertField(" MERGEFIELD Column1"); + builder.write(", "); + builder.insertField(" MERGEFIELD Column3"); + + return doc; + } + + /// + /// Create a data table with 2 columns, one of which does not have a corresponding MERGEFIELD in our source document. + /// + private static DataTable createSourceTableMappedDataFields() { + // Create a data table that will be used in a mail merge + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("Column1"); + dataTable.getColumns().add("Column2"); + dataTable.getRows().add("Value1", "Value2"); + + return dataTable; + } + //ExEnd + + @Test + public void getFieldNames() throws Exception { + //ExStart + //ExFor:FieldAddressBlock + //ExFor:FieldAddressBlock.GetFieldNames + //ExSummary:Shows how to get mail merge field names used by the field. + Document doc = new Document(getMyDir() + "Field sample - ADDRESSBLOCK.docx"); + + String[] addressFieldsExpect = {"Company", "First Name", "Middle Name", "Last Name", "Suffix", "Address 1", "City", "State", "Country or Region", "Postal Code"}; + + FieldAddressBlock addressBlockField = (FieldAddressBlock) doc.getRange().getFields().get(0); + String[] addressBlockFieldNames = addressBlockField.getFieldNames(); + //ExEnd + + Assert.assertEquals(addressBlockFieldNames, addressFieldsExpect); + + String[] greetingFieldsExpect = {"Courtesy Title", "Last Name"}; + + FieldGreetingLine greetingLineField = (FieldGreetingLine) doc.getRange().getFields().get(1); + String[] greetingLineFieldNames = greetingLineField.getFieldNames(); + + Assert.assertEquals(greetingLineFieldNames, greetingFieldsExpect); + } + + @Test + public void useNonMergeFields() throws Exception { + Document doc = new Document(); + //ExStart + //ExFor:MailMerge.UseNonMergeFields + //ExSummary:Shows how to perform mail merge into merge fields and into additional fields types. + doc.getMailMerge().setUseNonMergeFields(true); + //ExEnd + } + + /// + /// Without TestCaseSource/TestCase because of some strange behavior when using long data. + /// + @Test + public void mustacheTemplateSyntaxTrue() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.write("{{ testfield1 }}"); + builder.write("{{ testfield2 }}"); + builder.write("{{ testfield3 }}"); + + doc.getMailMerge().setUseNonMergeFields(true); + doc.getMailMerge().setPreserveUnusedTags(true); + + DataTable table = new DataTable("Test"); + table.getColumns().add("testfield2"); + table.getRows().add("value 1"); + + doc.getMailMerge().execute(table); + + String paraText = DocumentHelper.getParagraphText(doc, 0); + + Assert.assertEquals("{{ testfield1 }}value 1{{ testfield3 }}\f", paraText); + } + + @Test + public void mustacheTemplateSyntaxFalse() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.write("{{ testfield1 }}"); + builder.write("{{ testfield2 }}"); + builder.write("{{ testfield3 }}"); + + doc.getMailMerge().setUseNonMergeFields(true); + doc.getMailMerge().setPreserveUnusedTags(false); + + DataTable table = new DataTable("Test"); + table.getColumns().add("testfield2"); + table.getRows().add("value 1"); + + doc.getMailMerge().execute(table); + + String paraText = DocumentHelper.getParagraphText(doc, 0); + + Assert.assertEquals("\u0013MERGEFIELD \"testfield1\"\u0014«testfield1»\u0015value 1\u0013MERGEFIELD \"testfield3\"\u0014«testfield3»\u0015\f", paraText); + } + + @Test + public void testMailMergeGetRegionsHierarchy() throws Exception { + //ExStart + //ExFor:MailMerge.GetRegionsHierarchy + //ExFor:MailMergeRegionInfo + //ExFor:MailMergeRegionInfo.Regions + //ExFor:MailMergeRegionInfo.Name + //ExFor:MailMergeRegionInfo.Fields + //ExFor:MailMergeRegionInfo.StartField + //ExFor:MailMergeRegionInfo.EndField + //ExFor:MailMergeRegionInfo.Level + //ExSummary:Shows how to get MailMergeRegionInfo and work with it. + Document doc = new Document(getMyDir() + "Mail merge regions.docx"); + + // Returns a full hierarchy of regions (with fields) available in the document + MailMergeRegionInfo regionInfo = doc.getMailMerge().getRegionsHierarchy(); + + // Get top regions in the document + ArrayList topRegions = regionInfo.getRegions(); + Assert.assertEquals(topRegions.size(), 2); + Assert.assertEquals(((MailMergeRegionInfo) topRegions.get(0)).getName(), "Region1"); + Assert.assertEquals(((MailMergeRegionInfo) topRegions.get(1)).getName(), "Region2"); + Assert.assertEquals(((MailMergeRegionInfo) topRegions.get(0)).getLevel(), 1); + Assert.assertEquals(((MailMergeRegionInfo) topRegions.get(1)).getLevel(), 1); + + // Get nested region in first top region + ArrayList nestedRegions = ((MailMergeRegionInfo) topRegions.get(0)).getRegions(); + Assert.assertEquals(nestedRegions.size(), 2); + Assert.assertEquals(((MailMergeRegionInfo) nestedRegions.get(0)).getName(), "NestedRegion1"); + Assert.assertEquals(((MailMergeRegionInfo) nestedRegions.get(1)).getName(), "NestedRegion2"); + Assert.assertEquals(((MailMergeRegionInfo) nestedRegions.get(0)).getLevel(), 2); + Assert.assertEquals(((MailMergeRegionInfo) nestedRegions.get(1)).getLevel(), 2); + + // Get field list in first top region + ArrayList fieldList = ((MailMergeRegionInfo) topRegions.get(0)).getFields(); + Assert.assertEquals(fieldList.size(), 4); + + FieldMergeField startFieldMergeField = ((MailMergeRegionInfo) nestedRegions.get(0)).getStartField(); + Assert.assertEquals(startFieldMergeField.getFieldName(), "TableStart:NestedRegion1"); + + FieldMergeField endFieldMergeField = ((MailMergeRegionInfo) nestedRegions.get(0)).getEndField(); + Assert.assertEquals(endFieldMergeField.getFieldName(), "TableEnd:NestedRegion1"); + //ExEnd + } + + + //ExStart + //ExFor:MailMerge.MailMergeCallback + //ExFor:IMailMergeCallback + //ExFor:IMailMergeCallback.TagsReplaced + //ExSummary:Shows how to define custom logic for handling events during mail merge. + @Test //ExSkip + public void testTagsReplacedEventShouldRisedWithUseNonMergeFieldsOption() throws Exception { + Document document = new Document(); + document.getMailMerge().setUseNonMergeFields(true); + + MailMergeCallbackStub mailMergeCallbackStub = new MailMergeCallbackStub(); + document.getMailMerge().setMailMergeCallback(mailMergeCallbackStub); + + document.getMailMerge().execute(new String[0], new Object[0]); + + Assert.assertEquals(mailMergeCallbackStub.getTagsReplacedCounter(), 1); + } + + private static class MailMergeCallbackStub implements IMailMergeCallback { + public void tagsReplaced() { + mTagsReplacedCounter++; + } + + public int getTagsReplacedCounter() { + return mTagsReplacedCounter; + } + + private int mTagsReplacedCounter; + } + //ExEnd + + @Test + public void getRegionsByName() throws Exception { + Document doc = new Document(getMyDir() + "Mail merge regions.docx"); + + ArrayList regions = doc.getMailMerge().getRegionsByName("Region1"); + Assert.assertEquals(doc.getMailMerge().getRegionsByName("Region1").size(), 1); + + for (MailMergeRegionInfo region : regions) Assert.assertEquals(region.getName(), "Region1"); + + regions = doc.getMailMerge().getRegionsByName("Region2"); + Assert.assertEquals(doc.getMailMerge().getRegionsByName("Region2").size(), 1); + + for (MailMergeRegionInfo region : regions) Assert.assertEquals(region.getName(), "Region2"); + + regions = doc.getMailMerge().getRegionsByName("NestedRegion1"); + Assert.assertEquals(doc.getMailMerge().getRegionsByName("NestedRegion1").size(), 2); + + for (MailMergeRegionInfo region : regions) Assert.assertEquals(region.getName(), "NestedRegion1"); + } + + @Test + public void cleanupOptions() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.startTable(); + builder.insertCell(); + builder.insertField(" MERGEFIELD TableStart:StudentCourse "); + builder.insertCell(); + builder.insertField(" MERGEFIELD CourseName "); + builder.insertCell(); + builder.insertField(" MERGEFIELD TableEnd:StudentCourse "); + builder.endTable(); + + DataTable data = getDataTable(); + + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_EMPTY_TABLE_ROWS); + doc.getMailMerge().executeWithRegions(data); + + doc.save(getArtifactsDir() + "MailMerge.CleanupOptions.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "MailMerge.CleanupOptions.docx", getGoldsDir() + "MailMerge.CleanupOptions Gold.docx")); + } + + /** + * Create DataTable and fill it with data. + * In real life this DataTable should be filled from a database. + */ + private static DataTable getDataTable() { + DataTable dataTable = new DataTable("StudentCourse"); + dataTable.getColumns().add("CourseName"); + + DataRow dataRowEmpty = dataTable.newRow(); + dataTable.getRows().add(dataRowEmpty); + dataRowEmpty.set(0, ""); + + for (int i = 0; i < 10; i++) { + DataRow datarow = dataTable.newRow(); + dataTable.getRows().add(datarow); + datarow.set(0, "Course " + i); + } + + return dataTable; + } + + @Test(dataProvider = "unconditionalMergeFieldsAndRegionsDataProvider") + public void unconditionalMergeFieldsAndRegions(boolean doCountAllMergeFields) throws Exception { + //ExStart + //ExFor:MailMerge.UnconditionalMergeFieldsAndRegions + //ExSummary:Shows how to merge fields or regions regardless of the parent IF field's condition. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a MERGEFIELD nested inside an IF field + // Since the statement of the IF field is false, the result of the inner MERGEFIELD will not be displayed + // and the MERGEFIELD will not receive any data during a mail merge + FieldIf fieldIf = (FieldIf) builder.insertField(" IF 1 = 2 "); + builder.moveTo(fieldIf.getSeparator()); + builder.insertField(" MERGEFIELD FullName "); + + // We can still count MERGEFIELDs inside false-statement IF fields if we set this flag to true + doc.getMailMerge().setUnconditionalMergeFieldsAndRegions(doCountAllMergeFields); + + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FullName"); + dataTable.getRows().add("James Bond"); + + // Execute the mail merge + doc.getMailMerge().execute(dataTable); + + // The result will not be visible in the document because the IF field is false, but the inner MERGEFIELD did indeed receive data + doc.save(getArtifactsDir() + "MailMerge.UnconditionalMergeFieldsAndRegions.docx"); + + if (doCountAllMergeFields) + Assert.assertEquals("IF 1 = 2 \"James Bond\"", doc.getText().trim()); + else + Assert.assertEquals("IF 1 = 2 \u0013 MERGEFIELD FullName \u0014«FullName»", doc.getText().trim()); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "unconditionalMergeFieldsAndRegionsDataProvider") + public static Object[][] unconditionalMergeFieldsAndRegionsDataProvider() throws Exception { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "retainFirstSectionStartDataProvider") + public void retainFirstSectionStart(boolean isRetainFirstSectionStart, int sectionStart, int expected) throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField(" MERGEFIELD FullName "); + + doc.getFirstSection().getPageSetup().setSectionStart(sectionStart); + doc.getMailMerge().setRetainFirstSectionStart(isRetainFirstSectionStart); + + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FullName"); + dataTable.getRows().add("James Bond"); + + doc.getMailMerge().execute(dataTable); + + for (Section section : doc.getSections()) + Assert.assertEquals(expected, section.getPageSetup().getSectionStart()); + } + + @DataProvider(name = "retainFirstSectionStartDataProvider") + public static Object[][] retainFirstSectionStartDataProvider() throws Exception { + return new Object[][] + { + {true, SectionStart.CONTINUOUS, SectionStart.CONTINUOUS}, + {true, SectionStart.NEW_COLUMN, SectionStart.NEW_COLUMN}, + {true, SectionStart.NEW_PAGE, SectionStart.NEW_PAGE}, + {true, SectionStart.EVEN_PAGE, SectionStart.EVEN_PAGE}, + {true, SectionStart.ODD_PAGE, SectionStart.ODD_PAGE}, + {false, SectionStart.CONTINUOUS, SectionStart.NEW_PAGE}, + {false, SectionStart.NEW_COLUMN, SectionStart.NEW_PAGE}, + {false, SectionStart.NEW_PAGE, SectionStart.NEW_PAGE}, + {false, SectionStart.EVEN_PAGE, SectionStart.EVEN_PAGE}, + {false, SectionStart.ODD_PAGE, SectionStart.ODD_PAGE}, + }; + } + + @Test + public void restartListsAtEachSection() throws Exception + { + //ExStart + //ExFor:MailMerge.RestartListsAtEachSection + //ExSummary:Shows how to control whether or not list numbering is restarted at each section when mail merge is performed. + Document doc = new Document(getMyDir() + "Section breaks with numbering.docx"); + + doc.getMailMerge().setRestartListsAtEachSection(false); + doc.getMailMerge().execute(new String[0], new Object[0]); + + doc.save(getArtifactsDir() + "MailMerge.RestartListsAtEachSection.pdf"); + //ExEnd + } + + @Test + public void removeLastEmptyParagraph() throws Exception + { + //ExStart + //ExFor:DocumentBuilder.InsertHtml(String, HtmlInsertOptions) + //ExSummary:Shows how to use options while inserting html. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField(" MERGEFIELD Name "); + builder.insertParagraph(); + builder.insertField(" MERGEFIELD EMAIL "); + builder.insertParagraph(); + + // By default "DocumentBuilder.InsertHtml" inserts a HTML fragment that ends with a block-level HTML element, + // it normally closes that block-level element and inserts a paragraph break. + // As a result, a new empty paragraph appears after inserted document. + // If we specify "HtmlInsertOptions.RemoveLastEmptyParagraph", those extra empty paragraphs will be removed. + builder.moveToMergeField("NAME"); + builder.insertHtml("

          John Smith

          ", HtmlInsertOptions.USE_BUILDER_FORMATTING | HtmlInsertOptions.REMOVE_LAST_EMPTY_PARAGRAPH); + builder.moveToMergeField("EMAIL"); + builder.insertHtml("

          jsmith@example.com

          ", HtmlInsertOptions.USE_BUILDER_FORMATTING); + + doc.save(getArtifactsDir() + "MailMerge.RemoveLastEmptyParagraph.docx"); + //ExEnd + + Assert.assertEquals(4, doc.getFirstSection().getBody().getParagraphs().getCount()); + } + + @Test + public void removeEmptyTables() throws Exception + { + //ExStart:RemoveEmptyTables + //GistId:93fefe5344a8337b931d0fed5c028225 + //ExFor:MailMergeCleanupOptions + //ExSummary:Shows how to remove whole empty table during mail merge. + DataTable tableCustomers = new DataTable("A"); + tableCustomers.getColumns().add("CustomerID"); + tableCustomers.getColumns().add("CustomerName"); + tableCustomers.getRows().add(new Object[] { 1, "John Doe" }); + tableCustomers.getRows().add(new Object[] { 2, "Jane Doe" }); + + DataSet ds = new DataSet(); + ds.getTables().add(tableCustomers); + + Document doc = new Document(getMyDir() + "Mail merge tables.docx"); + Assert.assertEquals(2, doc.getChildNodes(NodeType.TABLE, true).getCount()); + + doc.getMailMerge().setMergeDuplicateRegions(false); + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_EMPTY_TABLES | MailMergeCleanupOptions.REMOVE_UNUSED_REGIONS); + doc.getMailMerge().executeWithRegions(ds.getTables().get("A")); + + doc.save(getArtifactsDir() + "MailMerge.RemoveEmptyTables.docx"); + + doc = new Document(getArtifactsDir() + "MailMerge.RemoveEmptyTables.docx"); + Assert.assertEquals(1, doc.getChildNodes(NodeType.TABLE, true).getCount()); + //ExEnd:RemoveEmptyTables + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExMailMergeCustom.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExMailMergeCustom.java new file mode 100644 index 00000000..bf82750a --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExMailMergeCustom.java @@ -0,0 +1,324 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.IMailMergeDataSource; +import com.aspose.words.IMailMergeDataSourceRoot; +import com.aspose.words.ref.Ref; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.HashMap; + +public class ExMailMergeCustom extends ApiExampleBase { + //ExStart + //ExFor:IMailMergeDataSource + //ExFor:IMailMergeDataSource.TableName + //ExFor:IMailMergeDataSource.MoveNext + //ExFor:IMailMergeDataSource.GetValue + //ExFor:IMailMergeDataSource.GetChildDataSource + //ExFor:MailMerge.Execute(IMailMergeDataSource) + //ExSummary:Shows how to execute a mail merge with a data source in the form of a custom object. + @Test //ExSkip + public void customDataSource() throws Exception { + // Create a destination document for the mail merge + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertField(" MERGEFIELD FullName "); + builder.insertParagraph(); + builder.insertField(" MERGEFIELD Address "); + + // Create some data that we will use in the mail merge + CustomerList customers = new CustomerList(); + customers.add(new Customer("Thomas Hardy", "120 Hanover Sq., London")); + customers.add(new Customer("Paolo Accorti", "Via Monte Bianco 34, Torino")); + + // To be able to mail merge from your own data source, it must be wrapped + // into an object that implements the IMailMergeDataSource interface + CustomerMailMergeDataSource customersDataSource = new CustomerMailMergeDataSource(customers); + + // Now you can pass your data source into Aspose.Words + doc.getMailMerge().execute(customersDataSource); + + doc.save(getArtifactsDir() + "MailMergeCustom.CustomDataSource.docx"); + testCustomDataSource(customers, new Document(getArtifactsDir() + "MailMergeCustom.CustomDataSource.docx")); //ExSkip + } + + // An example of a "data entity" class in your application. + public class Customer { + public Customer(final String aFullName, final String anAddress) { + mFullName = aFullName; + mAddress = anAddress; + } + + public String getFullName() { + return mFullName; + } + + public void setFullName(final String value) { + mFullName = value; + } + + public String getAddress() { + return mAddress; + } + + public void setAddress(final String value) { + mAddress = value; + } + + private String mFullName; + private String mAddress; + } + + // An example of a typed collection that contains your "data" objects. + public class CustomerList extends ArrayList { + public Customer get(final int index) { + return (Customer) super.get(index); + } + + public void set(final int index, final Customer value) { + super.set(index, value); + } + } + + // A custom mail merge data source that you implement to allow Aspose.Words + // to mail merge data from your Customer objects into Microsoft Word documents. + public class CustomerMailMergeDataSource implements IMailMergeDataSource { + public CustomerMailMergeDataSource(final CustomerList customers) { + mCustomers = customers; + + // When the data source is initialized, it must be positioned before the first record. + mRecordIndex = -1; + } + + // The name of the data source. Used by Aspose.Words only when executing mail merge with repeatable regions. + public String getTableName() { + return "Customer"; + } + + // Aspose.Words calls this method to get a value for every data field. + public boolean getValue(final String fieldName, final Ref fieldValue) throws Exception { + if (fieldName.equals("FullName")) { + fieldValue.set(mCustomers.get(mRecordIndex).getFullName()); + return true; + } else if (fieldName.equals("Address")) { + fieldValue.set(mCustomers.get(mRecordIndex).getAddress()); + return true; + } else { + // A field with this name was not found, + // return false to the Aspose.Words mail merge engine + fieldValue.set(null); + return false; + } + } + + // A standard implementation for moving to a next record in a collection. + public boolean moveNext() { + if (!isEof()) mRecordIndex++; + + return (!isEof()); + } + + public IMailMergeDataSource getChildDataSource(final String tableName) { + return null; + } + + private boolean isEof() { + return (mRecordIndex >= mCustomers.size()); + } + + private final CustomerList mCustomers; + private int mRecordIndex; + } + //ExEnd + + private void testCustomDataSource(CustomerList customerList, Document doc) { + String[][] mergeData = new String[customerList.size()][]; + + for (int i = 0; i < customerList.size(); i++) + mergeData[i] = new String[]{customerList.get(i).getFullName(), customerList.get(i).getAddress()}; + + TestUtil.mailMergeMatchesArray(mergeData, doc, true); + } + + //ExStart + //ExFor:IMailMergeDataSourceRoot + //ExFor:IMailMergeDataSourceRoot.GetDataSource(String) + //ExFor:MailMerge.ExecuteWithRegions(IMailMergeDataSourceRoot) + //ExSummary:Performs mail merge from a custom data source with master-detail data. + @Test //ExSkip + public void customDataSourceRoot() throws Exception { + // Create a document with two mail merge regions named "Washington" and "Seattle" + Document doc = createSourceDocumentWithMailMergeRegions(new String[]{"Washington", "Seattle"}); + + // Create two data sources + EmployeeList employeesWashingtonBranch = new EmployeeList(); + employeesWashingtonBranch.add(new Employee("John Doe", "Sales")); + employeesWashingtonBranch.add(new Employee("Jane Doe", "Management")); + + EmployeeList employeesSeattleBranch = new EmployeeList(); + employeesWashingtonBranch.add(new Employee("John Cardholder", "Management")); + employeesWashingtonBranch.add(new Employee("Joe Bloggs", "Sales")); + + // Register our data sources by name in a data source root + DataSourceRoot sourceRoot = new DataSourceRoot(); + sourceRoot.registerSource("Washington", new EmployeeListMailMergeSource(employeesWashingtonBranch)); + sourceRoot.registerSource("Seattle", new EmployeeListMailMergeSource(employeesSeattleBranch)); + + // Since we have consecutive mail merge regions, we would normally have to perform two mail merges + // However, one mail merge source data root call every relevant data source and merge automatically + doc.getMailMerge().executeWithRegions(sourceRoot); + + doc.save(getArtifactsDir() + "MailMergeCustom.CustomDataSourceRoot.docx"); + } + + /// + /// Create document that contains consecutive mail merge regions, with names designated by the input array, + /// for a data table of employees. + /// + private static Document createSourceDocumentWithMailMergeRegions(String[] regions) throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + for (String s : regions) { + builder.writeln("\n" + s + " branch: "); + builder.insertField(" MERGEFIELD TableStart:" + s); + builder.insertField(" MERGEFIELD FullName"); + builder.write(", "); + builder.insertField(" MERGEFIELD Department"); + builder.insertField(" MERGEFIELD TableEnd:" + s); + } + + return doc; + } + + /// + /// An example of a "data entity" class in your application. + /// + private static class Employee { + public Employee(String aFullName, String aDepartment) { + mFullName = aFullName; + mDepartment = aDepartment; + } + + public String getFullName() { + return mFullName; + } + + private final String mFullName; + + public String getDepartment() { + return mDepartment; + } + + private final String mDepartment; + } + + /// + /// An example of a typed collection that contains your "data" objects. + /// + private static class EmployeeList extends ArrayList { + public Employee get(int index) { + return (Employee) super.get(index); + } + + public void set(int index, Employee value) { + super.set(index, value); + } + } + + /// + /// Data source root that can be passed directly into a mail merge which can register and contain many child data sources. + /// These sources must all implement IMailMergeDataSource, and are registered and differentiated by a name + /// which corresponds to a mail merge region that will read the respective data. + /// + private static class DataSourceRoot implements IMailMergeDataSourceRoot { + public IMailMergeDataSource getDataSource(String tableName) { + EmployeeListMailMergeSource source = mSources.get(tableName); + source.reset(); + return mSources.get(tableName); + } + + public void registerSource(String sourceName, EmployeeListMailMergeSource source) { + mSources.put(sourceName, source); + } + + private final HashMap mSources = new HashMap<>(); + } + + /// + /// Custom mail merge data source. + /// + private static class EmployeeListMailMergeSource implements IMailMergeDataSource { + public EmployeeListMailMergeSource(EmployeeList employees) { + mEmployees = employees; + mRecordIndex = -1; + } + + /// + /// A standard implementation for moving to a next record in a collection. + /// + public boolean moveNext() { + if (!isEof()) + mRecordIndex++; + + return (!isEof()); + } + + private boolean isEof() { + return (mRecordIndex >= mEmployees.size()); + } + + public void reset() { + mRecordIndex = -1; + } + + /// + /// The name of the data source. Used by Aspose.Words only when executing mail merge with repeatable regions. + /// + public String getTableName() { + return "Employees"; + } + + /// + /// Aspose.Words calls this method to get a value for every data field. + /// + public boolean getValue(String fieldName, Ref fieldValue) { + switch (fieldName) { + case "FullName": + fieldValue.set(mEmployees.get(mRecordIndex).getFullName()); + return true; + case "Department": + fieldValue.set(mEmployees.get(mRecordIndex).getDepartment()); + return true; + default: + // A field with this name was not found, + // return false to the Aspose.Words mail merge engine + fieldValue.set(null); + return false; + } + } + + /// + /// Child data sources are for nested mail merges. + /// + public IMailMergeDataSource getChildDataSource(String tableName) { + throw new UnsupportedOperationException(); + } + + private final EmployeeList mEmployees; + private int mRecordIndex; + } + //ExEnd + +} + diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExMailMergeEvent.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExMailMergeEvent.java new file mode 100644 index 00000000..cdaa1a3c --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExMailMergeEvent.java @@ -0,0 +1,355 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.Shape; +import com.aspose.words.*; +import com.aspose.words.net.System.Data.DataRow; +import com.aspose.words.net.System.Data.DataTable; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.awt.*; +import java.io.ByteArrayInputStream; + +public class ExMailMergeEvent extends ApiExampleBase { + //ExStart + //ExFor:DocumentBuilder.InsertHtml(String) + //ExFor:MailMerge.FieldMergingCallback + //ExFor:IFieldMergingCallback + //ExFor:FieldMergingArgs + //ExFor:FieldMergingArgsBase + //ExFor:FieldMergingArgsBase.Field + //ExFor:FieldMergingArgsBase.DocumentFieldName + //ExFor:FieldMergingArgsBase.Document + //ExFor:IFieldMergingCallback.FieldMerging + //ExFor:FieldMergingArgs.Text + //ExSummary:Shows how to execute a mail merge with a custom callback that handles merge data in the form of HTML documents. + @Test //ExSkip + public void insertHtml() throws Exception { + Document doc = new Document(getMyDir() + "Field sample - MERGEFIELD.docx"); + + // Add a handler for the MergeField event + doc.getMailMerge().setFieldMergingCallback(new HandleMergeFieldInsertHtml()); + + final String htmlText = "\r\n

          Hello world!

          \r\n"; + + // Execute mail merge + doc.getMailMerge().execute(new String[]{"htmlField1"}, new String[]{htmlText}); + + // Save resulting document with a new name + doc.save(getArtifactsDir() + "MailMergeEvent.InsertHtml.docx"); + } + + private class HandleMergeFieldInsertHtml implements IFieldMergingCallback { + // This is called when merge field is actually merged with data in the document. + public void fieldMerging(final FieldMergingArgs args) throws Exception { + // All merge fields that expect HTML data should be marked with some prefix, e.g. 'html' + if (args.getDocumentFieldName().startsWith("html") && args.getField().getFieldCode().contains("\\b")) { + FieldMergeField field = args.getField(); + + // Insert the text for this merge field as HTML data, using DocumentBuilder + DocumentBuilder builder = new DocumentBuilder(args.getDocument()); + builder.moveToMergeField(args.getDocumentFieldName()); + builder.write(field.getTextBefore()); + builder.insertHtml((String) args.getFieldValue()); + + // The HTML text itself should not be inserted + // We have already inserted it as an HTML + args.setText(""); + } + } + + public void /*IFieldMergingCallback.*/imageFieldMerging(ImageFieldMergingArgs args) { + // Do nothing + } + } + //ExEnd + + //ExStart + //ExFor:FieldMergingArgsBase.FieldValue + //ExSummary:Shows how to use data source value of the field. + @Test //ExSkip + public void fieldFormats() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertField("MERGEFIELD TextField \\* Caps", null); + builder.write(", "); + builder.insertField("MERGEFIELD TextField2 \\* Upper", null); + builder.write(", "); + builder.insertField("MERGEFIELD NumericField \\# 0.0", null); + + builder.getDocument().getMailMerge().setFieldMergingCallback(new FieldValueMergingCallback()); + + builder.getDocument().getMailMerge().execute( + new String[]{"TextField", "TextField2", "NumericField"}, + new Object[]{"Original value", "Original value", 10}); + + Assert.assertEquals("New Value, New value from FieldMergingArgs, 20.0", doc.getText().trim()); + } + + private static class FieldValueMergingCallback implements IFieldMergingCallback { + /// + /// This is called when merge field is actually merged with data in the document. + /// + public void /*IFieldMergingCallback.*/fieldMerging(FieldMergingArgs e) { + switch (e.getFieldName()) { + case "TextField": + Assert.assertEquals("Original value", e.getFieldValue()); + e.setFieldValue("New value"); + break; + case "TextField2": + Assert.assertEquals("Original value", e.getFieldValue()); + e.setText("New value from FieldMergingArgs"); // Should suppress e.FieldValue and ignore format + e.setFieldValue("new value"); + break; + case "NumericField": + Assert.assertEquals(10, e.getFieldValue()); + e.setFieldValue(20); + break; + } + } + + public void /*IFieldMergingCallback.*/imageFieldMerging(ImageFieldMergingArgs e) { + // Do nothing + } + } + //ExEnd + + //ExStart + //ExFor:DocumentBuilder.MoveToMergeField(String) + //ExFor:FieldMergingArgsBase.FieldName + //ExFor:FieldMergingArgsBase.TableName + //ExFor:FieldMergingArgsBase.RecordIndex + //ExSummary:Shows how to insert checkbox form fields into a document during mail merge. + @Test //ExSkip + public void insertCheckBox() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startTable(); + builder.insertCell(); + builder.insertField(" MERGEFIELD TableStart:StudentCourse "); + builder.insertCell(); + builder.insertField(" MERGEFIELD CourseName "); + builder.insertCell(); + builder.insertField(" MERGEFIELD TableEnd:StudentCourse "); + builder.endTable(); + + // Add a handler for the MergeField event + doc.getMailMerge().setFieldMergingCallback(new HandleMergeFieldInsertCheckBox()); + + // Execute mail merge with regions + DataTable dataTable = getStudentCourseDataTable(); + doc.getMailMerge().executeWithRegions(dataTable); + + // Save resulting document with a new name + doc.save(getArtifactsDir() + "MailMergeEvent.InsertCheckBox.docx"); + } + + private class HandleMergeFieldInsertCheckBox implements IFieldMergingCallback { + // This is called for each merge field in the document + // when Document.MailMerge.ExecuteWithRegions is called. + public void fieldMerging(final FieldMergingArgs args) throws Exception { + if (args.getDocumentFieldName().equals("CourseName")) { + // The name of the table that we are merging can be found here + Assert.assertEquals(args.getTableName(), "StudentCourse"); + + // Insert the checkbox for this merge field, using DocumentBuilder + DocumentBuilder builder = new DocumentBuilder(args.getDocument()); + builder.moveToMergeField(args.getFieldName()); + builder.insertCheckBox(args.getDocumentFieldName() + mCheckBoxCount, false, 0); + // Get the actual value of the field + String fieldValue = args.getFieldValue().toString(); + + // In this case, for every record index 'n', the corresponding field value is "Course n" + Assert.assertEquals(args.getRecordIndex(), Character.getNumericValue(fieldValue.charAt(7))); + + builder.write(fieldValue); + mCheckBoxCount++; + } + } + + public void imageFieldMerging(final ImageFieldMergingArgs args) { + // Do nothing + } + + // Counter for CheckBox name generation. + private int mCheckBoxCount; + } + + // Create DataTable and fill it with data. + // In real life this DataTable should be filled from a database. + private static DataTable getStudentCourseDataTable() throws Exception { + DataTable dataTable = new DataTable("StudentCourse"); + dataTable.getColumns().add("CourseName"); + for (int i = 0; i < 10; i++) { + DataRow datarow = dataTable.newRow(); + dataTable.getRows().add(datarow); + datarow.set(0, "Course " + i); + } + return dataTable; + } + //ExEnd + + //ExStart + //ExFor:MailMerge.ExecuteWithRegions(DataTable) + //ExSummary:Demonstrates how to implement custom logic in the MergeField event to apply cell formatting. + @Test //ExSkip + public void alternatingRows() throws Exception { + Document doc = new Document(getMyDir() + "Mail merge destination - Northwind suppliers.docx"); + + // Add a handler for the MergeField event + doc.getMailMerge().setFieldMergingCallback(new HandleMergeFieldAlternatingRows()); + + // Execute mail merge with regions + DataTable dataTable = getSuppliersDataTable(); + doc.getMailMerge().executeWithRegions(dataTable); + + doc.save(getArtifactsDir() + "MailMergeEvent.AlternatingRows.docx"); + } + + private class HandleMergeFieldAlternatingRows implements IFieldMergingCallback { + // Called for every merge field encountered in the document. + // We can either return some data to the mail merge engine or do something + // else with the document. In this case we modify cell formatting. + public void fieldMerging(final FieldMergingArgs args) throws Exception { + if (mBuilder == null) { + mBuilder = new DocumentBuilder(args.getDocument()); + } + + // This way we catch the beginning of a new row + if (args.getFieldName().equals("CompanyName")) { + // Select the color depending on whether the row number is even or odd + Color rowColor; + if (isOdd(mRowIdx)) rowColor = new Color(213, 227, 235); + else rowColor = new Color(242, 242, 242); + + // There is no way to set cell properties for the whole row at the moment, + // so we have to iterate over all cells in the row + for (int colIdx = 0; colIdx < 4; colIdx++) { + mBuilder.moveToCell(0, mRowIdx, colIdx, 0); + mBuilder.getCellFormat().getShading().setBackgroundPatternColor(rowColor); + } + + mRowIdx++; + } + } + + public void imageFieldMerging(final ImageFieldMergingArgs args) { + // Do nothing + } + + private DocumentBuilder mBuilder; + private int mRowIdx; + } + + /* + // Returns true if the value is odd; false if the value is even. + */ + + private static boolean isOdd(final int value) { + return (value % 2 != 0); + } + + // Create DataTable and fill it with data. + // In real life this DataTable should be filled from a database. + private static DataTable getSuppliersDataTable() throws Exception { + DataTable dataTable = new DataTable("Suppliers"); + dataTable.getColumns().add("CompanyName"); + dataTable.getColumns().add("ContactName"); + for (int i = 0; i < 10; i++) { + DataRow datarow = dataTable.newRow(); + dataTable.getRows().add(datarow); + datarow.set(0, "Company " + i); + datarow.set(1, "Contact " + i); + } + + return dataTable; + } + //ExEnd + + @Test + public void imageFromUrl() throws Exception { + //ExStart + //ExFor:MailMerge.Execute(String[], Object[]) + //ExSummary:Demonstrates how to merge an image from a web address using an Image field. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertField("MERGEFIELD Image:Logo "); + + // Pass a URL which points to the image to merge into the document + doc.getMailMerge().execute(new String[]{"Logo"}, new Object[]{DocumentHelper.getBytesFromStream(getAsposelogoUri().toURL().openStream())}); + + doc.save(getArtifactsDir() + "MailMergeEvent.ImageFromUrl.doc"); + //ExEnd + + // Verify the image was merged into the document + Shape logoImage = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + Assert.assertNotNull(logoImage); + Assert.assertTrue(logoImage.hasImage()); + } + + //ExStart + //ExFor:MailMerge.FieldMergingCallback + //ExFor:MailMerge.ExecuteWithRegions(IDataReader,String) + //ExFor:IFieldMergingCallback + //ExFor:ImageFieldMergingArgs + //ExFor:IFieldMergingCallback.FieldMerging + //ExFor:IFieldMergingCallback.ImageFieldMerging + //ExFor:ImageFieldMergingArgs.ImageStream + //ExSummary:Shows how to insert images stored in a database BLOB field into a report. + @Test(groups = "SkipMono") //ExSkip + public void imageFromBlob() throws Exception { + Document doc = new Document(getMyDir() + "Mail merge destination - Northwind employees.docx"); + + // Set up the event handler for image fields + doc.getMailMerge().setFieldMergingCallback(new HandleMergeImageFieldFromBlob()); + + // Loads the driver + Class.forName("net.ucanaccess.jdbc.UcanaccessDriver"); + + // Open the database connection + String connString = "jdbc:ucanaccess://" + getDatabaseDir() + "Northwind.accdb"; + + // DSN-less DB connection + java.sql.Connection conn = java.sql.DriverManager.getConnection(connString, "Admin", ""); + + // Create and execute a command + java.sql.Statement statement = conn.createStatement(); + java.sql.ResultSet resultSet = statement.executeQuery("SELECT * FROM Employees"); + + DataTable table = new DataTable(resultSet, "Employees"); + + // Perform mail merge + doc.getMailMerge().executeWithRegions(table); + + // Close the database + conn.close(); + + doc.save(getArtifactsDir() + "MailMergeEvent.ImageFromBlob.docx"); + } + + private class HandleMergeImageFieldFromBlob implements IFieldMergingCallback { + public void fieldMerging(final FieldMergingArgs args) { + // Do nothing + } + + // This is called when mail merge engine encounters Image:XXX merge field in the document. + // You have a chance to return an Image object, file name or a stream that contains the image. + public void imageFieldMerging(final ImageFieldMergingArgs e) { + // The field value is a byte array, just cast it and create a stream on it + ByteArrayInputStream imageStream = new ByteArrayInputStream((byte[]) e.getFieldValue()); + // Now the mail merge engine will retrieve the image from the stream + e.setImageStream(imageStream); + } + } + //ExEnd +} + diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExMarkdownLoadOptions.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExMarkdownLoadOptions.java new file mode 100644 index 00000000..b4611eda --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExMarkdownLoadOptions.java @@ -0,0 +1,83 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; +import java.text.MessageFormat; + +@Test +class ExMarkdownLoadOptions extends ApiExampleBase +{ + @Test + public void preserveEmptyLines() throws Exception + { + //ExStart:PreserveEmptyLines + //GistId:9c17d666c47318436785490829a3984f + //ExFor:MarkdownLoadOptions + //ExFor:MarkdownLoadOptions.#ctor + //ExFor:MarkdownLoadOptions.PreserveEmptyLines + //ExSummary:Shows how to preserve empty line while load a document. + String mdText = MessageFormat.format("{0}Line1{0}{0}Line2{0}{0}", System.lineSeparator()); + + MarkdownLoadOptions loadOptions = new MarkdownLoadOptions(); + loadOptions.setPreserveEmptyLines(true); + Document doc = new Document(new ByteArrayInputStream(mdText.getBytes()), loadOptions); + + Assert.assertEquals("\rLine1\r\rLine2\r\f", doc.getText()); + //ExEnd:PreserveEmptyLines + } + + @Test + public void importUnderlineFormatting() throws Exception + { + //ExStart:ImportUnderlineFormatting + //GistId:6280fd6c1c1854468bea095ec2af902b + //ExFor:MarkdownLoadOptions.ImportUnderlineFormatting + //ExSummary:Shows how to recognize plus characters "++" as underline text formatting. + try (ByteArrayInputStream stream = new ByteArrayInputStream("++12 and B++".getBytes(StandardCharsets.US_ASCII))) + { + MarkdownLoadOptions loadOptions = new MarkdownLoadOptions(); { loadOptions.setImportUnderlineFormatting(true); } + Document doc = new Document(stream, loadOptions); + + Paragraph para = (Paragraph)doc.getChild(NodeType.PARAGRAPH, 0, true); + Assert.assertEquals(Underline.SINGLE, para.getRuns().get(0).getFont().getUnderline()); + + loadOptions = new MarkdownLoadOptions(); { loadOptions.setImportUnderlineFormatting(false); } + doc = new Document(stream, loadOptions); + + para = (Paragraph)doc.getChild(NodeType.PARAGRAPH, 0, true); + Assert.assertEquals(Underline.NONE, para.getRuns().get(0).getFont().getUnderline()); + } + //ExEnd:ImportUnderlineFormatting + } + + @Test + public void softLineBreakCharacter() throws Exception + { + //ExStart:SoftLineBreakCharacter + //GistId:571cc6e23284a2ec075d15d4c32e3bbf + //ExFor:MarkdownLoadOptions.SoftLineBreakCharacter + //ExSummary:Shows how to set soft line break character. + try (ByteArrayInputStream stream = new ByteArrayInputStream("line1\nline2".getBytes(StandardCharsets.UTF_8))) + { + MarkdownLoadOptions loadOptions = new MarkdownLoadOptions(); + loadOptions.setSoftLineBreakCharacter(ControlChar.LINE_BREAK_CHAR); + Document doc = new Document(stream, loadOptions); + + Assert.assertEquals("line1\u000bline2", doc.getText().trim()); + } + //ExEnd:SoftLineBreakCharacter + } +} + diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExMarkdownSaveOptions.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExMarkdownSaveOptions.java new file mode 100644 index 00000000..5e65b889 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExMarkdownSaveOptions.java @@ -0,0 +1,445 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.FileOutputStream; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.function.Supplier; +import java.util.stream.Stream; + +@Test +public class ExMarkdownSaveOptions extends ApiExampleBase +{ + @Test (dataProvider = "markdownDocumentTableContentAlignmentDataProvider") + public void markdownDocumentTableContentAlignment(int tableContentAlignment) throws Exception + { + //ExStart + //ExFor:TableContentAlignment + //ExFor:MarkdownSaveOptions.TableContentAlignment + //ExSummary:Shows how to align contents in tables. + DocumentBuilder builder = new DocumentBuilder(); + + builder.insertCell(); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.RIGHT); + builder.write("Cell1"); + builder.insertCell(); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.write("Cell2"); + + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); { saveOptions.setTableContentAlignment(tableContentAlignment); } + + builder.getDocument().save(getArtifactsDir() + "MarkdownSaveOptions.MarkdownDocumentTableContentAlignment.md", saveOptions); + + Document doc = new Document(getArtifactsDir() + "MarkdownSaveOptions.MarkdownDocumentTableContentAlignment.md"); + Table table = doc.getFirstSection().getBody().getTables().get(0); + + switch (tableContentAlignment) + { + case TableContentAlignment.AUTO: + Assert.assertEquals(ParagraphAlignment.RIGHT, + table.getFirstRow().getCells().get(0).getFirstParagraph().getParagraphFormat().getAlignment()); + Assert.assertEquals(ParagraphAlignment.CENTER, + table.getFirstRow().getCells().get(1).getFirstParagraph().getParagraphFormat().getAlignment()); + break; + case TableContentAlignment.LEFT: + Assert.assertEquals(ParagraphAlignment.LEFT, + table.getFirstRow().getCells().get(0).getFirstParagraph().getParagraphFormat().getAlignment()); + Assert.assertEquals(ParagraphAlignment.LEFT, + table.getFirstRow().getCells().get(1).getFirstParagraph().getParagraphFormat().getAlignment()); + break; + case TableContentAlignment.CENTER: + Assert.assertEquals(ParagraphAlignment.CENTER, + table.getFirstRow().getCells().get(0).getFirstParagraph().getParagraphFormat().getAlignment()); + Assert.assertEquals(ParagraphAlignment.CENTER, + table.getFirstRow().getCells().get(1).getFirstParagraph().getParagraphFormat().getAlignment()); + break; + case TableContentAlignment.RIGHT: + Assert.assertEquals(ParagraphAlignment.RIGHT, + table.getFirstRow().getCells().get(0).getFirstParagraph().getParagraphFormat().getAlignment()); + Assert.assertEquals(ParagraphAlignment.RIGHT, + table.getFirstRow().getCells().get(1).getFirstParagraph().getParagraphFormat().getAlignment()); + break; + } + //ExEnd + } + + @DataProvider(name = "markdownDocumentTableContentAlignmentDataProvider") + public static Object[][] markdownDocumentTableContentAlignmentDataProvider() throws Exception + { + return new Object[][] + { + {TableContentAlignment.LEFT}, + {TableContentAlignment.RIGHT}, + {TableContentAlignment.CENTER}, + {TableContentAlignment.AUTO}, + }; + } + + //ExStart + //ExFor:MarkdownSaveOptions + //ExFor:MarkdownSaveOptions.#ctor + //ExFor:MarkdownSaveOptions.ImageSavingCallback + //ExFor:MarkdownSaveOptions.SaveFormat + //ExFor:IImageSavingCallback + //ExSummary:Shows how to rename the image name during saving into Markdown document. + @Test //ExSkip + public void renameImages() throws Exception { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + // If we convert a document that contains images into Markdown, we will end up with one Markdown file which links to several images. + // Each image will be in the form of a file in the local file system. + // There is also a callback that can customize the name and file system location of each image. + saveOptions.setImageSavingCallback(new SavedImageRename("MarkdownSaveOptions.HandleDocument.md")); + saveOptions.setSaveFormat(SaveFormat.MARKDOWN); + + // The ImageSaving() method of our callback will be run at this time. + doc.save(getArtifactsDir() + "MarkdownSaveOptions.HandleDocument.md", saveOptions); + + Supplier> filteredShapes = () -> DocumentHelper.directoryGetFiles( + getArtifactsDir(), "*").stream(). + filter(s -> s.startsWith(getArtifactsDir() + "MarkdownSaveOptions.HandleDocument.md shape")); + + Assert.assertEquals(1, filteredShapes.get().filter(f -> f.endsWith(".jpeg")).count()); + Assert.assertEquals(8, filteredShapes.get().filter(f -> f.endsWith(".png")).count()); + } + + /// + /// Renames saved images that are produced when an Markdown document is saved. + /// + public static class SavedImageRename implements IImageSavingCallback + { + public SavedImageRename(String outFileName) + { + mOutFileName = outFileName; + } + + public void imageSaving(ImageSavingArgs args) throws Exception + { + String imageFileName = MessageFormat.format("{0} shape {1}, of type {2}.{3}", + mOutFileName, ++mCount, args.getCurrentShape().getShapeType(), + FilenameUtils.getExtension(args.getImageFileName())); + + args.setImageFileName(imageFileName); + args.setImageStream(new FileOutputStream(getArtifactsDir() + imageFileName)); + + Assert.assertTrue(args.isImageAvailable()); + Assert.assertFalse(args.getKeepImageStreamOpen()); + } + + private int mCount; + private String mOutFileName; + } + //ExEnd + + @Test (dataProvider = "exportImagesAsBase64DataProvider") + public void exportImagesAsBase64(boolean exportImagesAsBase64) throws Exception + { + //ExStart + //ExFor:MarkdownSaveOptions.ExportImagesAsBase64 + //ExSummary:Shows how to save a .md document with images embedded inside it. + Document doc = new Document(getMyDir() + "Images.docx"); + + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); { saveOptions.setExportImagesAsBase64(exportImagesAsBase64); } + + doc.save(getArtifactsDir() + "MarkdownSaveOptions.ExportImagesAsBase64.md", saveOptions); + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "MarkdownSaveOptions.ExportImagesAsBase64.md"), Charset.forName("UTF-8")); + + Assert.assertTrue(exportImagesAsBase64 + ? outDocContents.contains("data:image/jpeg;base64") + : outDocContents.contains("MarkdownSaveOptions.ExportImagesAsBase64.001.jpeg")); + //ExEnd + } + + @DataProvider(name = "exportImagesAsBase64DataProvider") + public static Object[][] exportImagesAsBase64DataProvider() { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test (dataProvider = "listExportModeDataProvider") + public void listExportMode(int markdownListExportMode) throws Exception + { + //ExStart + //ExFor:MarkdownSaveOptions.ListExportMode + //ExFor:MarkdownListExportMode + //ExSummary:Shows how to list items will be written to the markdown document. + Document doc = new Document(getMyDir() + "List item.docx"); + + // Use MarkdownListExportMode.PlainText or MarkdownListExportMode.MarkdownSyntax to export list. + MarkdownSaveOptions options = new MarkdownSaveOptions(); { options.setListExportMode(markdownListExportMode); } + doc.save(getArtifactsDir() + "MarkdownSaveOptions.ListExportMode.md", options); + //ExEnd + } + + @DataProvider(name = "listExportModeDataProvider") + public static Object[][] listExportModeDataProvider() { + return new Object[][] + { + {MarkdownListExportMode.PLAIN_TEXT}, + {MarkdownListExportMode.MARKDOWN_SYNTAX}, + }; + } + + @Test + public void imagesFolder() throws Exception + { + //ExStart + //ExFor:MarkdownSaveOptions.ImagesFolder + //ExFor:MarkdownSaveOptions.ImagesFolderAlias + //ExSummary:Shows how to specifies the name of the folder used to construct image URIs. + DocumentBuilder builder = new DocumentBuilder(); + + builder.writeln("Some image below:"); + builder.insertImage(getImageDir() + "Logo.jpg"); + + String imagesFolder = Paths.get(getArtifactsDir(), "ImagesDir").toString(); + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + // Use the "ImagesFolder" property to assign a folder in the local file system into which + // Aspose.Words will save all the document's linked images. + saveOptions.setImagesFolder(imagesFolder); + // Use the "ImagesFolderAlias" property to use this folder + // when constructing image URIs instead of the images folder's name. + saveOptions.setImagesFolderAlias("http://example.com/images"); + + builder.getDocument().save(getArtifactsDir() + "MarkdownSaveOptions.ImagesFolder.md", saveOptions); + //ExEnd + + ArrayList dirFiles = DocumentHelper.directoryGetFiles(imagesFolder, "MarkdownSaveOptions.ImagesFolder.001.jpeg"); + Assert.assertEquals(1, dirFiles.size()); + Document doc = new Document(getArtifactsDir() + "MarkdownSaveOptions.ImagesFolder.md"); + doc.getText().contains("http://example.com/images/MarkdownSaveOptions.ImagesFolder.001.jpeg"); + } + + @Test + public void exportUnderlineFormatting() throws Exception + { + //ExStart:ExportUnderlineFormatting + //GistId:b9e728d2381f759edd5b31d64c1c4d3f + //ExFor:MarkdownSaveOptions.ExportUnderlineFormatting + //ExSummary:Shows how to export underline formatting as ++. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.setUnderline(Underline.SINGLE); + builder.write("Lorem ipsum. Dolor sit amet."); + + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + saveOptions.setExportUnderlineFormatting(true); + doc.save(getArtifactsDir() + "MarkdownSaveOptions.ExportUnderlineFormatting.md", saveOptions); + //ExEnd:ExportUnderlineFormatting + } + + @Test + public void linkExportMode() throws Exception + { + //ExStart:LinkExportMode + //GistId:67585b023474b7f73b0066dd022cf938 + //ExFor:MarkdownSaveOptions.LinkExportMode + //ExFor:MarkdownLinkExportMode + //ExSummary:Shows how to links will be written to the .md file. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertShape(ShapeType.BALLOON, 100.0, 100.0); + + // Image will be written as reference: + // ![ref1] + // + // [ref1]: aw_ref.001.png + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + saveOptions.setLinkExportMode(MarkdownLinkExportMode.REFERENCE); + doc.save(getArtifactsDir() + "MarkdownSaveOptions.LinkExportMode.Reference.md", saveOptions); + + // Image will be written as inline: + // ![](aw_inline.001.png) + saveOptions.setLinkExportMode(MarkdownLinkExportMode.INLINE); + doc.save(getArtifactsDir() + "MarkdownSaveOptions.LinkExportMode.Inline.md", saveOptions); + //ExEnd:LinkExportMode + + String outDocContents = Files.readAllLines(Paths.get(getArtifactsDir() + "MarkdownSaveOptions.LinkExportMode.Inline.md")).get(1); + Assert.assertEquals("![](MarkdownSaveOptions.LinkExportMode.Inline.001.png)", outDocContents.trim()); + } + + @Test + public void exportTableAsHtml() throws Exception + { + //ExStart:ExportTableAsHtml + //GistId:3f058a176ba0e9f656c60c6d60d757a1 + //ExFor:MarkdownExportAsHtml + //ExFor:MarkdownSaveOptions.ExportAsHtml + //ExSummary:Shows how to export a table to Markdown as raw HTML. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Sample table:"); + + // Create table. + builder.insertCell(); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.RIGHT); + builder.write("Cell1"); + builder.insertCell(); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.write("Cell2"); + + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + saveOptions.setExportAsHtml(MarkdownExportAsHtml.TABLES); + + doc.save(getArtifactsDir() + "MarkdownSaveOptions.ExportTableAsHtml.md", saveOptions); + //ExEnd:ExportTableAsHtml + + String outDocContents = FileUtils.readFileToString(new File(getArtifactsDir() + "MarkdownSaveOptions.ExportTableAsHtml.md"), StandardCharsets.UTF_8); + Assert.assertEquals("\uFEFFSample table:\r\n" + + "
          " + + "

          Cell1

          " + + "
          " + + "

          Cell2

          " + + "
          ", outDocContents.trim()); + } + + @Test + public void imageResolution() throws Exception + { + //ExStart:ImageResolution + //GistId:f86d49dc0e6781b93e576539a01e6ca2 + //ExFor:MarkdownSaveOptions.ImageResolution + //ExSummary:Shows how to set the output resolution for images. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + saveOptions.setImageResolution(300); + + doc.save(getArtifactsDir() + "MarkdownSaveOptions.ImageResolution.md", saveOptions); + //ExEnd:ImageResolution + } + + @Test + public void officeMathExportMode() throws Exception + { + //ExStart:OfficeMathExportMode + //GistId:f86d49dc0e6781b93e576539a01e6ca2 + //ExFor:MarkdownSaveOptions.OfficeMathExportMode + //ExFor:MarkdownOfficeMathExportMode + //ExSummary:Shows how OfficeMath will be written to the document. + Document doc = new Document(getMyDir() + "Office math.docx"); + + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + saveOptions.setOfficeMathExportMode(MarkdownOfficeMathExportMode.IMAGE); + + doc.save(getArtifactsDir() + "MarkdownSaveOptions.OfficeMathExportMode.md", saveOptions); + //ExEnd:OfficeMathExportMode + } + + @Test (dataProvider = "emptyParagraphExportModeDataProvider") + public void emptyParagraphExportMode(int exportMode) throws Exception + { + //ExStart:EmptyParagraphExportMode + //GistId:ad73e0dd58a8c2ae742bb64f8561df35 + //ExFor:MarkdownEmptyParagraphExportMode + //ExFor:MarkdownSaveOptions.EmptyParagraphExportMode + //ExSummary:Shows how to export empty paragraphs. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("First"); + builder.writeln("\r\n\r\n\r\n"); + builder.writeln("Last"); + + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + saveOptions.setEmptyParagraphExportMode(exportMode); + + doc.save(getArtifactsDir() + "MarkdownSaveOptions.EmptyParagraphExportMode.md", saveOptions); + + String result = FileUtils.readFileToString( new File(getArtifactsDir() + "MarkdownSaveOptions.EmptyParagraphExportMode.md"), StandardCharsets.UTF_8); + + switch (exportMode) + { + case MarkdownEmptyParagraphExportMode.NONE: + Assert.assertEquals("\uFEFFFirst\r\n\r\nLast\r\n", result); + break; + case MarkdownEmptyParagraphExportMode.EMPTY_LINE: + Assert.assertEquals("\uFEFFFirst\r\n\r\n\r\n\r\n\r\nLast\r\n\r\n", result); + break; + case MarkdownEmptyParagraphExportMode.MARKDOWN_HARD_LINE_BREAK: + Assert.assertEquals("\uFEFFFirst\r\n\\\r\n\\\r\n\\\r\n\\\r\n\\\r\nLast\r\n
          \r\n", result); + break; + } + //ExEnd:EmptyParagraphExportMode + } + + @DataProvider(name = "emptyParagraphExportModeDataProvider") + public static Object[][] emptyParagraphExportModeDataProvider() throws Exception + { + return new Object[][] + { + {MarkdownEmptyParagraphExportMode.NONE}, + {MarkdownEmptyParagraphExportMode.EMPTY_LINE}, + {MarkdownEmptyParagraphExportMode.MARKDOWN_HARD_LINE_BREAK}, + }; + } + + @Test + public void nonCompatibleTables() throws Exception + { + //ExStart:NonCompatibleTables + //GistId:571cc6e23284a2ec075d15d4c32e3bbf + //ExFor:MarkdownExportAsHtml + //ExSummary:Shows how to export tables that cannot be correctly represented in pure Markdown as raw HTML. + String outputPath = getArtifactsDir() + "MarkdownSaveOptions.NonCompatibleTables.md"; + + Document doc = new Document(getMyDir() + "Non compatible table.docx"); + + // With the "NonCompatibleTables" option, you can export tables that have a complex structure with merged cells + // or nested tables to raw HTML and leave simple tables in Markdown format. + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + saveOptions.setExportAsHtml(MarkdownExportAsHtml.NON_COMPATIBLE_TABLES); + + doc.save(outputPath, saveOptions); + //ExEnd:NonCompatibleTables + + DocumentHelper.findTextInFile(outputPath, ""); + DocumentHelper.findTextInFile(outputPath, "|Heading 1|Heading 2|"); + } + + @Test + public void exportOfficeMathAsLatex() throws Exception + { + //ExStart:ExportOfficeMathAsLatex + //GistId:045648ef22da6b384ebcf0344717bfb5 + //ExFor:MarkdownSaveOptions.OfficeMathExportMode + //ExFor:MarkdownOfficeMathExportMode + //ExSummary:Shows how to export OfficeMath object as Latex. + Document doc = new Document(getMyDir() + "Office math.docx"); + + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + saveOptions.setOfficeMathExportMode(MarkdownOfficeMathExportMode.LATEX); + + doc.save(getArtifactsDir() + "MarkdownSaveOptions.ExportOfficeMathAsLatex.md", saveOptions); + //ExEnd:ExportOfficeMathAsLatex + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "MarkdownSaveOptions.ExportOfficeMathAsLatex.md", + getGoldsDir() + "MarkdownSaveOptions.ExportOfficeMathAsLatex.Gold.md")); + } +} + diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExMetered.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExMetered.java new file mode 100644 index 00000000..1bbf862a --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExMetered.java @@ -0,0 +1,56 @@ +package Examples; + +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.Document; +import com.aspose.words.Metered; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.text.MessageFormat; + +@Test +public class ExMetered extends ApiExampleBase { + @Test + public void testMeteredUsage() { + Assert.assertThrows(IllegalStateException.class, () -> usage()); + } + + @Test(enabled = false) + public void usage() throws Exception { + //ExStart + //ExFor:Metered + //ExFor:Metered.#ctor + //ExFor:Metered.GetConsumptionCredit + //ExFor:Metered.GetConsumptionQuantity + //ExFor:Metered.SetMeteredKey(String, String) + //ExFor:Metered.IsMeteredLicensed + //ExFor:Metered.GetProductName + //ExSummary:Shows how to activate a Metered license and track credit/consumption. + // Create a new Metered license, and then print its usage statistics. + Metered metered = new Metered(); + metered.setMeteredKey("MyPublicKey", "MyPrivateKey"); + + System.out.println("Is metered license accepted: {Metered.IsMeteredLicensed()}"); + System.out.println("Product name: {metered.GetProductName()}"); + System.out.println("Credit before operation: {Metered.GetConsumptionCredit()}"); + System.out.println("Consumption quantity before operation: {Metered.GetConsumptionQuantity()}"); + + // Operate using Aspose.Words, and then print our metered stats again to see how much we spent. + Document doc = new Document(getMyDir() + "Document.docx"); + doc.save(getArtifactsDir() + "Metered.Usage.pdf"); + + // Aspose Metered Licensing mechanism does not send the usage data to purchase server every time, + // you need to use waiting. + Thread.sleep(10000); + + System.out.println(MessageFormat.format("Credit after operation: {0}", Metered.getConsumptionCredit())); + System.out.println(MessageFormat.format("Consumption quantity after operation: {0}", Metered.getConsumptionQuantity())); + //ExEnd + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExMossDoc2Pdf.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExMossDoc2Pdf.java new file mode 100644 index 00000000..b16ab767 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExMossDoc2Pdf.java @@ -0,0 +1,108 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.Document; +import com.aspose.words.PdfSaveOptions; + +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.nio.charset.StandardCharsets; +import java.util.Date; + +/** + * DOC2PDF document converter for SharePoint. + * Uses Aspose.Words to perform the conversion. + */ +public class ExMossDoc2Pdf { + /** + * The main entry point for the application. + */ + public static void mossDoc2Pdf(final String[] args) throws Exception { + // Although SharePoint passes "-log " to us and we are + // supposed to log there, we will use our hardcoded path to the log file for the sake of simplicity. + // + // Make sure there are permissions to write into this folder. + // The document converter will be called under the document + // conversion account (not sure what name), so for testing purposes, + // I would give the Users group write permissions into this folder. + OutputStream os = new FileOutputStream("C:\\Aspose2Pdf\\log.txt", true); + gLog = new OutputStreamWriter(os, StandardCharsets.UTF_8); + + try { + gLog.write(new Date().toString() + " Started"); + gLog.write(System.getProperty("sun.java.command")); + + parseCommandLine(args); + + // Uncomment the code below when you have purchased a licenses for Aspose.Words. + // + // You need to deploy the license in the same folder as your + // executable, alternatively you can add the license file as an + // embedded resource to your project. + // + // // Set license for Aspose.Words. + // Aspose.Words.License wordsLicense = new Aspose.Words.License(); + // wordsLicense.SetLicense("Aspose.Total.lic"); + + convertDoc2Pdf(gInFileName, gOutFileName); + } catch (Exception e) { + gLog.write(e.getMessage()); + gLog.close(); + os.close(); + System.exit(100); + } finally { + gLog.close(); + os.close(); + } + } + + private static void parseCommandLine(final String[] args) throws Exception { + int i = 0; + while (i < args.length) { + String s = args[i]; + switch (s.toLowerCase()) { + case "-in": + i++; + gInFileName = args[i]; + break; + case "-out": + i++; + gOutFileName = args[i]; + break; + case "-config": + // Skip the name of the config file and do nothing. + i++; + break; + case "-log": + // Skip the name of the log file and do nothing. + i++; + break; + default: + throw new Exception("Unknown command line argument: " + s); + } + i++; + } + } + + private static void convertDoc2Pdf(final String inFileName, final String outFileName) throws Exception { + // You can load not only DOC here, but any format supported by + // Aspose.Words: DOC, DOCX, RTF, WordML, HTML, MHTML, ODT etc. + Document doc = new Document(inFileName); + + doc.save(outFileName, new PdfSaveOptions()); + } + + private static String gInFileName; + private static String gOutFileName; + private static Writer gLog; + +} \ No newline at end of file diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExMossRtf2Docx.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExMossRtf2Docx.java new file mode 100644 index 00000000..cd6b7b9a --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExMossRtf2Docx.java @@ -0,0 +1,22 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.Document; +import com.aspose.words.SaveFormat; + +public class ExMossRtf2Docx { + public static void convertRtfToDocx(final String inFileName, final String outFileName) throws Exception { + // Load an RTF file into Aspose.Words. + Document doc = new Document(inFileName); + + // Save the document in the OOXML format. + doc.save(outFileName, SaveFormat.DOCX); + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExNode.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExNode.java new file mode 100644 index 00000000..863bcf90 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExNode.java @@ -0,0 +1,621 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.lang.reflect.Array; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.Iterator; + +public class ExNode extends ApiExampleBase { + @Test + public void cloneCompositeNode() throws Exception { + //ExStart + //ExFor:Node + //ExFor:Node.Clone + //ExSummary:Shows how to clone a composite node. + Document doc = new Document(); + Paragraph para = doc.getFirstSection().getBody().getFirstParagraph(); + para.appendChild(new Run(doc, "Hello world!")); + + // Below are two ways of cloning a composite node. + // 1 - Create a clone of a node, and create a clone of each of its child nodes as well. + Node cloneWithChildren = para.deepClone(true); + + Assert.assertTrue(((CompositeNode) cloneWithChildren).hasChildNodes()); + Assert.assertEquals("Hello world!", cloneWithChildren.getText().trim()); + + // 2 - Create a clone of a node just by itself without any children. + Node cloneWithoutChildren = para.deepClone(false); + + Assert.assertFalse(((CompositeNode) cloneWithoutChildren).hasChildNodes()); + Assert.assertEquals("", cloneWithoutChildren.getText().trim()); + //ExEnd + } + + @Test + public void getParentNode() throws Exception { + //ExStart + //ExFor:Node.ParentNode + //ExSummary:Shows how to access a node's parent node. + Document doc = new Document(); + Paragraph para = doc.getFirstSection().getBody().getFirstParagraph(); + + // Append a child Run node to the document's first paragraph. + Run run = new Run(doc, "Hello world!"); + para.appendChild(run); + + // The paragraph is the parent node of the run node. We can trace this lineage + // all the way to the document node, which is the root of the document's node tree. + Assert.assertEquals(para, run.getParentNode()); + Assert.assertEquals(doc.getFirstSection().getBody(), para.getParentNode()); + Assert.assertEquals(doc.getFirstSection(), doc.getFirstSection().getBody().getParentNode()); + Assert.assertEquals(doc, doc.getFirstSection().getParentNode()); + //ExEnd + } + + @Test + public void ownerDocument() throws Exception { + //ExStart + //ExFor:Node.Document + //ExFor:Node.ParentNode + //ExSummary:Shows how to create a node and set its owning document. + Document doc = new Document(); + Paragraph para = new Paragraph(doc); + para.appendChild(new Run(doc, "Hello world!")); + + // We have not yet appended this paragraph as a child to any composite node. + Assert.assertNull(para.getParentNode()); + + // If a node is an appropriate child node type of another composite node, + // we can attach it as a child only if both nodes have the same owner document. + // The owner document is the document we passed to the node's constructor. + // We have not attached this paragraph to the document, so the document does not contain its text. + Assert.assertEquals(para.getDocument(), doc); + Assert.assertEquals("", doc.getText().trim()); + + // Since the document owns this paragraph, we can apply one of its styles to the paragraph's contents. + para.getParagraphFormat().setStyleName("Heading 1"); + + // Add this node to the document, and then verify its contents. + doc.getFirstSection().getBody().appendChild(para); + + Assert.assertEquals(doc.getFirstSection().getBody(), para.getParentNode()); + Assert.assertEquals("Hello world!", doc.getText().trim()); + //ExEnd + + Assert.assertEquals(para.getDocument(), doc); + Assert.assertNotNull(para.getParentNode()); + } + + @Test + public void childNodesEnumerate() throws Exception { + //ExStart + //ExFor:Node + //ExFor:Node.CustomNodeId + //ExFor:NodeType + //ExFor:CompositeNode + //ExFor:CompositeNode.GetChild + //ExFor:CompositeNode.GetChildNodes(NodeType, bool) + //ExFor:NodeCollection.Count + //ExFor:NodeCollection.Item + //ExSummary:Shows how to traverse through a composite node's collection of child nodes. + Document doc = new Document(); + + // Add two runs and one shape as child nodes to the first paragraph of this document. + Paragraph paragraph = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 0, true); + paragraph.appendChild(new Run(doc, "Hello world! ")); + + Shape shape = new Shape(doc, ShapeType.RECTANGLE); + shape.setWidth(200.0); + shape.setHeight(200.0); + // Note that the 'CustomNodeId' is not saved to an output file and exists only during the node lifetime. + shape.setCustomNodeId(100); + shape.setWrapType(WrapType.INLINE); + paragraph.appendChild(shape); + + paragraph.appendChild(new Run(doc, "Hello again!")); + + // Iterate through the paragraph's collection of immediate children, + // and print any runs or shapes that we find within. + NodeCollection children = paragraph.getChildNodes(NodeType.ANY, false); + + Assert.assertEquals(3, paragraph.getChildNodes(NodeType.ANY, false).getCount()); + + for (Node child : (Iterable) children) + switch (child.getNodeType()) { + case NodeType.RUN: + System.out.println("Run contents:"); + System.out.println(MessageFormat.format("\t\"{0}\"", child.getText().trim())); + break; + case NodeType.SHAPE: + Shape childShape = (Shape)child; + System.out.println("Shape:"); + System.out.println(MessageFormat.format("\t{0}, {1}x{2}", childShape.getShapeType(), childShape.getWidth(), childShape.getHeight())); + Assert.assertEquals(100, shape.getCustomNodeId()); //ExSkip + break; + } + //ExEnd + + Assert.assertEquals(NodeType.RUN, paragraph.getChild(NodeType.RUN, 0, true).getNodeType()); + Assert.assertEquals("Hello world! Hello again!", doc.getText().trim()); + } + + //ExStart + //ExFor:Node.NextSibling + //ExFor:CompositeNode.FirstChild + //ExFor:Node.IsComposite + //ExFor:CompositeNode.IsComposite + //ExFor:Node.NodeTypeToString + //ExFor:Paragraph.NodeType + //ExFor:Table.NodeType + //ExFor:Node.NodeType + //ExFor:Footnote.NodeType + //ExFor:FormField.NodeType + //ExFor:SmartTag.NodeType + //ExFor:Cell.NodeType + //ExFor:Row.NodeType + //ExFor:Document.NodeType + //ExFor:Comment.NodeType + //ExFor:Run.NodeType + //ExFor:Section.NodeType + //ExFor:SpecialChar.NodeType + //ExFor:Shape.NodeType + //ExFor:FieldEnd.NodeType + //ExFor:FieldSeparator.NodeType + //ExFor:FieldStart.NodeType + //ExFor:BookmarkStart.NodeType + //ExFor:CommentRangeEnd.NodeType + //ExFor:BuildingBlock.NodeType + //ExFor:GlossaryDocument.NodeType + //ExFor:BookmarkEnd.NodeType + //ExFor:GroupShape.NodeType + //ExFor:CommentRangeStart.NodeType + //ExSummary:Shows how to traverse a composite node's tree of child nodes. + @Test //ExSkip + public void recurseChildren() throws Exception { + Document doc = new Document(getMyDir() + "Paragraphs.docx"); + + // Any node that can contain child nodes, such as the document itself, is composite. + Assert.assertTrue(doc.isComposite()); + + // Invoke the recursive function that will go through and print all the child nodes of a composite node. + traverseAllNodes(doc, 0); + } + + /// + /// Recursively traverses a node tree while printing the type of each node + /// with an indent depending on depth as well as the contents of all inline nodes. + /// + @Test(enabled = false) //ExSkip + public void traverseAllNodes(CompositeNode parentNode, int depth) { + for (Node childNode = parentNode.getFirstChild(); childNode != null; childNode = childNode.getNextSibling()) { + System.out.println(MessageFormat.format("{0}{1}", String.format(" ", depth), Node.nodeTypeToString(childNode.getNodeType()))); + + // Recurse into the node if it is a composite node. Otherwise, print its contents if it is an inline node. + if (childNode.isComposite()) { + System.out.println(); + traverseAllNodes((CompositeNode) childNode, depth + 1); + } else if (childNode instanceof Inline) { + System.out.println(MessageFormat.format(" - \"{0}\"", childNode.getText().trim())); + } else { + System.out.println(); + } + } + } + //ExEnd + + @Test + public void removeNodes() throws Exception { + //ExStart + //ExFor:Node + //ExFor:Node.NodeType + //ExFor:Node.Remove + //ExSummary:Shows how to remove all child nodes of a specific type from a composite node. + Document doc = new Document(getMyDir() + "Tables.docx"); + + Assert.assertEquals(2, doc.getChildNodes(NodeType.TABLE, true).getCount()); + + Node curNode = doc.getFirstSection().getBody().getFirstChild(); + + while (curNode != null) { + // Save the next sibling node as a variable in case we want to move to it after deleting this node. + Node nextNode = curNode.getNextSibling(); + + // A section body can contain Paragraph and Table nodes. + // If the node is a Table, remove it from the parent. + if (curNode.getNodeType() == NodeType.TABLE) { + curNode.remove(); + } + + curNode = nextNode; + } + + Assert.assertEquals(0, doc.getChildNodes(NodeType.TABLE, true).getCount()); + //ExEnd + } + + @Test + public void enumNextSibling() throws Exception { + //ExStart + //ExFor:CompositeNode.FirstChild + //ExFor:Node.NextSibling + //ExFor:Node.NodeTypeToString + //ExFor:Node.NodeType + //ExSummary:Shows how to use a node's NextSibling property to enumerate through its immediate children. + Document doc = new Document(getMyDir() + "Paragraphs.docx"); + + for (Node node = doc.getFirstSection().getBody().getFirstChild(); node != null; node = node.getNextSibling()) { + System.out.println(Node.nodeTypeToString(node.getNodeType())); + } + //ExEnd + } + + @Test + public void typedAccess() throws Exception { + //ExStart + //ExFor:Story.Tables + //ExFor:Table.FirstRow + //ExFor:Table.LastRow + //ExFor:TableCollection + //ExSummary:Shows how to remove the first and last rows of all tables in a document. + Document doc = new Document(getMyDir() + "Tables.docx"); + + TableCollection tables = doc.getFirstSection().getBody().getTables(); + + Assert.assertEquals(5, tables.get(0).getRows().getCount()); + Assert.assertEquals(4, tables.get(1).getRows().getCount()); + + for (Table table : tables) { + if (table.getFirstRow() != null) { + table.getFirstRow().remove(); + } + + if (table.getLastRow() != null) { + table.getLastRow().remove(); + } + } + + Assert.assertEquals(3, tables.get(0).getRows().getCount()); + Assert.assertEquals(2, tables.get(1).getRows().getCount()); + //ExEnd + } + + @Test + public void removeChild() throws Exception { + //ExStart + //ExFor:CompositeNode.LastChild + //ExFor:Node.PreviousSibling + //ExFor:CompositeNode.RemoveChild``1(``0) + //ExSummary:Shows how to use of methods of Node and CompositeNode to remove a section before the last section in the document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Section 1 text."); + builder.insertBreak(BreakType.SECTION_BREAK_CONTINUOUS); + builder.writeln("Section 2 text."); + + // Both sections are siblings of each other. + Section lastSection = (Section) doc.getLastChild(); + Section firstSection = (Section) lastSection.getPreviousSibling(); + + // Remove a section based on its sibling relationship with another section. + if (lastSection.getPreviousSibling() != null) + doc.removeChild(firstSection); + + // The section we removed was the first one, leaving the document with only the second. + Assert.assertEquals("Section 2 text.", doc.getText().trim()); + //ExEnd + } + + @Test + public void selectCompositeNodes() throws Exception { + //ExStart + //ExFor:CompositeNode.SelectSingleNode + //ExFor:CompositeNode.SelectNodes + //ExFor:NodeList.GetEnumerator + //ExFor:NodeList.ToArray + //ExSummary:Shows how to select certain nodes by using an XPath expression. + Document doc = new Document(getMyDir() + "Tables.docx"); + + // This expression will extract all paragraph nodes, + // which are descendants of any table node in the document. + NodeList nodeList = doc.selectNodes("//Table//Paragraph"); + + // Iterate through the list with an enumerator and print the contents of every paragraph in each cell of the table. + int index = 0; + + Iterator e = nodeList.iterator(); + while (e.hasNext()) { + Node currentNode = e.next(); + System.out.println(MessageFormat.format("Table paragraph index {0}, contents: \"{1}\"", index++, currentNode.getText().trim())); + } + + // This expression will select any paragraphs that are direct children of any Body node in the document. + nodeList = doc.selectNodes("//Body/Paragraph"); + + // We can treat the list as an array. + Assert.assertEquals(nodeList.toArray().length, 4); + + // Use SelectSingleNode to select the first result of the same expression as above. + Node node = doc.selectSingleNode("//Body/Paragraph"); + + Assert.assertEquals(Paragraph.class, node.getClass()); + //ExEnd + } + + @Test + public void testNodeIsInsideField() throws Exception { + //ExStart + //ExFor:CompositeNode.SelectNodes + //ExSummary:Shows how to use an XPath expression to test whether a node is inside a field. + Document doc = new Document(getMyDir() + "Mail merge destination - Northwind employees.docx"); + + // The NodeList that results from this XPath expression will contain all nodes we find inside a field. + // However, FieldStart and FieldEnd nodes can be on the list if there are nested fields in the path. + // Currently does not find rare fields in which the FieldCode or FieldResult spans across multiple paragraphs. + NodeList resultList = + doc.selectNodes("//FieldStart/following-sibling::node()[following-sibling::FieldEnd]"); + Run[] runs = Arrays.stream(resultList.toArray()).filter(n -> n.getNodeType() == NodeType.RUN).toArray(Run[]::new); + Run run = runs[0]; + + // Check if the specified run is one of the nodes that are inside the field. + System.out.println(MessageFormat.format("Contents of the first Run node that''s part of a field: {0}", run.getText().trim())); + //ExEnd + } + + @Test + public void createAndAddParagraphNode() throws Exception { + Document doc = new Document(); + + Paragraph para = new Paragraph(doc); + + Section section = doc.getLastSection(); + section.getBody().appendChild(para); + } + + @Test + public void removeSmartTagsFromCompositeNode() throws Exception { + //ExStart + //ExFor:CompositeNode.RemoveSmartTags + //ExSummary:Removes all smart tags from descendant nodes of a composite node. + Document doc = new Document(getMyDir() + "Smart tags.doc"); + + Assert.assertEquals(8, doc.getChildNodes(NodeType.SMART_TAG, true).getCount()); + + doc.removeSmartTags(); + + Assert.assertEquals(0, doc.getChildNodes(NodeType.SMART_TAG, true).getCount()); + //ExEnd + } + + @Test + public void getIndexOfNode() throws Exception { + //ExStart + //ExFor:CompositeNode.IndexOf + //ExSummary:Shows how to get the index of a given child node from its parent. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + Body body = doc.getFirstSection().getBody(); + + // Retrieve the index of the last paragraph in the body of the first section. + Assert.assertEquals(24, body.getChildNodes(NodeType.ANY, false).indexOf(body.getLastParagraph())); + //ExEnd + } + + @Test + public void convertNodeToHtmlWithDefaultOptions() throws Exception { + //ExStart + //ExFor:Node.ToString(SaveFormat) + //ExFor:Node.ToString(SaveOptions) + //ExSummary:Exports the content of a node to String in HTML format. + Document doc = new Document(getMyDir() + "Document.docx"); + + Node node = doc.getLastSection().getBody().getLastParagraph(); + + // When we call the ToString method using the html SaveFormat overload, + // it converts the node's contents to their raw html representation. + Assert.assertEquals("

          " + + "Hello World!" + + "

          ", node.toString(SaveFormat.HTML)); + + // We can also modify the result of this conversion using a SaveOptions object. + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + saveOptions.setExportRelativeFontSize(true); + + Assert.assertEquals("

          " + + "Hello World!" + + "

          ", node.toString(saveOptions)); + //ExEnd + } + + @Test + public void typedNodeCollectionToArray() throws Exception { + //ExStart + //ExFor:ParagraphCollection.ToArray + //ExSummary:Shows how to create an array from a NodeCollection. + Document doc = new Document(getMyDir() + "Paragraphs.docx"); + + Paragraph[] paras = doc.getFirstSection().getBody().getParagraphs().toArray(); + + Assert.assertEquals(22, paras.length); + //ExEnd + } + + @Test + public void nodeEnumerationHotRemove() throws Exception { + //ExStart + //ExFor:ParagraphCollection.ToArray + //ExSummary:Shows how to use "hot remove" to remove a node during enumeration. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("The first paragraph"); + builder.writeln("The second paragraph"); + builder.writeln("The third paragraph"); + builder.writeln("The fourth paragraph"); + + // Remove a node from the collection in the middle of an enumeration. + for (Paragraph para : doc.getFirstSection().getBody().getParagraphs().toArray()) + if (para.getRange().getText().contains("third")) + para.remove(); + + Assert.assertFalse(doc.getText().contains("The third paragraph")); + //ExEnd + } + + //ExStart + //ExFor:NodeChangingAction + //ExFor:NodeChangingArgs.Action + //ExFor:NodeChangingArgs.NewParent + //ExFor:NodeChangingArgs.OldParent + //ExSummary:Shows how to use a NodeChangingCallback to monitor changes to the document tree in real-time as we edit it. + @Test //ExSkip + public void nodeChangingCallback() throws Exception { + Document doc = new Document(); + doc.setNodeChangingCallback(new NodeChangingPrinter()); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + builder.startTable(); + builder.insertCell(); + builder.write("Cell 1"); + builder.insertCell(); + builder.write("Cell 2"); + builder.endTable(); + + builder.insertImage(getImageDir() + "Logo.jpg"); + builder.getCurrentParagraph().getParentNode().removeAllChildren(); + } + + /// + /// Prints every node insertion/removal as it takes place in the document. + /// + private static class NodeChangingPrinter implements INodeChangingCallback { + public void nodeInserting(NodeChangingArgs args) { + Assert.assertEquals(args.getAction(), NodeChangingAction.INSERT); + Assert.assertEquals(args.getOldParent(), null); + } + + public void nodeInserted(NodeChangingArgs args) { + Assert.assertEquals(args.getAction(), NodeChangingAction.INSERT); + Assert.assertNotNull(args.getNewParent()); + + System.out.println("Inserted node:"); + System.out.println(MessageFormat.format("\tType:\t{0}", args.getNode().getNodeType())); + + if (!"".equals(args.getNode().getText().trim())) { + System.out.println(MessageFormat.format("\tText:\t\"{0}\"", args.getNode().getText().trim())); + } + + System.out.println(MessageFormat.format("\tHash:\t{0}", args.getNode().hashCode())); + System.out.println(MessageFormat.format("\tParent:\t{0} ({1})", args.getNewParent().getNodeType(), args.getNewParent().hashCode())); + } + + public void nodeRemoving(NodeChangingArgs args) { + Assert.assertEquals(args.getAction(), NodeChangingAction.REMOVE); + } + + public void nodeRemoved(NodeChangingArgs args) { + Assert.assertEquals(args.getAction(), NodeChangingAction.REMOVE); + Assert.assertNull(args.getNewParent()); + + System.out.println(MessageFormat.format("Removed node: {0} ({1})", args.getNode().getNodeType(), args.getNode().hashCode())); + } + } + //ExEnd + + @Test + public void nodeCollection() throws Exception { + //ExStart + //ExFor:NodeCollection.Contains(Node) + //ExFor:NodeCollection.Insert(Int32,Node) + //ExFor:NodeCollection.Remove(Node) + //ExSummary:Shows how to work with a NodeCollection. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Add text to the document by inserting Runs using a DocumentBuilder. + builder.write("Run 1. "); + builder.write("Run 2. "); + + // Every invocation of the "Write()" method creates a new Run, + // which then appears in the parent Paragraph's RunCollection. + RunCollection runs = doc.getFirstSection().getBody().getFirstParagraph().getRuns(); + + Assert.assertEquals(2, runs.getCount()); + + // We can also insert a node into the RunCollection manually. + Run newRun = new Run(doc, "Run 3. "); + runs.insert(3, newRun); + + Assert.assertTrue(runs.contains(newRun)); + Assert.assertEquals("Run 1. Run 2. Run 3.", doc.getText().trim()); + + // Access individual runs and remove them to remove their text from the document. + Run run = runs.get(1); + runs.remove(run); + + Assert.assertEquals("Run 1. Run 3.", doc.getText().trim()); + Assert.assertNotNull(run); + Assert.assertFalse(runs.contains(run)); + //ExEnd + } + + @Test + public void nodeList() throws Exception { + //ExStart + //ExFor:NodeList.Count + //ExFor:NodeList.Item(Int32) + //ExSummary:Shows how to use XPaths to navigate a NodeList. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert some nodes with a DocumentBuilder. + builder.writeln("Hello world!"); + + builder.startTable(); + builder.insertCell(); + builder.write("Cell 1"); + builder.insertCell(); + builder.write("Cell 2"); + builder.endTable(); + + builder.insertImage(getImageDir() + "Logo.jpg"); + + // Our document contains three Run nodes. + NodeList runs = doc.selectNodes("//Run"); + + Assert.assertEquals(3, runs.getCount()); + + // Use a double forward slash to select all Run nodes + // that are indirect descendants of a Table node, which would be the runs inside the two cells we inserted. + runs = doc.selectNodes("//Table//Run"); + + Assert.assertEquals(2, runs.getCount()); + + // Single forward slashes specify direct descendant relationships, + // which we skipped when we used double slashes. + Assert.assertEquals(doc.selectNodes("//Table//Run"), + doc.selectNodes("//Table/Row/Cell/Paragraph/Run")); + + // Access the shape that contains the image we inserted. + NodeList shapes = doc.selectNodes("//Shape"); + + Assert.assertEquals(1, shapes.getCount()); + + Shape shape = (Shape) shapes.get(0); + Assert.assertTrue(shape.hasImage()); + //ExEnd + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExNodeImporter.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExNodeImporter.java new file mode 100644 index 00000000..0e523ab1 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExNodeImporter.java @@ -0,0 +1,190 @@ +package Examples; + +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +@Test +public class ExNodeImporter extends ApiExampleBase { + @Test(dataProvider = "keepSourceNumberingDataProvider") + public void keepSourceNumbering(boolean keepSourceNumbering) throws Exception { + //ExStart + //ExFor:ImportFormatOptions.KeepSourceNumbering + //ExFor:NodeImporter.#ctor(DocumentBase, DocumentBase, ImportFormatMode, ImportFormatOptions) + //ExSummary:Shows how to resolve list numbering clashes in source and destination documents. + // Open a document with a custom list numbering scheme, and then clone it. + // Since both have the same numbering format, the formats will clash if we import one document into the other. + Document srcDoc = new Document(getMyDir() + "Custom list numbering.docx"); + Document dstDoc = srcDoc.deepClone(); + + // When we import the document's clone into the original and then append it, + // then the two lists with the same list format will join. + // If we set the "KeepSourceNumbering" flag to "false", then the list from the document clone + // that we append to the original will carry on the numbering of the list we append it to. + // This will effectively merge the two lists into one. + // If we set the "KeepSourceNumbering" flag to "true", then the document clone + // list will preserve its original numbering, making the two lists appear as separate lists. + ImportFormatOptions importFormatOptions = new ImportFormatOptions(); + importFormatOptions.setKeepSourceNumbering(keepSourceNumbering); + + NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.KEEP_DIFFERENT_STYLES, importFormatOptions); + for (Paragraph paragraph : srcDoc.getFirstSection().getBody().getParagraphs()) { + Node importedNode = importer.importNode(paragraph, true); + dstDoc.getFirstSection().getBody().appendChild(importedNode); + } + + dstDoc.updateListLabels(); + + if (keepSourceNumbering) { + Assert.assertEquals( + "6. Item 1\r\n" + + "7. Item 2 \r\n" + + "8. Item 3\r\n" + + "9. Item 4\r\n" + + "6. Item 1\r\n" + + "7. Item 2 \r\n" + + "8. Item 3\r\n" + + "9. Item 4", dstDoc.getFirstSection().getBody().toString(SaveFormat.TEXT).trim()); + } else { + Assert.assertEquals( + "6. Item 1\r\n" + + "7. Item 2 \r\n" + + "8. Item 3\r\n" + + "9. Item 4\r\n" + + "10. Item 1\r\n" + + "11. Item 2 \r\n" + + "12. Item 3\r\n" + + "13. Item 4", dstDoc.getFirstSection().getBody().toString(SaveFormat.TEXT).trim()); + } + //ExEnd + } + + @DataProvider(name = "keepSourceNumberingDataProvider") + public static Object[][] keepSourceNumberingDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + //ExStart + //ExFor:Paragraph.IsEndOfSection + //ExFor:NodeImporter + //ExFor:NodeImporter.#ctor(DocumentBase, DocumentBase, ImportFormatMode) + //ExFor:NodeImporter.ImportNode(Node, Boolean) + //ExSummary:Shows how to insert the contents of one document to a bookmark in another document. + @Test//ExSkip + public void insertAtBookmark() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startBookmark("InsertionPoint"); + builder.write("We will insert a document here: "); + builder.endBookmark("InsertionPoint"); + + Document docToInsert = new Document(); + builder = new DocumentBuilder(docToInsert); + + builder.write("Hello world!"); + + docToInsert.save(getArtifactsDir() + "NodeImporter.InsertAtMergeField.docx"); + + Bookmark bookmark = doc.getRange().getBookmarks().get("InsertionPoint"); + insertDocument(bookmark.getBookmarkStart().getParentNode(), docToInsert); + + Assert.assertEquals("We will insert a document here: " + + "\rHello world!", doc.getText().trim()); + } + + /// + /// Inserts the contents of a document after the specified node. + /// + static void insertDocument(Node insertionDestination, Document docToInsert) { + if (((insertionDestination.getNodeType()) == (NodeType.PARAGRAPH)) || ((insertionDestination.getNodeType()) == (NodeType.TABLE))) { + CompositeNode destinationParent = insertionDestination.getParentNode(); + + NodeImporter importer = + new NodeImporter(docToInsert, insertionDestination.getDocument(), ImportFormatMode.KEEP_SOURCE_FORMATTING); + + // Loop through all block-level nodes in the section's body, + // then clone and insert every node that is not the last empty paragraph of a section. + for (Section srcSection : docToInsert.getSections()) + for (Node srcNode : srcSection.getBody()) { + if (((srcNode.getNodeType()) == (NodeType.PARAGRAPH))) { + Paragraph para = (Paragraph) srcNode; + if (para.isEndOfSection() && !para.hasChildNodes()) + continue; + } + + Node newNode = importer.importNode(srcNode, true); + + destinationParent.insertAfter(newNode, insertionDestination); + insertionDestination = newNode; + } + } else { + throw new IllegalArgumentException("The destination node should be either a paragraph or table."); + } + } + //ExEnd + + @Test + public void insertAtMergeField() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.write("A document will appear here: "); + builder.insertField(" MERGEFIELD Document_1 "); + + Document subDoc = new Document(); + builder = new DocumentBuilder(subDoc); + builder.write("Hello world!"); + + subDoc.save(getArtifactsDir() + "NodeImporter.InsertAtMergeField.docx"); + + doc.getMailMerge().setFieldMergingCallback(new InsertDocumentAtMailMergeHandler()); + + // The main document has a merge field in it called "Document_1". + // Execute a mail merge using a data source that contains a local system filename + // of the document that we wish to insert into the MERGEFIELD. + doc.getMailMerge().execute(new String[]{"Document_1"}, + new Object[]{getArtifactsDir() + "NodeImporter.InsertAtMergeField.docx"}); + + Assert.assertEquals("A document will appear here: \r" + + "Hello world!", doc.getText().trim()); + } + + /// + /// If the mail merge encounters a MERGEFIELD with a specified name, + /// this handler treats the current value of a mail merge data source as a local system filename of a document. + /// The handler will insert the document in its entirety into the MERGEFIELD instead of the current merge value. + /// + private static class InsertDocumentAtMailMergeHandler implements IFieldMergingCallback { + public void /*IFieldMergingCallback.*/fieldMerging(FieldMergingArgs args) throws Exception { + if ("Document_1".equals(args.getDocumentFieldName())) { + DocumentBuilder builder = new DocumentBuilder(args.getDocument()); + builder.moveToMergeField(args.getDocumentFieldName()); + + Document subDoc = new Document((String) args.getFieldValue()); + + insertDocument(builder.getCurrentParagraph(), subDoc); + + if (!builder.getCurrentParagraph().hasChildNodes()) + builder.getCurrentParagraph().remove(); + + args.setText(null); + } + } + + public void /*IFieldMergingCallback.*/imageFieldMerging(ImageFieldMergingArgs args) { + // Do nothing. + } + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExOdtSaveOptions.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExOdtSaveOptions.java new file mode 100644 index 00000000..29757c0b --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExOdtSaveOptions.java @@ -0,0 +1,149 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +public class ExOdtSaveOptions extends ApiExampleBase { + @Test(dataProvider = "odt11SchemaDataProvider") + public void odt11Schema(boolean exportToOdt11Specs) throws Exception { + //ExStart + //ExFor:OdtSaveOptions + //ExFor:OdtSaveOptions.#ctor + //ExFor:OdtSaveOptions.IsStrictSchema11 + //ExFor:OdtSaveOptions.MeasureUnit + //ExFor:MeasurementUnits + //ExSummary:Shows how to make a saved document conform to an older ODT schema. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + OdtSaveOptions saveOptions = new OdtSaveOptions(); + { + saveOptions.setMeasureUnit(OdtSaveMeasureUnit.CENTIMETERS); + saveOptions.isStrictSchema11(exportToOdt11Specs); + } + + doc.save(getArtifactsDir() + "OdtSaveOptions.Odt11Schema.odt", saveOptions); + //ExEnd + + doc = new Document(getArtifactsDir() + "OdtSaveOptions.Odt11Schema.odt"); + + Assert.assertEquals(com.aspose.words.MeasurementUnits.CENTIMETERS, doc.getLayoutOptions().getRevisionOptions().getMeasurementUnit()); + + if (exportToOdt11Specs) { + Assert.assertEquals(2, doc.getRange().getFormFields().getCount()); + Assert.assertEquals(FieldType.FIELD_FORM_TEXT_INPUT, doc.getRange().getFormFields().get(0).getType()); + Assert.assertEquals(FieldType.FIELD_FORM_CHECK_BOX, doc.getRange().getFormFields().get(1).getType()); + } else { + Assert.assertEquals(3, doc.getRange().getFormFields().getCount()); + Assert.assertEquals(FieldType.FIELD_FORM_TEXT_INPUT, doc.getRange().getFormFields().get(0).getType()); + Assert.assertEquals(FieldType.FIELD_FORM_CHECK_BOX, doc.getRange().getFormFields().get(1).getType()); + Assert.assertEquals(FieldType.FIELD_FORM_DROP_DOWN, doc.getRange().getFormFields().get(2).getType()); + } + } + + @DataProvider(name = "odt11SchemaDataProvider") + public static Object[][] odt11SchemaDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "measurementUnitsDataProvider") + public void measurementUnits(int odtSaveMeasureUnit) throws Exception { + //ExStart + //ExFor:OdtSaveOptions + //ExFor:OdtSaveOptions.MeasureUnit + //ExFor:OdtSaveMeasureUnit + //ExSummary:Shows how to use different measurement units to define style parameters of a saved ODT document. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // When we export the document to .odt, we can use an OdtSaveOptions object to modify how we save the document. + // We can set the "MeasureUnit" property to "OdtSaveMeasureUnit.Centimeters" + // to define content such as style parameters using the metric system, which Open Office uses. + // We can set the "MeasureUnit" property to "OdtSaveMeasureUnit.Inches" + // to define content such as style parameters using the imperial system, which Microsoft Word uses. + OdtSaveOptions saveOptions = new OdtSaveOptions(); + { + saveOptions.setMeasureUnit(odtSaveMeasureUnit); + } + + doc.save(getArtifactsDir() + "OdtSaveOptions.Odt11Schema.odt", saveOptions); + //ExEnd + + switch (odtSaveMeasureUnit) { + case OdtSaveMeasureUnit.CENTIMETERS: + TestUtil.docPackageFileContainsString("", + getArtifactsDir() + "OdtSaveOptions.Odt11Schema.odt", "styles.xml"); + break; + case OdtSaveMeasureUnit.INCHES: + TestUtil.docPackageFileContainsString("", + getArtifactsDir() + "OdtSaveOptions.Odt11Schema.odt", "styles.xml"); + break; + } + } + + @DataProvider(name = "measurementUnitsDataProvider") + public static Object[][] measurementUnitsDataProvider() { + return new Object[][] + { + {OdtSaveMeasureUnit.CENTIMETERS}, + {OdtSaveMeasureUnit.INCHES}, + }; + } + + @Test(dataProvider = "encryptDataProvider") + public void encrypt(/*SaveFormat*/int saveFormat) throws Exception { + //ExStart + //ExFor:OdtSaveOptions.#ctor(SaveFormat) + //ExFor:OdtSaveOptions.Password + //ExFor:OdtSaveOptions.SaveFormat + //ExSummary:Shows how to encrypt a saved ODT/OTT document with a password, and then load it using Aspose.Words. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + // Create a new OdtSaveOptions, and pass either "SaveFormat.Odt", + // or "SaveFormat.Ott" as the format to save the document in. + OdtSaveOptions saveOptions = new OdtSaveOptions(saveFormat); + saveOptions.setPassword("@sposeEncrypted_1145"); + + String extensionString = FileFormatUtil.saveFormatToExtension(saveFormat); + + // If we open this document with an appropriate editor, + // it will prompt us for the password we specified in the SaveOptions object. + doc.save(getArtifactsDir() + "OdtSaveOptions.Encrypt" + extensionString, saveOptions); + + FileFormatInfo docInfo = FileFormatUtil.detectFileFormat(getArtifactsDir() + "OdtSaveOptions.Encrypt" + extensionString); + + Assert.assertTrue(docInfo.isEncrypted()); + + // If we wish to open or edit this document again using Aspose.Words, + // we will have to provide a LoadOptions object with the correct password to the loading constructor. + doc = new Document(getArtifactsDir() + "OdtSaveOptions.Encrypt" + extensionString, + new LoadOptions("@sposeEncrypted_1145")); + + Assert.assertEquals("Hello world!", doc.getText().trim()); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "encryptDataProvider") + public static Object[][] encryptDataProvider() throws Exception { + return new Object[][] + { + {SaveFormat.ODT}, + {SaveFormat.OTT}, + }; + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExOoxmlSaveOptions.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExOoxmlSaveOptions.java new file mode 100644 index 00000000..cd60dd87 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExOoxmlSaveOptions.java @@ -0,0 +1,458 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import com.aspose.words.List; +import com.aspose.words.Shape; +import org.apache.commons.lang.time.StopWatch; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.text.MessageFormat; +import java.util.Date; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +public class ExOoxmlSaveOptions extends ApiExampleBase { + @Test + public void password() throws Exception { + //ExStart + //ExFor:OoxmlSaveOptions.Password + //ExSummary:Shows how to create a password encrypted Office Open XML document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + saveOptions.setPassword("MyPassword"); + + doc.save(getArtifactsDir() + "OoxmlSaveOptions.Password.docx", saveOptions); + + // We will not be able to open this document with Microsoft Word or + // Aspose.Words without providing the correct password. + Assert.assertThrows(IncorrectPasswordException.class, () -> new Document(getArtifactsDir() + "OoxmlSaveOptions.Password.docx")); + + // Open the encrypted document by passing the correct password in a LoadOptions object. + doc = new Document(getArtifactsDir() + "OoxmlSaveOptions.Password.docx", new LoadOptions("MyPassword")); + + Assert.assertEquals("Hello world!", doc.getText().trim()); + //ExEnd + } + + @Test + public void iso29500Strict() throws Exception { + //ExStart + //ExFor:CompatibilityOptions + //ExFor:CompatibilityOptions.OptimizeFor(MsWordVersion) + //ExFor:OoxmlSaveOptions + //ExFor:OoxmlSaveOptions.#ctor + //ExFor:OoxmlSaveOptions.SaveFormat + //ExFor:OoxmlCompliance + //ExFor:OoxmlSaveOptions.Compliance + //ExFor:ShapeMarkupLanguage + //ExSummary:Shows how to set an OOXML compliance specification for a saved document to adhere to. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // If we configure compatibility options to comply with Microsoft Word 2003, + // inserting an image will define its shape using VML. + doc.getCompatibilityOptions().optimizeFor(MsWordVersion.WORD_2003); + builder.insertImage(getImageDir() + "Transparent background logo.png"); + + Assert.assertEquals(ShapeMarkupLanguage.VML, ((Shape) doc.getChild(NodeType.SHAPE, 0, true)).getMarkupLanguage()); + + // The "ISO/IEC 29500:2008" OOXML standard does not support VML shapes. + // If we set the "Compliance" property of the SaveOptions object to "OoxmlCompliance.Iso29500_2008_Strict", + // any document we save while passing this object will have to follow that standard. + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + saveOptions.setCompliance(OoxmlCompliance.ISO_29500_2008_STRICT); + saveOptions.setSaveFormat(SaveFormat.DOCX); + + doc.save(getArtifactsDir() + "OoxmlSaveOptions.Iso29500Strict.docx", saveOptions); + + // Our saved document defines the shape using DML to adhere to the "ISO/IEC 29500:2008" OOXML standard. + doc = new Document(getArtifactsDir() + "OoxmlSaveOptions.Iso29500Strict.docx"); + + Assert.assertEquals(ShapeMarkupLanguage.DML, ((Shape) doc.getChild(NodeType.SHAPE, 0, true)).getMarkupLanguage()); + //ExEnd + } + + @Test(dataProvider = "restartingDocumentListDataProvider") + public void restartingDocumentList(boolean restartListAtEachSection) throws Exception { + //ExStart + //ExFor:List.IsRestartAtEachSection + //ExFor:OoxmlCompliance + //ExFor:OoxmlSaveOptions.Compliance + //ExSummary:Shows how to configure a list to restart numbering at each section. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + doc.getLists().add(ListTemplate.NUMBER_DEFAULT); + + List list = doc.getLists().get(0); + list.isRestartAtEachSection(restartListAtEachSection); + + // The "IsRestartAtEachSection" property will only be applicable when + // the document's OOXML compliance level is to a standard that is newer than "OoxmlComplianceCore.Ecma376". + OoxmlSaveOptions options = new OoxmlSaveOptions(); + { + options.setCompliance(OoxmlCompliance.ISO_29500_2008_TRANSITIONAL); + } + + builder.getListFormat().setList(list); + + builder.writeln("List item 1"); + builder.writeln("List item 2"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.writeln("List item 3"); + builder.writeln("List item 4"); + + doc.save(getArtifactsDir() + "OoxmlSaveOptions.RestartingDocumentList.docx", options); + + doc = new Document(getArtifactsDir() + "OoxmlSaveOptions.RestartingDocumentList.docx"); + + Assert.assertEquals(restartListAtEachSection, doc.getLists().get(0).isRestartAtEachSection()); + //ExEnd + } + + @DataProvider(name = "restartingDocumentListDataProvider") + public static Object[][] restartingDocumentListDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "lastSavedTimeDataProvider") + public void lastSavedTime(boolean updateLastSavedTimeProperty) throws Exception { + //ExStart + //ExFor:SaveOptions.UpdateLastSavedTimeProperty + //ExSummary:Shows how to determine whether to preserve the document's "Last saved time" property when saving. + Document doc = new Document(getMyDir() + "Document.docx"); + + // When we save the document to an OOXML format, we can create an OoxmlSaveOptions object + // and then pass it to the document's saving method to modify how we save the document. + // Set the "UpdateLastSavedTimeProperty" property to "true" to + // set the output document's "Last saved time" built-in property to the current date/time. + // Set the "UpdateLastSavedTimeProperty" property to "false" to + // preserve the original value of the input document's "Last saved time" built-in property. + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + saveOptions.setUpdateLastSavedTimeProperty(updateLastSavedTimeProperty); + + doc.save(getArtifactsDir() + "OoxmlSaveOptions.LastSavedTime.docx", saveOptions); + //ExEnd + } + + @DataProvider(name = "lastSavedTimeDataProvider") + public static Object[][] lastSavedTimeDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "keepLegacyControlCharsDataProvider") + public void keepLegacyControlChars(boolean keepLegacyControlChars) throws Exception { + //ExStart + //ExFor:OoxmlSaveOptions.KeepLegacyControlChars + //ExFor:OoxmlSaveOptions.#ctor(SaveFormat) + //ExSummary:Shows how to support legacy control characters when converting to .docx. + Document doc = new Document(getMyDir() + "Legacy control character.doc"); + + // When we save the document to an OOXML format, we can create an OoxmlSaveOptions object + // and then pass it to the document's saving method to modify how we save the document. + // Set the "KeepLegacyControlChars" property to "true" to preserve + // the "ShortDateTime" legacy character while saving. + // Set the "KeepLegacyControlChars" property to "false" to remove + // the "ShortDateTime" legacy character from the output document. + OoxmlSaveOptions so = new OoxmlSaveOptions(SaveFormat.DOCX); + so.setKeepLegacyControlChars(keepLegacyControlChars); + + doc.save(getArtifactsDir() + "OoxmlSaveOptions.KeepLegacyControlChars.docx", so); + + doc = new Document(getArtifactsDir() + "OoxmlSaveOptions.KeepLegacyControlChars.docx"); + + if (keepLegacyControlChars) + Assert.assertEquals("\u0013date \\@ \"M/d/yyyy\"\u0014\u0015\f", doc.getFirstSection().getBody().getText()); + else + Assert.assertEquals("\u001e\f", doc.getFirstSection().getBody().getText()); + //ExEnd + } + + @DataProvider(name = "keepLegacyControlCharsDataProvider") + public static Object[][] keepLegacyControlCharsDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "documentCompressionDataProvider") + public void documentCompression(/*CompressionLevel*/int compressionLevel) throws Exception { + //ExStart + //ExFor:OoxmlSaveOptions.CompressionLevel + //ExFor:CompressionLevel + //ExSummary:Shows how to specify the compression level to use while saving an OOXML document. + Document doc = new Document(getMyDir() + "Big document.docx"); + + // When we save the document to an OOXML format, we can create an OoxmlSaveOptions object + // and then pass it to the document's saving method to modify how we save the document. + // Set the "CompressionLevel" property to "CompressionLevel.Maximum" to apply the strongest and slowest compression. + // Set the "CompressionLevel" property to "CompressionLevel.Normal" to apply + // the default compression that Aspose.Words uses while saving OOXML documents. + // Set the "CompressionLevel" property to "CompressionLevel.Fast" to apply a faster and weaker compression. + // Set the "CompressionLevel" property to "CompressionLevel.SuperFast" to apply + // the default compression that Microsoft Word uses. + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(SaveFormat.DOCX); + saveOptions.setCompressionLevel(compressionLevel); + + StopWatch st = new StopWatch(); + st.start(); + doc.save(getArtifactsDir() + "OoxmlSaveOptions.DocumentCompression.docx", saveOptions); + st.stop(); + + File fileInfo = new File(getArtifactsDir() + "OoxmlSaveOptions.DocumentCompression.docx"); + + System.out.println(MessageFormat.format("Saving operation done using the \"{0}\" compression level:", compressionLevel)); + System.out.println(MessageFormat.format("\tDuration:\t{0}", st.getTime())); + System.out.println(MessageFormat.format("\tFile Size:\t{0} bytes", fileInfo.length())); + //ExEnd + + long testedFileLength = fileInfo.length(); + switch (compressionLevel) { + case CompressionLevel.MAXIMUM: + Assert.assertTrue(testedFileLength <= 1266000); + break; + case CompressionLevel.NORMAL: + Assert.assertTrue(testedFileLength < 1267000); + break; + case CompressionLevel.FAST: + Assert.assertTrue(testedFileLength < 1269000); + break; + case CompressionLevel.SUPER_FAST: + Assert.assertTrue(testedFileLength < 1271000); + break; + } + } + + @DataProvider(name = "documentCompressionDataProvider") + public static Object[][] documentCompressionDataProvider() { + return new Object[][] + { + {CompressionLevel.MAXIMUM}, + {CompressionLevel.FAST}, + {CompressionLevel.NORMAL}, + {CompressionLevel.SUPER_FAST}, + }; + } + + @Test + public void checkFileSignatures() throws Exception { + int[] compressionLevels = { + CompressionLevel.MAXIMUM, + CompressionLevel.NORMAL, + CompressionLevel.FAST, + CompressionLevel.SUPER_FAST + }; + + String[] fileSignatures = new String[] + { + "50 4B 03 04 14 00 08 08 08 00 ", + "50 4B 03 04 14 00 08 08 08 00 ", + "50 4B 03 04 14 00 08 08 08 00 ", + "50 4B 03 04 14 00 08 08 08 00 " + }; + + Document doc = new Document(); + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(SaveFormat.DOCX); + + for (int i = 0; i < fileSignatures.length; i++) { + saveOptions.setCompressionLevel(compressionLevels[i]); + doc.save(getArtifactsDir() + "OoxmlSaveOptions.CheckFileSignatures.docx", saveOptions); + } + } + + @Test + public void exportGeneratorName() throws Exception + { + //ExStart + //ExFor:SaveOptions.ExportGeneratorName + //ExSummary:Shows how to disable adding name and version of Aspose.Words into produced files. + Document doc = new Document(); + + // Use https://docs.aspose.com/words/net/generator-or-producer-name-included-in-output-documents/ to know how to check the result. + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setExportGeneratorName(false); } + + doc.save(getArtifactsDir() + "OoxmlSaveOptions.ExportGeneratorName.docx", saveOptions); + //ExEnd + } + + @Test (dataProvider = "progressCallbackDataProvider") + //ExStart + //ExFor:SaveOptions.ProgressCallback + //ExFor:IDocumentSavingCallback + //ExFor:IDocumentSavingCallback.Notify(DocumentSavingArgs) + //ExFor:DocumentSavingArgs.EstimatedProgress + //ExSummary:Shows how to manage a document while saving to docx. + public void progressCallback(int saveFormat, String ext) throws Exception + { + Document doc = new Document(getMyDir() + "Big document.docx"); + + // Following formats are supported: Docx, FlatOpc, Docm, Dotm, Dotx. + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(saveFormat); + { + saveOptions.setProgressCallback(new SavingProgressCallback()); + } + + try { + doc.save(getArtifactsDir() + MessageFormat.format("OoxmlSaveOptions.ProgressCallback.{0}", ext), saveOptions); + } + catch (IllegalStateException exception) { + Assert.assertTrue(exception.getMessage().contains("EstimatedProgress")); + } + } + + @DataProvider(name = "progressCallbackDataProvider") //ExSkip + public static Object[][] progressCallbackDataProvider() throws Exception + { + return new Object[][] + { + {SaveFormat.DOCX, "docx"}, + {SaveFormat.DOCM, "docm"}, + {SaveFormat.DOTM, "dotm"}, + {SaveFormat.DOTX, "dotx"}, + {SaveFormat.FLAT_OPC, "flatopc"}, + }; + } + + /// + /// Saving progress callback. Cancel a document saving after the "MaxDuration" seconds. + /// + public static class SavingProgressCallback implements IDocumentSavingCallback + { + /// + /// Ctr. + /// + public SavingProgressCallback() + { + mSavingStartedAt = new Date(); + } + + /// + /// Callback method which called during document saving. + /// + /// Saving arguments. + public void notify(DocumentSavingArgs args) + { + Date canceledAt = new Date(); + long diff = canceledAt.getTime() - mSavingStartedAt.getTime(); + long ellapsedSeconds = TimeUnit.MILLISECONDS.toSeconds(diff); + + if (ellapsedSeconds > MAX_DURATION) + throw new IllegalStateException(MessageFormat.format("EstimatedProgress = {0}; CanceledAt = {1}", args.getEstimatedProgress(), canceledAt)); + } + + /// + /// Date and time when document saving is started. + /// + private Date mSavingStartedAt; + + /// + /// Maximum allowed duration in sec. + /// + private static final double MAX_DURATION = 0.01d; + } + //ExEnd + + @Test + public void zip64ModeOption() throws Exception + { + //ExStart:Zip64ModeOption + //GistId:f0964b777330b758f6b82330b040b24c + //ExFor:OoxmlSaveOptions.Zip64Mode + //ExFor:Zip64Mode + //ExSummary:Shows how to use ZIP64 format extensions. + Random random = new Random(); + DocumentBuilder builder = new DocumentBuilder(); + + for (int i = 0; i < 10000; i++) + { + BufferedImage bmp = new BufferedImage(5, 5, BufferedImage.TYPE_INT_ARGB); + Graphics2D g = bmp.createGraphics(); + g.setColor(new Color(random.nextInt(254), random.nextInt(254), random.nextInt(254))); + g.drawImage(bmp, 0, 0, null); + g.dispose(); + builder.insertImage(bmp); + } + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + saveOptions.setZip64Mode(Zip64Mode.ALWAYS); + + builder.getDocument().save(getArtifactsDir() + "OoxmlSaveOptions.Zip64ModeOption.docx", saveOptions); + //ExEnd:Zip64ModeOption + } + + @Test + public void digitalSignature() throws Exception + { + //ExStart:DigitalSignature + //GistId:31b7350f8d91d4b12eb43978940d566a + //ExFor:OoxmlSaveOptions.DigitalSignatureDetails + //ExFor:DigitalSignatureDetails + //ExFor:DigitalSignatureDetails.#ctor(CertificateHolder, SignOptions) + //ExFor:DigitalSignatureDetails.CertificateHolder + //ExFor:DigitalSignatureDetails.SignOptions + //ExSummary:Shows how to sign OOXML document. + Document doc = new Document(getMyDir() + "Document.docx"); + + CertificateHolder certificateHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + SignOptions signOptions = new SignOptions(); + signOptions.setComments("Some comments"); + signOptions.setSignTime(new Date()); + saveOptions.setDigitalSignatureDetails(new DigitalSignatureDetails( + certificateHolder, + signOptions)); + + doc.save(getArtifactsDir() + "OoxmlSaveOptions.DigitalSignature.docx", saveOptions); + //ExEnd:DigitalSignature + } + + @Test + public void updateAmbiguousTextFont() throws Exception + { + //ExStart:UpdateAmbiguousTextFont + //GistId:3c52d1e8d47af34d5026f3a951027f59 + //ExFor:SaveOptions.UpdateAmbiguousTextFont + //ExSummary:Shows how to update the font to match the character code being used. + Document doc = new Document(getMyDir() + "Special symbol.docx"); + Run run = doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0); + System.out.println(run.getText()); // ฿ + System.out.println(run.getFont().getName()); // Arial + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + saveOptions.setUpdateAmbiguousTextFont(true); + doc.save(getArtifactsDir() + "OoxmlSaveOptions.UpdateAmbiguousTextFont.docx", saveOptions); + + doc = new Document(getArtifactsDir() + "OoxmlSaveOptions.UpdateAmbiguousTextFont.docx"); + run = doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0); + System.out.println(run.getText()); // ฿ + System.out.println(run.getFont().getName()); // Angsana New + //ExEnd:UpdateAmbiguousTextFont + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExPageSetup.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExPageSetup.java new file mode 100644 index 00000000..953980a7 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExPageSetup.java @@ -0,0 +1,1122 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import javax.print.PrintService; +import javax.print.PrintServiceLookup; +import javax.print.attribute.standard.Media; +import java.awt.*; +import java.awt.print.PrinterJob; +import java.text.MessageFormat; + +public class ExPageSetup extends ApiExampleBase { + @Test + public void clearFormatting() throws Exception { + //ExStart + //ExFor:DocumentBuilder.PageSetup + //ExFor:DocumentBuilder.InsertBreak + //ExFor:DocumentBuilder.Document + //ExFor:PageSetup + //ExFor:PageSetup.Orientation + //ExFor:PageSetup.VerticalAlignment + //ExFor:PageSetup.ClearFormatting + //ExFor:Orientation + //ExFor:PageVerticalAlignment + //ExFor:BreakType + //ExSummary:Shows how to apply and revert page setup settings to sections in a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Modify the page setup properties for the builder's current section and add text. + builder.getPageSetup().setOrientation(Orientation.LANDSCAPE); + builder.getPageSetup().setVerticalAlignment(PageVerticalAlignment.CENTER); + builder.writeln("This is the first section, which landscape oriented with vertically centered text."); + + // If we start a new section using a document builder, + // it will inherit the builder's current page setup properties. + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + + Assert.assertEquals(Orientation.LANDSCAPE, doc.getSections().get(1).getPageSetup().getOrientation()); + Assert.assertEquals(PageVerticalAlignment.CENTER, doc.getSections().get(1).getPageSetup().getVerticalAlignment()); + + // We can revert its page setup properties to their default values using the "ClearFormatting" method. + builder.getPageSetup().clearFormatting(); + + Assert.assertEquals(Orientation.PORTRAIT, doc.getSections().get(1).getPageSetup().getOrientation()); + Assert.assertEquals(PageVerticalAlignment.TOP, doc.getSections().get(1).getPageSetup().getVerticalAlignment()); + + builder.writeln("This is the second section, which is in default Letter paper size, portrait orientation and top alignment."); + + doc.save(getArtifactsDir() + "PageSetup.ClearFormatting.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.ClearFormatting.docx"); + + Assert.assertEquals(Orientation.LANDSCAPE, doc.getSections().get(0).getPageSetup().getOrientation()); + Assert.assertEquals(PageVerticalAlignment.CENTER, doc.getSections().get(0).getPageSetup().getVerticalAlignment()); + + Assert.assertEquals(Orientation.PORTRAIT, doc.getSections().get(1).getPageSetup().getOrientation()); + Assert.assertEquals(PageVerticalAlignment.TOP, doc.getSections().get(1).getPageSetup().getVerticalAlignment()); + } + + @Test(dataProvider = "differentFirstPageHeaderFooterDataProvider") + public void differentFirstPageHeaderFooter(boolean differentFirstPageHeaderFooter) throws Exception { + //ExStart + //ExFor:PageSetup.DifferentFirstPageHeaderFooter + //ExSummary:Shows how to enable or disable primary headers/footers. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are two types of header/footers. + // 1 - The "First" header/footer, which appears on the first page of the section. + builder.moveToHeaderFooter(HeaderFooterType.HEADER_FIRST); + builder.writeln("First page header."); + + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_FIRST); + builder.writeln("First page footer."); + + // 2 - The "Primary" header/footer, which appears on every page in the section. + // We can override the primary header/footer by a first and an even page header/footer. + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.writeln("Primary header."); + + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + builder.writeln("Primary footer."); + + builder.moveToSection(0); + builder.writeln("Page 1."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 2."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 3."); + + // Each section has a "PageSetup" object that specifies page appearance-related properties + // such as orientation, size, and borders. + // Set the "DifferentFirstPageHeaderFooter" property to "true" to apply the first header/footer to the first page. + // Set the "DifferentFirstPageHeaderFooter" property to "false" + // to make the first page display the primary header/footer. + builder.getPageSetup().setDifferentFirstPageHeaderFooter(differentFirstPageHeaderFooter); + + doc.save(getArtifactsDir() + "PageSetup.DifferentFirstPageHeaderFooter.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.DifferentFirstPageHeaderFooter.docx"); + + Assert.assertEquals(differentFirstPageHeaderFooter, doc.getFirstSection().getPageSetup().getDifferentFirstPageHeaderFooter()); + } + + @DataProvider(name = "differentFirstPageHeaderFooterDataProvider") + public static Object[][] differentFirstPageHeaderFooterDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "oddAndEvenPagesHeaderFooterDataProvider") + public void oddAndEvenPagesHeaderFooter(boolean oddAndEvenPagesHeaderFooter) throws Exception { + //ExStart + //ExFor:PageSetup.OddAndEvenPagesHeaderFooter + //ExSummary:Shows how to enable or disable even page headers/footers. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are two types of header/footers. + // 1 - The "Primary" header/footer, which appears on every page in the section. + // We can override the primary header/footer by a first and an even page header/footer. + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.writeln("Primary header."); + + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + builder.writeln("Primary footer."); + + // 2 - The "Even" header/footer, which appears on every even page of this section. + builder.moveToHeaderFooter(HeaderFooterType.HEADER_EVEN); + builder.writeln("Even page header."); + + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_EVEN); + builder.writeln("Even page footer."); + + builder.moveToSection(0); + builder.writeln("Page 1."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 2."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 3."); + + // Each section has a "PageSetup" object that specifies page appearance-related properties + // such as orientation, size, and borders. + // Set the "OddAndEvenPagesHeaderFooter" property to "true" + // to display the even page header/footer on even pages. + // Set the "OddAndEvenPagesHeaderFooter" property to "false" + // to display the primary header/footer on even pages. + builder.getPageSetup().setOddAndEvenPagesHeaderFooter(oddAndEvenPagesHeaderFooter); + + doc.save(getArtifactsDir() + "PageSetup.OddAndEvenPagesHeaderFooter.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.OddAndEvenPagesHeaderFooter.docx"); + + Assert.assertEquals(oddAndEvenPagesHeaderFooter, doc.getFirstSection().getPageSetup().getOddAndEvenPagesHeaderFooter()); + } + + @DataProvider(name = "oddAndEvenPagesHeaderFooterDataProvider") + public static Object[][] oddAndEvenPagesHeaderFooterDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void charactersPerLine() throws Exception { + //ExStart + //ExFor:PageSetup.CharactersPerLine + //ExFor:PageSetup.LayoutMode + //ExFor:SectionLayoutMode + //ExSummary:Shows how to specify a for the number of characters that each line may have. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Enable pitching, and then use it to set the number of characters per line in this section. + builder.getPageSetup().setLayoutMode(SectionLayoutMode.GRID); + builder.getPageSetup().setCharactersPerLine(10); + + // The number of characters also depends on the size of the font. + doc.getStyles().get("Normal").getFont().setSize(20.0); + + Assert.assertEquals(8, doc.getFirstSection().getPageSetup().getCharactersPerLine()); + + builder.writeln("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + + doc.save(getArtifactsDir() + "PageSetup.CharactersPerLine.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.CharactersPerLine.docx"); + + Assert.assertEquals(SectionLayoutMode.GRID, doc.getFirstSection().getPageSetup().getLayoutMode()); + Assert.assertEquals(8, doc.getFirstSection().getPageSetup().getCharactersPerLine()); + } + + @Test + public void linesPerPage() throws Exception { + //ExStart + //ExFor:PageSetup.LinesPerPage + //ExFor:PageSetup.LayoutMode + //ExFor:ParagraphFormat.SnapToGrid + //ExFor:SectionLayoutMode + //ExSummary:Shows how to specify a limit for the number of lines that each page may have. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Enable pitching, and then use it to set the number of lines per page in this section. + // A large enough font size will push some lines down onto the next page to avoid overlapping characters. + builder.getPageSetup().setLayoutMode(SectionLayoutMode.LINE_GRID); + builder.getPageSetup().setLinesPerPage(15); + + builder.getParagraphFormat().setSnapToGrid(true); + + for (int i = 0; i < 30; i++) + builder.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "); + + doc.save(getArtifactsDir() + "PageSetup.LinesPerPage.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.LinesPerPage.docx"); + + Assert.assertEquals(SectionLayoutMode.LINE_GRID, doc.getFirstSection().getPageSetup().getLayoutMode()); + Assert.assertEquals(14, doc.getFirstSection().getPageSetup().getLinesPerPage()); + + for (Paragraph paragraph : doc.getFirstSection().getBody().getParagraphs()) + Assert.assertTrue(paragraph.getParagraphFormat().getSnapToGrid()); + } + + @Test + public void setSectionStart() throws Exception { + //ExStart + //ExFor:SectionStart + //ExFor:PageSetup.SectionStart + //ExFor:Document.Sections + //ExSummary:Shows how to specify how a new section separates itself from the previous. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("This text is in section 1."); + + // Section break types determine how a new section separates itself from the previous section. + // Below are five types of section breaks. + // 1 - Starts the next section on a new page: + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.writeln("This text is in section 2."); + + Assert.assertEquals(SectionStart.NEW_PAGE, doc.getSections().get(1).getPageSetup().getSectionStart()); + + // 2 - Starts the next section on the current page: + builder.insertBreak(BreakType.SECTION_BREAK_CONTINUOUS); + builder.writeln("This text is in section 3."); + + Assert.assertEquals(SectionStart.CONTINUOUS, doc.getSections().get(2).getPageSetup().getSectionStart()); + + // 3 - Starts the next section on a new even page: + builder.insertBreak(BreakType.SECTION_BREAK_EVEN_PAGE); + builder.writeln("This text is in section 4."); + + Assert.assertEquals(SectionStart.EVEN_PAGE, doc.getSections().get(3).getPageSetup().getSectionStart()); + + // 4 - Starts the next section on a new odd page: + builder.insertBreak(BreakType.SECTION_BREAK_ODD_PAGE); + builder.writeln("This text is in section 5."); + + Assert.assertEquals(SectionStart.ODD_PAGE, doc.getSections().get(4).getPageSetup().getSectionStart()); + + // 5 - Starts the next section on a new column: + TextColumnCollection columns = builder.getPageSetup().getTextColumns(); + columns.setCount(2); + + builder.insertBreak(BreakType.SECTION_BREAK_NEW_COLUMN); + builder.writeln("This text is in section 6."); + + Assert.assertEquals(SectionStart.NEW_COLUMN, doc.getSections().get(5).getPageSetup().getSectionStart()); + + doc.save(getArtifactsDir() + "PageSetup.SetSectionStart.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.SetSectionStart.docx"); + + Assert.assertEquals(SectionStart.NEW_PAGE, doc.getSections().get(0).getPageSetup().getSectionStart()); + Assert.assertEquals(SectionStart.NEW_PAGE, doc.getSections().get(1).getPageSetup().getSectionStart()); + Assert.assertEquals(SectionStart.CONTINUOUS, doc.getSections().get(2).getPageSetup().getSectionStart()); + Assert.assertEquals(SectionStart.EVEN_PAGE, doc.getSections().get(3).getPageSetup().getSectionStart()); + Assert.assertEquals(SectionStart.ODD_PAGE, doc.getSections().get(4).getPageSetup().getSectionStart()); + Assert.assertEquals(SectionStart.NEW_COLUMN, doc.getSections().get(5).getPageSetup().getSectionStart()); + } + + @Test(enabled = false, description = "Run only when the printer driver is installed") + public void paperTrayForDifferentPaperType() throws Exception { + //ExStart + //ExFor:PageSetup.FirstPageTray + //ExFor:PageSetup.OtherPagesTray + //ExSummary:Shows how to set up printing using different printer trays for different paper sizes. + Document doc = new Document(); + + /// Choose the default printer to be used for printing this document. + PrintService printService = PrintServiceLookup.lookupDefaultPrintService(); + Media[] trays = (Media[]) printService.getSupportedAttributeValues(Media.class, null, null); + + // This is the tray we will use for pages in the "A4" paper size. + int printerTrayForA4 = trays[0].getValue(); + // This is the tray we will use for pages in the "Letter" paper size. + int printerTrayForLetter = trays[1].getValue(); + + // Modify the PageSettings object of this section to get Microsoft Word to instruct the printer + // to use one of the trays we identified above, depending on this section's paper size. + for (Section section : doc.getSections()) { + if (section.getPageSetup().getPaperSize() == PaperSize.LETTER) { + section.getPageSetup().setFirstPageTray(printerTrayForLetter); + section.getPageSetup().setOtherPagesTray(printerTrayForLetter); + } else if (section.getPageSetup().getPaperSize() == PaperSize.A4) { + section.getPageSetup().setFirstPageTray(printerTrayForA4); + section.getPageSetup().setOtherPagesTray(printerTrayForA4); + } + } + //ExEnd + + for (Section section : DocumentHelper.saveOpen(doc).getSections()) { + if (section.getPageSetup().getPaperSize() == com.aspose.words.PaperSize.LETTER) { + Assert.assertEquals(printerTrayForLetter, section.getPageSetup().getFirstPageTray()); + Assert.assertEquals(printerTrayForLetter, section.getPageSetup().getOtherPagesTray()); + } else if (section.getPageSetup().getPaperSize() == com.aspose.words.PaperSize.A4) { + Assert.assertEquals(printerTrayForA4, section.getPageSetup().getFirstPageTray()); + Assert.assertEquals(printerTrayForA4, section.getPageSetup().getOtherPagesTray()); + } + } + } + + @Test + public void pageMargins() throws Exception { + //ExStart + //ExFor:ConvertUtil + //ExFor:ConvertUtil.InchToPoint + //ExFor:PaperSize + //ExFor:PageSetup.PaperSize + //ExFor:PageSetup.Orientation + //ExFor:PageSetup.TopMargin + //ExFor:PageSetup.BottomMargin + //ExFor:PageSetup.LeftMargin + //ExFor:PageSetup.RightMargin + //ExFor:PageSetup.HeaderDistance + //ExFor:PageSetup.FooterDistance + //ExSummary:Shows how to adjust paper size, orientation, margins, along with other settings for a section. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getPageSetup().setPaperSize(PaperSize.LEGAL); + builder.getPageSetup().setOrientation(Orientation.LANDSCAPE); + builder.getPageSetup().setTopMargin(ConvertUtil.inchToPoint(1.0)); + builder.getPageSetup().setBottomMargin(ConvertUtil.inchToPoint(1.0)); + builder.getPageSetup().setLeftMargin(ConvertUtil.inchToPoint(1.5)); + builder.getPageSetup().setRightMargin(ConvertUtil.inchToPoint(1.5)); + builder.getPageSetup().setHeaderDistance(ConvertUtil.inchToPoint(0.2)); + builder.getPageSetup().setFooterDistance(ConvertUtil.inchToPoint(0.2)); + + builder.writeln("Hello world!"); + + doc.save(getArtifactsDir() + "PageSetup.PageMargins.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.PageMargins.docx"); + + Assert.assertEquals(PaperSize.LEGAL, doc.getFirstSection().getPageSetup().getPaperSize()); + Assert.assertEquals(1008.0d, doc.getFirstSection().getPageSetup().getPageWidth()); + Assert.assertEquals(612.0d, doc.getFirstSection().getPageSetup().getPageHeight()); + Assert.assertEquals(Orientation.LANDSCAPE, doc.getFirstSection().getPageSetup().getOrientation()); + Assert.assertEquals(72.0d, doc.getFirstSection().getPageSetup().getTopMargin()); + Assert.assertEquals(72.0d, doc.getFirstSection().getPageSetup().getBottomMargin()); + Assert.assertEquals(108.0d, doc.getFirstSection().getPageSetup().getLeftMargin()); + Assert.assertEquals(108.0d, doc.getFirstSection().getPageSetup().getRightMargin()); + Assert.assertEquals(14.4d, doc.getFirstSection().getPageSetup().getHeaderDistance()); + Assert.assertEquals(14.4d, doc.getFirstSection().getPageSetup().getFooterDistance()); + } + + @Test + public void paperSizes() throws Exception { + //ExStart + //ExFor:PaperSize + //ExFor:PageSetup.PaperSize + //ExSummary:Shows how to set page sizes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // We can change the current page's size to a pre-defined size + // by using the "PaperSize" property of this section's PageSetup object. + builder.getPageSetup().setPaperSize(PaperSize.TABLOID); + + Assert.assertEquals(792.0d, builder.getPageSetup().getPageWidth()); + Assert.assertEquals(1224.0d, builder.getPageSetup().getPageHeight()); + + builder.writeln(MessageFormat.format("This page is {0}x{1}.", builder.getPageSetup().getPageWidth(), builder.getPageSetup().getPageHeight())); + + // Each section has its own PageSetup object. When we use a document builder to make a new section, + // that section's PageSetup object inherits all the previous section's PageSetup object's values. + builder.insertBreak(BreakType.SECTION_BREAK_EVEN_PAGE); + + Assert.assertEquals(PaperSize.TABLOID, builder.getPageSetup().getPaperSize()); + + builder.getPageSetup().setPaperSize(PaperSize.A5); + builder.writeln(MessageFormat.format("This page is {0}x{1}.", builder.getPageSetup().getPageWidth(), builder.getPageSetup().getPageHeight())); + + Assert.assertEquals(419.55d, builder.getPageSetup().getPageWidth()); + Assert.assertEquals(595.30d, builder.getPageSetup().getPageHeight()); + + builder.insertBreak(BreakType.SECTION_BREAK_EVEN_PAGE); + + // Set a custom size for this section's pages. + builder.getPageSetup().setPageWidth(620.0); + builder.getPageSetup().setPageHeight(480.0); + + Assert.assertEquals(PaperSize.CUSTOM, builder.getPageSetup().getPaperSize()); + + builder.writeln(MessageFormat.format("This page is {0}x{1}.", builder.getPageSetup().getPageWidth(), builder.getPageSetup().getPageHeight())); + + doc.save(getArtifactsDir() + "PageSetup.PaperSizes.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.PaperSizes.docx"); + + Assert.assertEquals(PaperSize.TABLOID, doc.getSections().get(0).getPageSetup().getPaperSize()); + Assert.assertEquals(792.0d, doc.getSections().get(0).getPageSetup().getPageWidth()); + Assert.assertEquals(1224.0d, doc.getSections().get(0).getPageSetup().getPageHeight()); + Assert.assertEquals(PaperSize.A5, doc.getSections().get(1).getPageSetup().getPaperSize()); + Assert.assertEquals(419.55d, doc.getSections().get(1).getPageSetup().getPageWidth()); + Assert.assertEquals(595.30d, doc.getSections().get(1).getPageSetup().getPageHeight()); + Assert.assertEquals(PaperSize.CUSTOM, doc.getSections().get(2).getPageSetup().getPaperSize()); + Assert.assertEquals(620.0d, doc.getSections().get(2).getPageSetup().getPageWidth()); + Assert.assertEquals(480.0d, doc.getSections().get(2).getPageSetup().getPageHeight()); + } + + @Test + public void columnsSameWidth() throws Exception { + //ExStart + //ExFor:PageSetup.TextColumns + //ExFor:TextColumnCollection + //ExFor:TextColumnCollection.Spacing + //ExFor:TextColumnCollection.SetCount + //ExFor:TextColumnCollection.Count + //ExFor:TextColumnCollection.Width + //ExSummary:Shows how to create multiple evenly spaced columns in a section. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + TextColumnCollection columns = builder.getPageSetup().getTextColumns(); + columns.setSpacing(100.0); + columns.setCount(2); + + builder.writeln("Column 1."); + builder.insertBreak(BreakType.COLUMN_BREAK); + builder.writeln("Column 2."); + + doc.save(getArtifactsDir() + "PageSetup.ColumnsSameWidth.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.ColumnsSameWidth.docx"); + + Assert.assertEquals(100.0d, doc.getFirstSection().getPageSetup().getTextColumns().getSpacing()); + Assert.assertEquals(2, doc.getFirstSection().getPageSetup().getTextColumns().getCount()); + Assert.assertEquals(184.0, doc.getFirstSection().getPageSetup().getTextColumns().getWidth(), 0.01); + } + + @Test + public void customColumnWidth() throws Exception { + //ExStart + //ExFor:TextColumnCollection.EvenlySpaced + //ExFor:TextColumnCollection.Item + //ExFor:TextColumn + //ExFor:TextColumn.Width + //ExFor:TextColumn.SpaceAfter + //ExSummary:Shows how to create unevenly spaced columns. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + PageSetup pageSetup = builder.getPageSetup(); + + TextColumnCollection columns = pageSetup.getTextColumns(); + columns.setEvenlySpaced(false); + columns.setCount(2); + + // Determine the amount of room that we have available for arranging columns. + double contentWidth = pageSetup.getPageWidth() - pageSetup.getLeftMargin() - pageSetup.getRightMargin(); + + Assert.assertEquals(468.0d, contentWidth, 0.01d); + + // Set the first column to be narrow. + TextColumn column = columns.get(0); + column.setWidth(100.0); + column.setSpaceAfter(20.0); + + // Set the second column to take the rest of the space available within the margins of the page. + column = columns.get(1); + column.setWidth(contentWidth - column.getWidth() - column.getSpaceAfter()); + + builder.writeln("Narrow column 1."); + builder.insertBreak(BreakType.COLUMN_BREAK); + builder.writeln("Wide column 2."); + + doc.save(getArtifactsDir() + "PageSetup.CustomColumnWidth.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.CustomColumnWidth.docx"); + pageSetup = doc.getFirstSection().getPageSetup(); + + Assert.assertFalse(pageSetup.getTextColumns().getEvenlySpaced()); + Assert.assertEquals(2, pageSetup.getTextColumns().getCount()); + Assert.assertEquals(100.0d, pageSetup.getTextColumns().get(0).getWidth()); + Assert.assertEquals(20.0d, pageSetup.getTextColumns().get(0).getSpaceAfter()); + Assert.assertEquals(468.0d, pageSetup.getTextColumns().get(1).getWidth()); + Assert.assertEquals(0.0d, pageSetup.getTextColumns().get(1).getSpaceAfter()); + } + + @Test(dataProvider = "verticalLineBetweenColumnsDataProvider") + public void verticalLineBetweenColumns(boolean lineBetween) throws Exception { + //ExStart + //ExFor:TextColumnCollection.LineBetween + //ExSummary:Shows how to separate columns with a vertical line. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Configure the current section's PageSetup object to divide the text into several columns. + // Set the "LineBetween" property to "true" to put a dividing line between columns. + // Set the "LineBetween" property to "false" to leave the space between columns blank. + TextColumnCollection columns = builder.getPageSetup().getTextColumns(); + columns.setLineBetween(lineBetween); + columns.setCount(3); + + builder.writeln("Column 1."); + builder.insertBreak(BreakType.COLUMN_BREAK); + builder.writeln("Column 2."); + builder.insertBreak(BreakType.COLUMN_BREAK); + builder.writeln("Column 3."); + + doc.save(getArtifactsDir() + "PageSetup.VerticalLineBetweenColumns.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.VerticalLineBetweenColumns.docx"); + + Assert.assertEquals(lineBetween, doc.getFirstSection().getPageSetup().getTextColumns().getLineBetween()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "verticalLineBetweenColumnsDataProvider") + public static Object[][] verticalLineBetweenColumnsDataProvider() throws Exception { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void lineNumbers() throws Exception { + //ExStart + //ExFor:PageSetup.LineStartingNumber + //ExFor:PageSetup.LineNumberDistanceFromText + //ExFor:PageSetup.LineNumberCountBy + //ExFor:PageSetup.LineNumberRestartMode + //ExFor:ParagraphFormat.SuppressLineNumbers + //ExFor:LineNumberRestartMode + //ExSummary:Shows how to enable line numbering for a section. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // We can use the section's PageSetup object to display numbers to the left of the section's text lines. + // This is the same behavior as a List object, + // but it covers the entire section and does not modify the text in any way. + // Our section will restart the numbering on each new page from 1 and display the number, + // if it is a multiple of 3, at 50pt to the left of the line. + PageSetup pageSetup = builder.getPageSetup(); + pageSetup.setLineStartingNumber(1); + pageSetup.setLineNumberCountBy(3); + pageSetup.setLineNumberRestartMode(LineNumberRestartMode.RESTART_PAGE); + pageSetup.setLineNumberDistanceFromText(50.0d); + + for (int i = 1; i <= 25; i++) + builder.writeln(MessageFormat.format("Line {0}.", i)); + + // The line counter will skip any paragraph with the "SuppressLineNumbers" flag set to "true". + // This paragraph is on the 15th line, which is a multiple of 3, and thus would normally display a line number. + // The section's line counter will also ignore this line, treat the next line as the 15th, + // and continue the count from that point onward. + doc.getFirstSection().getBody().getParagraphs().get(14).getParagraphFormat().setSuppressLineNumbers(true); + + doc.save(getArtifactsDir() + "PageSetup.LineNumbers.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.LineNumbers.docx"); + pageSetup = doc.getFirstSection().getPageSetup(); + + Assert.assertEquals(1, pageSetup.getLineStartingNumber()); + Assert.assertEquals(3, pageSetup.getLineNumberCountBy()); + Assert.assertEquals(LineNumberRestartMode.RESTART_PAGE, pageSetup.getLineNumberRestartMode()); + Assert.assertEquals(50.0d, pageSetup.getLineNumberDistanceFromText()); + } + + @Test + public void pageBorderProperties() throws Exception { + //ExStart + //ExFor:Section.PageSetup + //ExFor:PageSetup.BorderAlwaysInFront + //ExFor:PageSetup.BorderDistanceFrom + //ExFor:PageSetup.BorderAppliesTo + //ExFor:PageBorderDistanceFrom + //ExFor:PageBorderAppliesTo + //ExFor:Border.DistanceFromText + //ExSummary:Shows how to create a wide blue band border at the top of the first page. + Document doc = new Document(); + + PageSetup pageSetup = doc.getSections().get(0).getPageSetup(); + pageSetup.setBorderAlwaysInFront(false); + pageSetup.setBorderDistanceFrom(PageBorderDistanceFrom.PAGE_EDGE); + pageSetup.setBorderAppliesTo(PageBorderAppliesTo.FIRST_PAGE); + + Border border = pageSetup.getBorders().getByBorderType(BorderType.TOP); + border.setLineStyle(LineStyle.SINGLE); + border.setLineWidth(30.0); + border.setColor(Color.BLUE); + border.setDistanceFromText(0.0); + + doc.save(getArtifactsDir() + "PageSetup.PageBorderProperties.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.PageBorderProperties.docx"); + pageSetup = doc.getFirstSection().getPageSetup(); + + Assert.assertFalse(pageSetup.getBorderAlwaysInFront()); + Assert.assertEquals(PageBorderDistanceFrom.PAGE_EDGE, pageSetup.getBorderDistanceFrom()); + Assert.assertEquals(PageBorderAppliesTo.FIRST_PAGE, pageSetup.getBorderAppliesTo()); + + border = pageSetup.getBorders().getByBorderType(BorderType.TOP); + + Assert.assertEquals(LineStyle.SINGLE, border.getLineStyle()); + Assert.assertEquals(30.0d, border.getLineWidth()); + Assert.assertEquals(Color.BLUE.getRGB(), border.getColor().getRGB()); + Assert.assertEquals(0.0d, border.getDistanceFromText()); + } + + @Test + public void pageBorders() throws Exception { + //ExStart + //ExFor:PageSetup.Borders + //ExFor:Border.Shadow + //ExFor:BorderCollection.LineStyle + //ExFor:BorderCollection.LineWidth + //ExFor:BorderCollection.Color + //ExFor:BorderCollection.DistanceFromText + //ExFor:BorderCollection.Shadow + //ExSummary:Shows how to create green wavy page border with a shadow. + Document doc = new Document(); + PageSetup pageSetup = doc.getSections().get(0).getPageSetup(); + + pageSetup.getBorders().setLineStyle(LineStyle.DOUBLE_WAVE); + pageSetup.getBorders().setLineWidth(2.0); + pageSetup.getBorders().setColor(Color.GREEN); + pageSetup.getBorders().setDistanceFromText(24.0); + pageSetup.getBorders().setShadow(true); + + doc.save(getArtifactsDir() + "PageSetup.PageBorders.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.PageBorders.docx"); + pageSetup = doc.getFirstSection().getPageSetup(); + + for (Border border : pageSetup.getBorders()) { + Assert.assertEquals(LineStyle.DOUBLE_WAVE, border.getLineStyle()); + Assert.assertEquals(2.0d, border.getLineWidth()); + Assert.assertEquals(Color.GREEN.getRGB(), border.getColor().getRGB()); + Assert.assertEquals(24.0d, border.getDistanceFromText()); + Assert.assertTrue(border.getShadow()); + } + } + + @Test + public void pageNumbering() throws Exception { + //ExStart + //ExFor:PageSetup.RestartPageNumbering + //ExFor:PageSetup.PageStartingNumber + //ExFor:PageSetup.PageNumberStyle + //ExFor:DocumentBuilder.InsertField(String, String) + //ExSummary:Shows how to set up page numbering in a section. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Section 1, page 1."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Section 1, page 2."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Section 1, page 3."); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.writeln("Section 2, page 1."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Section 2, page 2."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Section 2, page 3."); + + // Move the document builder to the first section's primary header, + // which every page in that section will display. + builder.moveToSection(0); + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + + // Insert a PAGE field, which will display the number of the current page. + builder.write("Page "); + builder.insertField("PAGE", ""); + + // Configure the section to have the page count that PAGE fields display start from 5. + // Also, configure all PAGE fields to display their page numbers using uppercase Roman numerals. + PageSetup pageSetup = doc.getSections().get(0).getPageSetup(); + pageSetup.setRestartPageNumbering(true); + pageSetup.setPageStartingNumber(5); + pageSetup.setPageNumberStyle(NumberStyle.UPPERCASE_ROMAN); + + // Create another primary header for the second section, with another PAGE field. + builder.moveToSection(1); + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.write(" - "); + builder.insertField("PAGE", ""); + builder.write(" - "); + + // Configure the section to have the page count that PAGE fields display start from 10. + // Also, configure all PAGE fields to display their page numbers using Arabic numbers. + pageSetup = doc.getSections().get(1).getPageSetup(); + pageSetup.setPageStartingNumber(10); + pageSetup.setRestartPageNumbering(true); + pageSetup.setPageNumberStyle(NumberStyle.ARABIC); + + doc.save(getArtifactsDir() + "PageSetup.PageNumbering.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.PageNumbering.docx"); + pageSetup = doc.getSections().get(0).getPageSetup(); + + Assert.assertTrue(pageSetup.getRestartPageNumbering()); + Assert.assertEquals(5, pageSetup.getPageStartingNumber()); + Assert.assertEquals(NumberStyle.UPPERCASE_ROMAN, pageSetup.getPageNumberStyle()); + + pageSetup = doc.getSections().get(1).getPageSetup(); + + Assert.assertTrue(pageSetup.getRestartPageNumbering()); + Assert.assertEquals(10, pageSetup.getPageStartingNumber()); + Assert.assertEquals(NumberStyle.ARABIC, pageSetup.getPageNumberStyle()); + } + + @Test + public void footnoteOptions() throws Exception { + //ExStart + //ExFor:PageSetup.EndnoteOptions + //ExFor:PageSetup.FootnoteOptions + //ExSummary:Shows how to configure options affecting footnotes/endnotes in a section. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Hello world!"); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote reference text."); + + // Configure all footnotes in the first section to restart the numbering from 1 + // at each new page and display themselves directly beneath the text on every page. + FootnoteOptions footnoteOptions = doc.getSections().get(0).getPageSetup().getFootnoteOptions(); + footnoteOptions.setPosition(FootnotePosition.BENEATH_TEXT); + footnoteOptions.setRestartRule(FootnoteNumberingRule.RESTART_PAGE); + footnoteOptions.setStartNumber(1); + + builder.write(" Hello again."); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Endnote reference text."); + + // Configure all endnotes in the first section to maintain a continuous count throughout the section, + // starting from 1. Also, set them all to appear collected at the end of the document. + EndnoteOptions endnoteOptions = doc.getSections().get(0).getPageSetup().getEndnoteOptions(); + endnoteOptions.setPosition(EndnotePosition.END_OF_DOCUMENT); + endnoteOptions.setRestartRule(FootnoteNumberingRule.CONTINUOUS); + endnoteOptions.setStartNumber(1); + + doc.save(getArtifactsDir() + "PageSetup.FootnoteOptions.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.FootnoteOptions.docx"); + footnoteOptions = doc.getFirstSection().getPageSetup().getFootnoteOptions(); + + Assert.assertEquals(FootnotePosition.BENEATH_TEXT, footnoteOptions.getPosition()); + Assert.assertEquals(FootnoteNumberingRule.RESTART_PAGE, footnoteOptions.getRestartRule()); + Assert.assertEquals(1, footnoteOptions.getStartNumber()); + + endnoteOptions = doc.getFirstSection().getPageSetup().getEndnoteOptions(); + + Assert.assertEquals(EndnotePosition.END_OF_DOCUMENT, endnoteOptions.getPosition()); + Assert.assertEquals(FootnoteNumberingRule.CONTINUOUS, endnoteOptions.getRestartRule()); + Assert.assertEquals(1, endnoteOptions.getStartNumber()); + } + + @Test(dataProvider = "bidiDataProvider") + public void bidi(boolean reverseColumns) throws Exception { + //ExStart + //ExFor:PageSetup.Bidi + //ExSummary:Shows how to set the order of text columns in a section. + Document doc = new Document(); + + PageSetup pageSetup = doc.getSections().get(0).getPageSetup(); + pageSetup.getTextColumns().setCount(3); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.write("Column 1."); + builder.insertBreak(BreakType.COLUMN_BREAK); + builder.write("Column 2."); + builder.insertBreak(BreakType.COLUMN_BREAK); + builder.write("Column 3."); + + // Set the "Bidi" property to "true" to arrange the columns starting from the page's right side. + // The order of the columns will match the direction of the right-to-left text. + // Set the "Bidi" property to "false" to arrange the columns starting from the page's left side. + // The order of the columns will match the direction of the left-to-right text. + pageSetup.setBidi(reverseColumns); + + doc.save(getArtifactsDir() + "PageSetup.Bidi.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.Bidi.docx"); + pageSetup = doc.getFirstSection().getPageSetup(); + + Assert.assertEquals(3, pageSetup.getTextColumns().getCount()); + Assert.assertEquals(reverseColumns, pageSetup.getBidi()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "bidiDataProvider") + public static Object[][] bidiDataProvider() throws Exception { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void pageBorder() throws Exception { + //ExStart + //ExFor:PageSetup.BorderSurroundsFooter + //ExFor:PageSetup.BorderSurroundsHeader + //ExSummary:Shows how to apply a border to the page and header/footer. + Document doc = new Document(); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world! This is the main body text."); + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.write("This is the header."); + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + builder.write("This is the footer."); + builder.moveToDocumentEnd(); + + // Insert a blue double-line border. + PageSetup pageSetup = doc.getSections().get(0).getPageSetup(); + pageSetup.getBorders().setLineStyle(LineStyle.DOUBLE); + pageSetup.getBorders().setColor(Color.BLUE); + + // A section's PageSetup object has "BorderSurroundsHeader" and "BorderSurroundsFooter" flags that determine + // whether a page border surrounds the main body text, also includes the header or footer, respectively. + // Set the "BorderSurroundsHeader" flag to "true" to surround the header with our border, + // and then set the "BorderSurroundsFooter" flag to leave the footer outside of the border. + pageSetup.setBorderSurroundsHeader(true); + pageSetup.setBorderSurroundsFooter(false); + + doc.save(getArtifactsDir() + "PageSetup.PageBorder.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.PageBorder.docx"); + pageSetup = doc.getFirstSection().getPageSetup(); + + Assert.assertTrue(pageSetup.getBorderSurroundsHeader()); + Assert.assertFalse(pageSetup.getBorderSurroundsFooter()); + } + + @Test + public void gutter() throws Exception { + //ExStart + //ExFor:PageSetup.Gutter + //ExFor:PageSetup.RtlGutter + //ExFor:PageSetup.MultiplePages + //ExSummary:Shows how to set gutter margins. + Document doc = new Document(); + + // Insert text that spans several pages. + DocumentBuilder builder = new DocumentBuilder(doc); + for (int i = 0; i < 6; i++) { + builder.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + builder.insertBreak(BreakType.PAGE_BREAK); + } + + // A gutter adds whitespaces to either the left or right page margin, + // which makes up for the center folding of pages in a book encroaching on the page's layout. + PageSetup pageSetup = doc.getSections().get(0).getPageSetup(); + + // Determine how much space our pages have for text within the margins and then add an amount to pad a margin. + Assert.assertEquals(468.00d, pageSetup.getPageWidth() - pageSetup.getLeftMargin() - pageSetup.getRightMargin(), 0.01d); + + pageSetup.setGutter(100.0d); + + // Set the "RtlGutter" property to "true" to place the gutter in a more suitable position for right-to-left text. + pageSetup.setRtlGutter(true); + + // Set the "MultiplePages" property to "MultiplePagesType.MirrorMargins" to alternate + // the left/right page side position of margins every page. + pageSetup.setMultiplePages(MultiplePagesType.MIRROR_MARGINS); + + doc.save(getArtifactsDir() + "PageSetup.Gutter.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.Gutter.docx"); + pageSetup = doc.getFirstSection().getPageSetup(); + + Assert.assertEquals(100.0d, pageSetup.getGutter()); + Assert.assertTrue(pageSetup.getRtlGutter()); + Assert.assertEquals(MultiplePagesType.MIRROR_MARGINS, pageSetup.getMultiplePages()); + } + + @Test + public void booklet() throws Exception { + //ExStart + //ExFor:PageSetup.Gutter + //ExFor:PageSetup.MultiplePages + //ExFor:PageSetup.SheetsPerBooklet + //ExFor:MultiplePagesType + //ExSummary:Shows how to configure a document that can be printed as a book fold. + Document doc = new Document(); + + // Insert text that spans 16 pages. + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("My Booklet:"); + + for (int i = 0; i < 15; i++) { + builder.insertBreak(BreakType.PAGE_BREAK); + builder.write(MessageFormat.format("Booklet face #{0}", i)); + } + + // Configure the first section's "PageSetup" property to print the document in the form of a book fold. + // When we print this document on both sides, we can take the pages to stack them + // and fold them all down the middle at once. The contents of the document will line up into a book fold. + PageSetup pageSetup = doc.getSections().get(0).getPageSetup(); + pageSetup.setMultiplePages(MultiplePagesType.BOOK_FOLD_PRINTING); + + // We can only specify the number of sheets in multiples of 4. + pageSetup.setSheetsPerBooklet(4); + + doc.save(getArtifactsDir() + "PageSetup.Booklet.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.Booklet.docx"); + pageSetup = doc.getFirstSection().getPageSetup(); + + Assert.assertEquals(MultiplePagesType.BOOK_FOLD_PRINTING, pageSetup.getMultiplePages()); + Assert.assertEquals(4, pageSetup.getSheetsPerBooklet()); + } + + @Test + public void setTextOrientation() throws Exception { + //ExStart + //ExFor:PageSetup.TextOrientation + //ExSummary:Shows how to set text orientation. + Document doc = new Document(); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + // Set the "TextOrientation" property to "TextOrientation.Upward" to rotate all the text 90 degrees + // to the right so that all left-to-right text now goes top-to-bottom. + PageSetup pageSetup = doc.getSections().get(0).getPageSetup(); + pageSetup.setTextOrientation(TextOrientation.UPWARD); + + doc.save(getArtifactsDir() + "PageSetup.SetTextOrientation.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.SetTextOrientation.docx"); + pageSetup = doc.getFirstSection().getPageSetup(); + + Assert.assertEquals(TextOrientation.UPWARD, pageSetup.getTextOrientation()); + } + + //ExStart + //ExFor:PageSetup.SuppressEndnotes + //ExFor:Body.ParentSection + //ExSummary:Shows how to store endnotes at the end of each section, and modify their positions. + @Test //ExSkip + public void suppressEndnotes() throws Exception { + Document doc = new Document(); + doc.removeAllChildren(); + + // By default, a document compiles all endnotes at its end. + Assert.assertEquals(EndnotePosition.END_OF_DOCUMENT, doc.getEndnoteOptions().getPosition()); + + // We use the "Position" property of the document's "EndnoteOptions" object + // to collect endnotes at the end of each section instead. + doc.getEndnoteOptions().setPosition(EndnotePosition.END_OF_SECTION); + + insertSectionWithEndnote(doc, "Section 1", "Endnote 1, will stay in section 1"); + insertSectionWithEndnote(doc, "Section 2", "Endnote 2, will be pushed down to section 3"); + insertSectionWithEndnote(doc, "Section 3", "Endnote 3, will stay in section 3"); + + // While getting sections to display their respective endnotes, we can set the "SuppressEndnotes" flag + // of a section's "PageSetup" object to "true" to revert to the default behavior and pass its endnotes + // onto the next section. + PageSetup pageSetup = doc.getSections().get(1).getPageSetup(); + pageSetup.setSuppressEndnotes(true); + + doc.save(getArtifactsDir() + "PageSetup.SuppressEndnotes.docx"); + testSuppressEndnotes(new Document(getArtifactsDir() + "PageSetup.SuppressEndnotes.docx")); //ExSkip + } + + /// + /// Append a section with text and an endnote to a document. + /// + private static void insertSectionWithEndnote(Document doc, String sectionBodyText, String endnoteText) { + Section section = new Section(doc); + + doc.appendChild(section); + + Body body = new Body(doc); + section.appendChild(body); + + Assert.assertEquals(body.getParentNode(), section); + + Paragraph para = new Paragraph(doc); + body.appendChild(para); + + Assert.assertEquals(para.getParentNode(), body); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.moveTo(para); + builder.write(sectionBodyText); + builder.insertFootnote(FootnoteType.ENDNOTE, endnoteText); + } + //ExEnd + + private static void testSuppressEndnotes(Document doc) { + PageSetup pageSetup = doc.getSections().get(1).getPageSetup(); + + Assert.assertTrue(pageSetup.getSuppressEndnotes()); + } + + @Test + public void chapterPageSeparator() throws Exception + { + //ExStart + //ExFor:PageSetup.HeadingLevelForChapter + //ExFor:ChapterPageSeparator + //ExFor:PageSetup.ChapterPageSeparator + //ExSummary:Shows how to work with page chapters. + Document doc = new Document(getMyDir() + "Big document.docx"); + + PageSetup pageSetup = doc.getFirstSection().getPageSetup(); + + pageSetup.setPageNumberStyle(NumberStyle.UPPERCASE_ROMAN); + pageSetup.setChapterPageSeparator(com.aspose.words.ChapterPageSeparator.COLON); + pageSetup.setHeadingLevelForChapter(1); + //ExEnd + } + + @Test + public void jisbPaperSize() throws Exception + { + //ExStart:JisbPaperSize + //GistId:cc5f9f2033531562b29954d9f73776a5 + //ExFor:PageSetup.PaperSize + //ExSummary:Shows how to set the paper size of JisB4 or JisB5. + Document doc = new Document(getMyDir() + "Big document.docx"); + + PageSetup pageSetup = doc.getFirstSection().getPageSetup(); + // Set the paper size to JisB4 (257x364mm). + pageSetup.setPaperSize(PaperSize.JIS_B_4); + // Alternatively, set the paper size to JisB5. (182x257mm). + pageSetup.setPaperSize(PaperSize.JIS_B_5); + //ExEnd:JisbPaperSize + + doc = DocumentHelper.saveOpen(doc); + pageSetup = doc.getFirstSection().getPageSetup(); + + Assert.assertEquals(PaperSize.JIS_B_5, pageSetup.getPaperSize()); + } + + @Test(enabled = false, description = "Run only when the printer driver is installed") + public void PrintPagesRemaining() throws Exception { + //ExStart:PrintPagesRemaining + //GistId:571cc6e23284a2ec075d15d4c32e3bbf + //ExFor:AsposeWordsPrintDocument + //ExFor:AsposeWordsPrintDocument.PagesRemaining + //ExSummary: Shows how to monitor printing progress. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // Create a special Aspose.Words implementation of the Java PrintDocument class + AsposeWordsPrintDocument printDoc = new AsposeWordsPrintDocument(doc); + + // In Java, printer settings are handled through PrinterJob. + PrinterJob printerJob = PrinterJob.getPrinterJob(); + printerJob.setPrintable(printDoc); + + // Initialize the custom printing tracker. + PrintTracker printTracker = new PrintTracker(printDoc); + + printerJob.print(); + + // Write the event log. + for (String eventString : printTracker.getEventLog()) { + System.out.println(eventString); + } + //ExEnd:PrintPagesRemaining + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExParagraph.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExParagraph.java new file mode 100644 index 00000000..e9901d79 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExParagraph.java @@ -0,0 +1,623 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.Font; +import com.aspose.words.*; +import org.apache.commons.collections4.IterableUtils; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.awt.*; +import java.text.MessageFormat; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Date; +import java.util.Locale; + +public class ExParagraph extends ApiExampleBase { + @Test + public void documentBuilderInsertParagraph() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertParagraph + //ExFor:ParagraphFormat.FirstLineIndent + //ExFor:ParagraphFormat.Alignment + //ExFor:ParagraphFormat.KeepTogether + //ExFor:ParagraphFormat.AddSpaceBetweenFarEastAndAlpha + //ExFor:ParagraphFormat.AddSpaceBetweenFarEastAndDigit + //ExFor:Paragraph.IsEndOfDocument + //ExSummary:Shows how to insert a paragraph into the document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Font font = builder.getFont(); + font.setSize(16.0); + font.setBold(true); + font.setColor(Color.BLUE); + font.setName("Arial"); + font.setUnderline(Underline.DASH); + + ParagraphFormat paragraphFormat = builder.getParagraphFormat(); + paragraphFormat.setFirstLineIndent(8.0); + paragraphFormat.setAlignment(ParagraphAlignment.JUSTIFY); + paragraphFormat.setAddSpaceBetweenFarEastAndAlpha(true); + paragraphFormat.setAddSpaceBetweenFarEastAndDigit(true); + paragraphFormat.setKeepTogether(true); + + // The "Writeln" method ends the paragraph after appending text + // and then starts a new line, adding a new paragraph. + builder.writeln("Hello world!"); + + Assert.assertTrue(builder.getCurrentParagraph().isEndOfDocument()); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + Paragraph paragraph = doc.getFirstSection().getBody().getFirstParagraph(); + + Assert.assertEquals(8.0d, paragraph.getParagraphFormat().getFirstLineIndent()); + Assert.assertEquals(ParagraphAlignment.JUSTIFY, paragraph.getParagraphFormat().getAlignment()); + Assert.assertTrue(paragraph.getParagraphFormat().getAddSpaceBetweenFarEastAndAlpha()); + Assert.assertTrue(paragraph.getParagraphFormat().getAddSpaceBetweenFarEastAndDigit()); + Assert.assertTrue(paragraph.getParagraphFormat().getKeepTogether()); + Assert.assertEquals("Hello world!", paragraph.getText().trim()); + + Font runFont = paragraph.getRuns().get(0).getFont(); + + Assert.assertEquals(16.0d, runFont.getSize()); + Assert.assertTrue(runFont.getBold()); + Assert.assertEquals(Color.BLUE.getRGB(), runFont.getColor().getRGB()); + Assert.assertEquals("Arial", runFont.getName()); + Assert.assertEquals(Underline.DASH, runFont.getUnderline()); + } + + @Test + public void appendField() throws Exception { + //ExStart + //ExFor:Paragraph.AppendField(FieldType, Boolean) + //ExFor:Paragraph.AppendField(String) + //ExFor:Paragraph.AppendField(String, String) + //ExSummary:Shows various ways of appending fields to a paragraph. + Document doc = new Document(); + Paragraph paragraph = doc.getFirstSection().getBody().getFirstParagraph(); + + // Below are three ways of appending a field to the end of a paragraph. + // 1 - Append a DATE field using a field type, and then update it: + paragraph.appendField(FieldType.FIELD_DATE, true); + + // 2 - Append a TIME field using a field code: + paragraph.appendField(" TIME \\@ \"HH:mm:ss\" "); + + // 3 - Append a QUOTE field using a field code, and get it to display a placeholder value: + paragraph.appendField(" QUOTE \"Real value\"", "Placeholder value"); + + Assert.assertEquals("Placeholder value", doc.getRange().getFields().get(2).getResult()); + + // This field will display its placeholder value until we update it. + doc.updateFields(); + + Assert.assertEquals("Real value", doc.getRange().getFields().get(2).getResult()); + + doc.save(getArtifactsDir() + "Paragraph.AppendField.docx"); + //ExEnd + } + + @Test + public void insertField() throws Exception { + //ExStart + //ExFor:Paragraph.InsertField(string, Node, bool) + //ExFor:Paragraph.InsertField(FieldType, bool, Node, bool) + //ExFor:Paragraph.InsertField(string, string, Node, bool) + //ExSummary:Shows various ways of adding fields to a paragraph. + Document doc = new Document(); + Paragraph para = doc.getFirstSection().getBody().getFirstParagraph(); + + // Below are three ways of inserting a field into a paragraph. + // 1 - Insert an AUTHOR field into a paragraph after one of the paragraph's child nodes: + Run run = new Run(doc); + { + run.setText("This run was written by "); + } + para.appendChild(run); + + doc.getBuiltInDocumentProperties().get("Author").setValue("John Doe"); + para.insertField(FieldType.FIELD_AUTHOR, true, run, true); + + // 2 - Insert a QUOTE field after one of the paragraph's child nodes: + run = new Run(doc); + { + run.setText("."); + } + para.appendChild(run); + + Field field = para.insertField(" QUOTE \" Real value\" ", run, true); + + // 3 - Insert a QUOTE field before one of the paragraph's child nodes, + // and get it to display a placeholder value: + para.insertField(" QUOTE \" Real value.\"", " Placeholder value.", field.getStart(), false); + + Assert.assertEquals(" Placeholder value.", doc.getRange().getFields().get(1).getResult()); + + // This field will display its placeholder value until we update it. + doc.updateFields(); + + Assert.assertEquals(" Real value.", doc.getRange().getFields().get(1).getResult()); + + doc.save(getArtifactsDir() + "Paragraph.InsertField.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Paragraph.InsertField.docx"); + + TestUtil.verifyField(FieldType.FIELD_AUTHOR, " AUTHOR ", "John Doe", doc.getRange().getFields().get(0)); + TestUtil.verifyField(FieldType.FIELD_QUOTE, " QUOTE \" Real value.\"", " Real value.", doc.getRange().getFields().get(1)); + TestUtil.verifyField(FieldType.FIELD_QUOTE, " QUOTE \" Real value\" ", " Real value", doc.getRange().getFields().get(2)); + } + + @Test + public void insertFieldBeforeTextInParagraph() throws Exception { + Document doc = DocumentHelper.createDocumentFillWithDummyText(); + + insertFieldUsingFieldCode(doc, " AUTHOR ", null, false, 1); + + Assert.assertEquals(DocumentHelper.getParagraphText(doc, 1), "\u0013 AUTHOR \u0014Test Author\u0015Hello World!\r"); + } + + @Test + public void insertFieldAfterTextInParagraph() throws Exception { + LocalDateTime ldt = LocalDateTime.now(); + String date = DateTimeFormatter.ofPattern("M/d/yyyy", Locale.ENGLISH).format(ldt); + + Document doc = DocumentHelper.createDocumentFillWithDummyText(); + + insertFieldUsingFieldCode(doc, " DATE ", null, true, 1); + + Assert.assertEquals(DocumentHelper.getParagraphText(doc, 1), MessageFormat.format("Hello World!\u0013 DATE \u0014{0}\u0015\r", date)); + } + + @Test + public void insertFieldBeforeTextInParagraphWithoutUpdateField() throws Exception { + Document doc = DocumentHelper.createDocumentFillWithDummyText(); + + insertFieldUsingFieldType(doc, FieldType.FIELD_AUTHOR, false, null, false, 1); + + Assert.assertEquals(DocumentHelper.getParagraphText(doc, 1), "\u0013 AUTHOR \u0014\u0015Hello World!\r"); + } + + @Test + public void insertFieldAfterTextInParagraphWithoutUpdateField() throws Exception { + Document doc = DocumentHelper.createDocumentFillWithDummyText(); + + insertFieldUsingFieldType(doc, FieldType.FIELD_AUTHOR, false, null, true, 1); + + Assert.assertEquals(DocumentHelper.getParagraphText(doc, 1), "Hello World!\u0013 AUTHOR \u0014\u0015\r"); + } + + @Test + public void insertFieldWithoutSeparator() throws Exception { + Document doc = DocumentHelper.createDocumentFillWithDummyText(); + + insertFieldUsingFieldType(doc, FieldType.FIELD_LIST_NUM, true, null, false, 1); + + Assert.assertEquals(DocumentHelper.getParagraphText(doc, 1), "\u0013 LISTNUM \u0015Hello World!\r"); + } + + @Test + public void insertFieldBeforeParagraphWithoutDocumentAuthor() throws Exception { + Document doc = DocumentHelper.createDocumentFillWithDummyText(); + doc.getBuiltInDocumentProperties().setAuthor(""); + + insertFieldUsingFieldCodeFieldString(doc, " AUTHOR ", null, null, false, 1); + + Assert.assertEquals(DocumentHelper.getParagraphText(doc, 1), "\u0013 AUTHOR \u0014\u0015Hello World!\r"); + } + + @Test + public void insertFieldAfterParagraphWithoutChangingDocumentAuthor() throws Exception { + Document doc = DocumentHelper.createDocumentFillWithDummyText(); + + insertFieldUsingFieldCodeFieldString(doc, " AUTHOR ", null, null, true, 1); + + Assert.assertEquals(DocumentHelper.getParagraphText(doc, 1), "Hello World!\u0013 AUTHOR \u0014\u0015\r"); + } + + @Test + public void insertFieldBeforeRunText() throws Exception { + Document doc = DocumentHelper.createDocumentFillWithDummyText(); + + // Add some text into the paragraph + Run run = DocumentHelper.insertNewRun(doc, " Hello World!", 1); + + insertFieldUsingFieldCodeFieldString(doc, " AUTHOR ", "Test Field Value", run, false, 1); + + Assert.assertEquals(DocumentHelper.getParagraphText(doc, 1), "Hello World!\u0013 AUTHOR \u0014Test Field Value\u0015 Hello World!\r"); + } + + @Test + public void insertFieldAfterRunText() throws Exception { + Document doc = DocumentHelper.createDocumentFillWithDummyText(); + + // Add some text into the paragraph + Run run = DocumentHelper.insertNewRun(doc, " Hello World!", 1); + + insertFieldUsingFieldCodeFieldString(doc, " AUTHOR ", "", run, true, 1); + + Assert.assertEquals(DocumentHelper.getParagraphText(doc, 1), "Hello World! Hello World!\u0013 AUTHOR \u0014\u0015\r"); + } + + @Test(description = "WORDSNET-12396") + public void insertFieldEmptyParagraphWithoutUpdateField() throws Exception { + Document doc = DocumentHelper.createDocumentWithoutDummyText(); + + insertFieldUsingFieldType(doc, FieldType.FIELD_AUTHOR, false, null, false, 1); + + Assert.assertEquals(DocumentHelper.getParagraphText(doc, 1), "\u0013 AUTHOR \u0014\u0015\f"); + } + + @Test(description = "WORDSNET-12397") + public void insertFieldEmptyParagraphWithUpdateField() throws Exception { + Document doc = DocumentHelper.createDocumentWithoutDummyText(); + + insertFieldUsingFieldType(doc, FieldType.FIELD_AUTHOR, true, null, false, 0); + + Assert.assertEquals(DocumentHelper.getParagraphText(doc, 0), "\u0013 AUTHOR \u0014Test Author\u0015\r"); + } + + @Test + public void compositeNodeChildren() throws Exception { + //ExStart + //ExFor:CompositeNode.Count + //ExFor:CompositeNode.GetChildNodes(NodeType, Boolean) + //ExFor:CompositeNode.InsertAfter``1(``0, Node) + //ExFor:CompositeNode.InsertBefore``1(``0, Node) + //ExFor:CompositeNode.PrependChild``1(``0) + //ExFor:Paragraph.GetText + //ExFor:Run + //ExSummary:Shows how to add, update and delete child nodes in a CompositeNode's collection of children. + Document doc = new Document(); + + // An empty document, by default, has one paragraph. + Assert.assertEquals(1, doc.getFirstSection().getBody().getParagraphs().getCount()); + + // Composite nodes such as our paragraph can contain other composite and inline nodes as children. + Paragraph paragraph = doc.getFirstSection().getBody().getFirstParagraph(); + Run paragraphText = new Run(doc, "Initial text. "); + paragraph.appendChild(paragraphText); + + // Create three more run nodes. + Run run1 = new Run(doc, "Run 1. "); + Run run2 = new Run(doc, "Run 2. "); + Run run3 = new Run(doc, "Run 3. "); + + // The document body will not display these runs until we insert them into a composite node + // that itself is a part of the document's node tree, as we did with the first run. + // We can determine where the text contents of nodes that we insert + // appears in the document by specifying an insertion location relative to another node in the paragraph. + Assert.assertEquals("Initial text.", paragraph.getText().trim()); + + // Insert the second run into the paragraph in front of the initial run. + paragraph.insertBefore(run2, paragraphText); + + Assert.assertEquals("Run 2. Initial text.", paragraph.getText().trim()); + + // Insert the third run after the initial run. + paragraph.insertAfter(run3, paragraphText); + + Assert.assertEquals("Run 2. Initial text. Run 3.", paragraph.getText().trim()); + + // Insert the first run to the start of the paragraph's child nodes collection. + paragraph.prependChild(run1); + + Assert.assertEquals("Run 1. Run 2. Initial text. Run 3.", paragraph.getText().trim()); + Assert.assertEquals(4, paragraph.getChildNodes(NodeType.ANY, true).getCount()); + + // We can modify the contents of the run by editing and deleting existing child nodes. + ((Run) paragraph.getChildNodes(NodeType.RUN, true).get(1)).setText("Updated run 2. "); + paragraph.getChildNodes(NodeType.RUN, true).remove(paragraphText); + + Assert.assertEquals("Run 1. Updated run 2. Run 3.", paragraph.getText().trim()); + Assert.assertEquals(3, paragraph.getChildNodes(NodeType.ANY, true).getCount()); + //ExEnd + } + + @Test + public void moveRevisions() throws Exception { + //ExStart + //ExFor:Paragraph.IsMoveFromRevision + //ExFor:Paragraph.IsMoveToRevision + //ExFor:ParagraphCollection + //ExFor:ParagraphCollection.Item(Int32) + //ExFor:Story.Paragraphs + //ExSummary:Shows how to check whether a paragraph is a move revision. + Document doc = new Document(getMyDir() + "Revisions.docx"); + + // This document contains "Move" revisions, which appear when we highlight text with the cursor, + // and then drag it to move it to another location + // while tracking revisions in Microsoft Word via "Review" -> "Track changes". + Assert.assertEquals(6, IterableUtils.countMatches(doc.getRevisions(), r -> r.getRevisionType() == RevisionType.MOVING)); + + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + // Move revisions consist of pairs of "Move from", and "Move to" revisions. + // These revisions are potential changes to the document that we can either accept or reject. + // Before we accept/reject a move revision, the document + // must keep track of both the departure and arrival destinations of the text. + // The second and the fourth paragraph define one such revision, and thus both have the same contents. + Assert.assertEquals(paragraphs.get(1).getText(), paragraphs.get(3).getText()); + + // The "Move from" revision is the paragraph where we dragged the text from. + // If we accept the revision, this paragraph will disappear, + // and the other will remain and no longer be a revision. + Assert.assertTrue(paragraphs.get(1).isMoveFromRevision()); + + // The "Move to" revision is the paragraph where we dragged the text to. + // If we reject the revision, this paragraph instead will disappear, and the other will remain. + Assert.assertTrue(paragraphs.get(3).isMoveToRevision()); + //ExEnd + } + + @Test + public void rangeRevisions() throws Exception + { + //ExStart + //ExFor:Range.Revisions + //ExSummary:Shows how to work with revisions in range. + Document doc = new Document(getMyDir() + "Revisions.docx"); + + Paragraph paragraph = doc.getFirstSection().getBody().getFirstParagraph(); + for (Revision revision : paragraph.getRange().getRevisions()) + { + if (revision.getRevisionType() == RevisionType.DELETION) + revision.accept(); + } + + // Reject the first section revisions. + doc.getFirstSection().getRange().getRevisions().rejectAll(); + //ExEnd + } + + @Test + public void getFormatRevision() throws Exception { + //ExStart + //ExFor:Paragraph.IsFormatRevision + //ExSummary:Shows how to check whether a paragraph is a format revision. + Document doc = new Document(getMyDir() + "Format revision.docx"); + + // This paragraph is a "Format" revision, which occurs when we change the formatting of existing text + // while tracking revisions in Microsoft Word via "Review" -> "Track changes". + Assert.assertTrue(doc.getFirstSection().getBody().getFirstParagraph().isFormatRevision()); + //ExEnd + } + + @Test + public void getFrameProperties() throws Exception { + //ExStart + //ExFor:Paragraph.FrameFormat + //ExFor:FrameFormat + //ExFor:FrameFormat.IsFrame + //ExFor:FrameFormat.Width + //ExFor:FrameFormat.Height + //ExFor:FrameFormat.HeightRule + //ExFor:FrameFormat.HorizontalAlignment + //ExFor:FrameFormat.VerticalAlignment + //ExFor:FrameFormat.HorizontalPosition + //ExFor:FrameFormat.RelativeHorizontalPosition + //ExFor:FrameFormat.HorizontalDistanceFromText + //ExFor:FrameFormat.VerticalPosition + //ExFor:FrameFormat.RelativeVerticalPosition + //ExFor:FrameFormat.VerticalDistanceFromText + //ExSummary:Shows how to get information about formatting properties of paragraphs that are frames. + Document doc = new Document(getMyDir() + "Paragraph frame.docx"); + + Paragraph paragraphFrame = IterableUtils.find(doc.getFirstSection().getBody().getParagraphs(), p -> p.getFrameFormat().isFrame()); + + Assert.assertEquals(233.3d, paragraphFrame.getFrameFormat().getWidth()); + Assert.assertEquals(138.8d, paragraphFrame.getFrameFormat().getHeight()); + Assert.assertEquals(HeightRule.AT_LEAST, paragraphFrame.getFrameFormat().getHeightRule()); + Assert.assertEquals(HorizontalAlignment.DEFAULT, paragraphFrame.getFrameFormat().getHorizontalAlignment()); + Assert.assertEquals(VerticalAlignment.DEFAULT, paragraphFrame.getFrameFormat().getVerticalAlignment()); + Assert.assertEquals(34.05d, paragraphFrame.getFrameFormat().getHorizontalPosition()); + Assert.assertEquals(RelativeHorizontalPosition.PAGE, paragraphFrame.getFrameFormat().getRelativeHorizontalPosition()); + Assert.assertEquals(9.0d, paragraphFrame.getFrameFormat().getHorizontalDistanceFromText()); + Assert.assertEquals(20.5d, paragraphFrame.getFrameFormat().getVerticalPosition()); + Assert.assertEquals(RelativeVerticalPosition.PARAGRAPH, paragraphFrame.getFrameFormat().getRelativeVerticalPosition()); + Assert.assertEquals(0.0d, paragraphFrame.getFrameFormat().getVerticalDistanceFromText()); + //ExEnd + } + + /// + /// Insert field into the first paragraph of the current document using field type. + /// + private static void insertFieldUsingFieldType(Document doc, int fieldType, boolean updateField, Node refNode, + boolean isAfter, int paraIndex) throws Exception { + Paragraph para = DocumentHelper.getParagraph(doc, paraIndex); + para.insertField(fieldType, updateField, refNode, isAfter); + } + + /// + /// Insert field into the first paragraph of the current document using field code. + /// + private static void insertFieldUsingFieldCode(Document doc, String fieldCode, Node refNode, boolean isAfter, + int paraIndex) throws Exception { + Paragraph para = DocumentHelper.getParagraph(doc, paraIndex); + para.insertField(fieldCode, refNode, isAfter); + } + + /// + /// Insert field into the first paragraph of the current document using field code and field String. + /// + private static void insertFieldUsingFieldCodeFieldString(Document doc, String fieldCode, String fieldValue, + Node refNode, boolean isAfter, int paraIndex) { + Paragraph para = DocumentHelper.getParagraph(doc, paraIndex); + para.insertField(fieldCode, fieldValue, refNode, isAfter); + } + + @Test + public void isRevision() throws Exception { + //ExStart + //ExFor:Paragraph.IsDeleteRevision + //ExFor:Paragraph.IsInsertRevision + //ExSummary:Shows how to work with revision paragraphs. + Document doc = new Document(); + Body body = doc.getFirstSection().getBody(); + Paragraph para = body.getFirstParagraph(); + + para.appendChild(new Run(doc, "Paragraph 1. ")); + body.appendParagraph("Paragraph 2. "); + body.appendParagraph("Paragraph 3. "); + + // The above paragraphs are not revisions. + // Paragraphs that we add after starting revision tracking will register as "Insert" revisions. + doc.startTrackRevisions("John Doe", new Date()); + + para = body.appendParagraph("Paragraph 4. "); + + Assert.assertTrue(para.isInsertRevision()); + + // Paragraphs that we remove after starting revision tracking will register as "Delete" revisions. + ParagraphCollection paragraphs = body.getParagraphs(); + + Assert.assertEquals(4, paragraphs.getCount()); + + para = paragraphs.get(2); + para.remove(); + + // Such paragraphs will remain until we either accept or reject the delete revision. + // Accepting the revision will remove the paragraph for good, + // and rejecting the revision will leave it in the document as if we never deleted it. + Assert.assertEquals(4, paragraphs.getCount()); + Assert.assertTrue(para.isDeleteRevision()); + + // Accept the revision, and then verify that the paragraph is gone. + doc.acceptAllRevisions(); + + Assert.assertEquals(paragraphs.getCount(), 3); + Assert.assertEquals(para.getCount(), 0); + Assert.assertEquals( + "Paragraph 1. \r" + + "Paragraph 2. \r" + + "Paragraph 4.", doc.getText().trim()); + //ExEnd + } + + @Test + public void breakIsStyleSeparator() throws Exception { + //ExStart + //ExFor:Paragraph.BreakIsStyleSeparator + //ExSummary:Shows how to write text to the same line as a TOC heading and have it not show up in the TOC. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertTableOfContents("\\o \\h \\z \\u"); + builder.insertBreak(BreakType.PAGE_BREAK); + + // Insert a paragraph with a style that the TOC will pick up as an entry. + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + + // Both these strings are in the same paragraph and will therefore show up on the same TOC entry. + builder.write("Heading 1. "); + builder.write("Will appear in the TOC. "); + + // If we insert a style separator, we can write more text in the same paragraph + // and use a different style without showing up in the TOC. + // If we use a heading type style after the separator, we can draw multiple TOC entries from one document text line. + builder.insertStyleSeparator(); + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.QUOTE); + builder.write("Won't appear in the TOC. "); + + Assert.assertTrue(doc.getFirstSection().getBody().getParagraphs().get(0).getBreakIsStyleSeparator()); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Paragraph.BreakIsStyleSeparator.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Paragraph.BreakIsStyleSeparator.docx"); + + TestUtil.verifyField(FieldType.FIELD_TOC, "TOC \\o \\h \\z \\u", + "\u0013 HYPERLINK \\l \"_Toc256000000\" \u0014Heading 1. Will appear in the TOC.\t\u0013 PAGEREF _Toc256000000 \\h \u00142\u0015\u0015\r", doc.getRange().getFields().get(0)); + Assert.assertFalse(doc.getFirstSection().getBody().getFirstParagraph().getBreakIsStyleSeparator()); + } + + @Test + public void tabStops() throws Exception { + //ExStart + //ExFor:TabLeader + //ExFor:TabAlignment + //ExFor:Paragraph.GetEffectiveTabStops + //ExSummary:Shows how to set custom tab stops for a paragraph. + Document doc = new Document(); + Paragraph para = doc.getFirstSection().getBody().getFirstParagraph(); + + // If we are in a paragraph with no tab stops in this collection, + // the cursor will jump 36 points each time we press the Tab key in Microsoft Word. + Assert.assertEquals(0, doc.getFirstSection().getBody().getFirstParagraph().getEffectiveTabStops().length); + + // We can add custom tab stops in Microsoft Word if we enable the ruler via the "View" tab. + // Each unit on this ruler is two default tab stops, which is 72 points. + // We can add custom tab stops programmatically like this. + TabStopCollection tabStops = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat().getTabStops(); + tabStops.add(72.0, TabAlignment.LEFT, TabLeader.DOTS); + tabStops.add(216.0, TabAlignment.CENTER, TabLeader.DASHES); + tabStops.add(360.0, TabAlignment.RIGHT, TabLeader.LINE); + + // We can see these tab stops in Microsoft Word by enabling the ruler via "View" -> "Show" -> "Ruler". + Assert.assertEquals(3, para.getEffectiveTabStops().length); + + // Any tab characters we add will make use of the tab stops on the ruler and may, + // depending on the tab leader's value, leave a line between the tab departure and arrival destinations. + para.appendChild(new Run(doc, "\tTab 1\tTab 2\tTab 3")); + + doc.save(getArtifactsDir() + "Paragraph.TabStops.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Paragraph.TabStops.docx"); + tabStops = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat().getTabStops(); + + TestUtil.verifyTabStop(72.0d, TabAlignment.LEFT, TabLeader.DOTS, false, tabStops.get(0)); + TestUtil.verifyTabStop(216.0d, TabAlignment.CENTER, TabLeader.DASHES, false, tabStops.get(1)); + TestUtil.verifyTabStop(360.0d, TabAlignment.RIGHT, TabLeader.LINE, false, tabStops.get(2)); + } + + @Test + public void joinRuns() throws Exception { + //ExStart + //ExFor:Paragraph.JoinRunsWithSameFormatting + //ExSummary:Shows how to simplify paragraphs by merging superfluous runs. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert four runs of text into the paragraph. + builder.write("Run 1. "); + builder.write("Run 2. "); + builder.write("Run 3. "); + builder.write("Run 4. "); + + // If we open this document in Microsoft Word, the paragraph will look like one seamless text body. + // However, it will consist of four separate runs with the same formatting. Fragmented paragraphs like this + // may occur when we manually edit parts of one paragraph many times in Microsoft Word. + Paragraph para = builder.getCurrentParagraph(); + + Assert.assertEquals(4, para.getRuns().getCount()); + + // Change the style of the last run to set it apart from the first three. + para.getRuns().get(3).getFont().setStyleIdentifier(StyleIdentifier.EMPHASIS); + + // We can run the "JoinRunsWithSameFormatting" method to optimize the document's contents + // by merging similar runs into one, reducing their overall count. + // This method also returns the number of runs that this method merged. + // These two merges occurred to combine Runs #1, #2, and #3, + // while leaving out Run #4 because it has an incompatible style. + Assert.assertEquals(2, para.joinRunsWithSameFormatting()); + + // The number of runs left will equal the original count + // minus the number of run merges that the "JoinRunsWithSameFormatting" method carried out. + Assert.assertEquals(2, para.getRuns().getCount()); + Assert.assertEquals("Run 1. Run 2. Run 3. ", para.getRuns().get(0).getText()); + Assert.assertEquals("Run 4. ", para.getRuns().get(1).getText()); + //ExEnd + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExParagraphFormat.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExParagraphFormat.java new file mode 100644 index 00000000..6c414482 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExParagraphFormat.java @@ -0,0 +1,585 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.pdf.TextAbsorber; +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.text.MessageFormat; + +public class ExParagraphFormat extends ApiExampleBase { + @Test + public void asianTypographyProperties() throws Exception { + //ExStart + //ExFor:ParagraphFormat.FarEastLineBreakControl + //ExFor:ParagraphFormat.WordWrap + //ExFor:ParagraphFormat.HangingPunctuation + //ExSummary:Shows how to set special properties for Asian typography. + Document doc = new Document(getMyDir() + "Document.docx"); + + ParagraphFormat format = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat(); + format.setFarEastLineBreakControl(true); + format.setWordWrap(false); + format.setHangingPunctuation(true); + + doc.save(getArtifactsDir() + "ParagraphFormat.AsianTypographyProperties.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "ParagraphFormat.AsianTypographyProperties.docx"); + format = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat(); + + Assert.assertTrue(format.getFarEastLineBreakControl()); + Assert.assertFalse(format.getWordWrap()); + Assert.assertTrue(format.getHangingPunctuation()); + } + + @Test(dataProvider = "dropCapDataProvider") + public void dropCap(int dropCapPosition) throws Exception { + //ExStart + //ExFor:DropCapPosition + //ExSummary:Shows how to create a drop cap. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert one paragraph with a large letter that the text in the second and third paragraphs begins with. + builder.getFont().setSize(54.0); + builder.writeln("L"); + + builder.getFont().setSize(18.0); + builder.writeln("orem ipsum dolor sit amet, consectetur adipiscing elit, " + + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "); + builder.writeln("Ut enim ad minim veniam, quis nostrud exercitation " + + "ullamco laboris nisi ut aliquip ex ea commodo consequat."); + + // Currently, the second and third paragraphs will appear underneath the first. + // We can convert the first paragraph as a drop cap for the other paragraphs via its "ParagraphFormat" object. + // Set the "DropCapPosition" property to "DropCapPosition.Margin" to place the drop cap + // outside the left-hand side page margin if our text is left-to-right. + // Set the "DropCapPosition" property to "DropCapPosition.Normal" to place the drop cap within the page margins + // and to wrap the rest of the text around it. + // "DropCapPosition.None" is the default state for all paragraphs. + ParagraphFormat format = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat(); + format.setDropCapPosition(dropCapPosition); + + doc.save(getArtifactsDir() + "ParagraphFormat.DropCap.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "ParagraphFormat.DropCap.docx"); + + Assert.assertEquals(dropCapPosition, doc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat().getDropCapPosition()); + Assert.assertEquals(DropCapPosition.NONE, doc.getFirstSection().getBody().getParagraphs().get(1).getParagraphFormat().getDropCapPosition()); + } + + @DataProvider(name = "dropCapDataProvider") + public static Object[][] dropCapDataProvider() { + return new Object[][] + { + {DropCapPosition.MARGIN}, + {DropCapPosition.NORMAL}, + {DropCapPosition.NONE}, + }; + } + + @Test + public void lineSpacing() throws Exception { + //ExStart + //ExFor:ParagraphFormat.LineSpacing + //ExFor:ParagraphFormat.LineSpacingRule + //ExFor:LineSpacingRule + //ExSummary:Shows how to work with line spacing. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are three line spacing rules that we can define using the + // paragraph's "LineSpacingRule" property to configure spacing between paragraphs. + // 1 - Set a minimum amount of spacing. + // This will give vertical padding to lines of text of any size + // that is too small to maintain the minimum line-height. + builder.getParagraphFormat().setLineSpacingRule(LineSpacingRule.AT_LEAST); + builder.getParagraphFormat().setLineSpacing(20.0); + + builder.writeln("Minimum line spacing of 20."); + builder.writeln("Minimum line spacing of 20."); + + // 2 - Set exact spacing. + // Using font sizes that are too large for the spacing will truncate the text. + builder.getParagraphFormat().setLineSpacingRule(LineSpacingRule.EXACTLY); + builder.getParagraphFormat().setLineSpacing(5.0); + + builder.writeln("Line spacing of exactly 5."); + builder.writeln("Line spacing of exactly 5."); + + // 3 - Set spacing as a multiple of default line spacing, which is 12 points by default. + // This kind of spacing will scale to different font sizes. + builder.getParagraphFormat().setLineSpacingRule(LineSpacingRule.MULTIPLE); + builder.getParagraphFormat().setLineSpacing(18.0); + + builder.writeln("Line spacing of 1.5 default lines."); + builder.writeln("Line spacing of 1.5 default lines."); + + doc.save(getArtifactsDir() + "ParagraphFormat.LineSpacing.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "ParagraphFormat.LineSpacing.docx"); + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + Assert.assertEquals(LineSpacingRule.AT_LEAST, paragraphs.get(0).getParagraphFormat().getLineSpacingRule()); + Assert.assertEquals(20.0d, paragraphs.get(0).getParagraphFormat().getLineSpacing()); + Assert.assertEquals(LineSpacingRule.AT_LEAST, paragraphs.get(1).getParagraphFormat().getLineSpacingRule()); + Assert.assertEquals(20.0d, paragraphs.get(1).getParagraphFormat().getLineSpacing()); + + Assert.assertEquals(LineSpacingRule.EXACTLY, paragraphs.get(2).getParagraphFormat().getLineSpacingRule()); + Assert.assertEquals(5.0d, paragraphs.get(2).getParagraphFormat().getLineSpacing()); + Assert.assertEquals(LineSpacingRule.EXACTLY, paragraphs.get(3).getParagraphFormat().getLineSpacingRule()); + Assert.assertEquals(5.0d, paragraphs.get(3).getParagraphFormat().getLineSpacing()); + + Assert.assertEquals(LineSpacingRule.MULTIPLE, paragraphs.get(4).getParagraphFormat().getLineSpacingRule()); + Assert.assertEquals(18.0d, paragraphs.get(4).getParagraphFormat().getLineSpacing()); + Assert.assertEquals(LineSpacingRule.MULTIPLE, paragraphs.get(5).getParagraphFormat().getLineSpacingRule()); + Assert.assertEquals(18.0d, paragraphs.get(5).getParagraphFormat().getLineSpacing()); + } + + @Test(dataProvider = "paragraphSpacingAutoDataProvider") + public void paragraphSpacingAuto(boolean autoSpacing) throws Exception { + //ExStart + //ExFor:ParagraphFormat.SpaceAfter + //ExFor:ParagraphFormat.SpaceAfterAuto + //ExFor:ParagraphFormat.SpaceBefore + //ExFor:ParagraphFormat.SpaceBeforeAuto + //ExSummary:Shows how to set automatic paragraph spacing. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Apply a large amount of spacing before and after paragraphs that this builder will create. + builder.getParagraphFormat().setSpaceBefore(24.0); + builder.getParagraphFormat().setSpaceAfter(24.0); + + // Set these flags to "true" to apply automatic spacing, + // effectively ignoring the spacing in the properties we set above. + // Leave them as "false" will apply our custom paragraph spacing. + builder.getParagraphFormat().setSpaceAfterAuto(autoSpacing); + builder.getParagraphFormat().setSpaceBeforeAuto(autoSpacing); + + // Insert two paragraphs that will have spacing above and below them and save the document. + builder.writeln("Paragraph 1."); + builder.writeln("Paragraph 2."); + + doc.save(getArtifactsDir() + "ParagraphFormat.ParagraphSpacingAuto.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "ParagraphFormat.ParagraphSpacingAuto.docx"); + ParagraphFormat format = doc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat(); + + Assert.assertEquals(24.0d, format.getSpaceBefore()); + Assert.assertEquals(24.0d, format.getSpaceAfter()); + Assert.assertEquals(autoSpacing, format.getSpaceAfterAuto()); + Assert.assertEquals(autoSpacing, format.getSpaceBeforeAuto()); + + format = doc.getFirstSection().getBody().getParagraphs().get(1).getParagraphFormat(); + + Assert.assertEquals(24.0d, format.getSpaceBefore()); + Assert.assertEquals(24.0d, format.getSpaceAfter()); + Assert.assertEquals(autoSpacing, format.getSpaceAfterAuto()); + Assert.assertEquals(autoSpacing, format.getSpaceBeforeAuto()); + } + + @DataProvider(name = "paragraphSpacingAutoDataProvider") + public static Object[][] paragraphSpacingAutoDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "paragraphSpacingSameStyleDataProvider") + public void paragraphSpacingSameStyle(boolean noSpaceBetweenParagraphsOfSameStyle) throws Exception { + //ExStart + //ExFor:ParagraphFormat.SpaceAfter + //ExFor:ParagraphFormat.SpaceBefore + //ExFor:ParagraphFormat.NoSpaceBetweenParagraphsOfSameStyle + //ExSummary:Shows how to apply no spacing between paragraphs with the same style. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Apply a large amount of spacing before and after paragraphs that this builder will create. + builder.getParagraphFormat().setSpaceBefore(24.0); + builder.getParagraphFormat().setSpaceAfter(24.0); + + // Set the "NoSpaceBetweenParagraphsOfSameStyle" flag to "true" to apply + // no spacing between paragraphs with the same style, which will group similar paragraphs. + // Leave the "NoSpaceBetweenParagraphsOfSameStyle" flag as "false" + // to evenly apply spacing to every paragraph. + builder.getParagraphFormat().setNoSpaceBetweenParagraphsOfSameStyle(noSpaceBetweenParagraphsOfSameStyle); + + builder.getParagraphFormat().setStyle(doc.getStyles().get("Normal")); + builder.writeln(MessageFormat.format("Paragraph in the \"{0}\" style.", builder.getParagraphFormat().getStyle().getName())); + builder.writeln(MessageFormat.format("Paragraph in the \"{0}\" style.", builder.getParagraphFormat().getStyle().getName())); + builder.writeln(MessageFormat.format("Paragraph in the \"{0}\" style.", builder.getParagraphFormat().getStyle().getName())); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Quote")); + builder.writeln(MessageFormat.format("Paragraph in the \"{0}\" style.", builder.getParagraphFormat().getStyle().getName())); + builder.writeln(MessageFormat.format("Paragraph in the \"{0}\" style.", builder.getParagraphFormat().getStyle().getName())); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Normal")); + builder.writeln(MessageFormat.format("Paragraph in the \"{0}\" style.", builder.getParagraphFormat().getStyle().getName())); + builder.writeln(MessageFormat.format("Paragraph in the \"{0}\" style.", builder.getParagraphFormat().getStyle().getName())); + + doc.save(getArtifactsDir() + "ParagraphFormat.ParagraphSpacingSameStyle.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "ParagraphFormat.ParagraphSpacingSameStyle.docx"); + + for (Paragraph paragraph : doc.getFirstSection().getBody().getParagraphs()) { + ParagraphFormat format = paragraph.getParagraphFormat(); + + Assert.assertEquals(24.0d, format.getSpaceBefore()); + Assert.assertEquals(24.0d, format.getSpaceAfter()); + Assert.assertEquals(noSpaceBetweenParagraphsOfSameStyle, format.getNoSpaceBetweenParagraphsOfSameStyle()); + } + } + + @DataProvider(name = "paragraphSpacingSameStyleDataProvider") + public static Object[][] paragraphSpacingSameStyleDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void paragraphOutlineLevel() throws Exception { + //ExStart + //ExFor:ParagraphFormat.OutlineLevel + //ExFor:OutlineLevel + //ExSummary:Shows how to configure paragraph outline levels to create collapsible text. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Each paragraph has an OutlineLevel, which could be any number from 1 to 9, or at the default "BodyText" value. + // Setting the property to one of the numbered values will show an arrow to the left + // of the beginning of the paragraph. + builder.getParagraphFormat().setOutlineLevel(OutlineLevel.LEVEL_1); + builder.writeln("Paragraph outline level 1."); + + // Level 1 is the topmost level. If there is a paragraph with a lower level below a paragraph with a higher level, + // collapsing the higher-level paragraph will collapse the lower level paragraph. + builder.getParagraphFormat().setOutlineLevel(OutlineLevel.LEVEL_2); + builder.writeln("Paragraph outline level 2."); + + // Two paragraphs of the same level will not collapse each other, + // and the arrows do not collapse the paragraphs they point to. + builder.getParagraphFormat().setOutlineLevel(OutlineLevel.LEVEL_3); + builder.writeln("Paragraph outline level 3."); + builder.writeln("Paragraph outline level 3."); + + // The default "BodyText" value is the lowest, which a paragraph of any level can collapse. + builder.getParagraphFormat().setOutlineLevel(OutlineLevel.BODY_TEXT); + builder.writeln("Paragraph at main text level."); + + doc.save(getArtifactsDir() + "ParagraphFormat.ParagraphOutlineLevel.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "ParagraphFormat.ParagraphOutlineLevel.docx"); + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + Assert.assertEquals(OutlineLevel.LEVEL_1, paragraphs.get(0).getParagraphFormat().getOutlineLevel()); + Assert.assertEquals(OutlineLevel.LEVEL_2, paragraphs.get(1).getParagraphFormat().getOutlineLevel()); + Assert.assertEquals(OutlineLevel.LEVEL_3, paragraphs.get(2).getParagraphFormat().getOutlineLevel()); + Assert.assertEquals(OutlineLevel.LEVEL_3, paragraphs.get(3).getParagraphFormat().getOutlineLevel()); + Assert.assertEquals(OutlineLevel.BODY_TEXT, paragraphs.get(4).getParagraphFormat().getOutlineLevel()); + + } + + @Test(dataProvider = "pageBreakBeforeDataProvider") + public void pageBreakBefore(boolean pageBreakBefore) throws Exception { + //ExStart + //ExFor:ParagraphFormat.PageBreakBefore + //ExSummary:Shows how to create paragraphs with page breaks at the beginning. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Set this flag to "true" to apply a page break to each paragraph's beginning + // that the document builder will create under this ParagraphFormat configuration. + // The first paragraph will not receive a page break. + // Leave this flag as "false" to start each new paragraph on the same page + // as the previous, provided there is sufficient space. + builder.getParagraphFormat().setPageBreakBefore(pageBreakBefore); + + builder.writeln("Paragraph 1."); + builder.writeln("Paragraph 2."); + + LayoutCollector layoutCollector = new LayoutCollector(doc); + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + if (pageBreakBefore) { + Assert.assertEquals(1, layoutCollector.getStartPageIndex(paragraphs.get(0))); + Assert.assertEquals(2, layoutCollector.getStartPageIndex(paragraphs.get(1))); + } else { + Assert.assertEquals(1, layoutCollector.getStartPageIndex(paragraphs.get(0))); + Assert.assertEquals(1, layoutCollector.getStartPageIndex(paragraphs.get(1))); + } + + doc.save(getArtifactsDir() + "ParagraphFormat.PageBreakBefore.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "ParagraphFormat.PageBreakBefore.docx"); + paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + Assert.assertEquals(pageBreakBefore, paragraphs.get(0).getParagraphFormat().getPageBreakBefore()); + Assert.assertEquals(pageBreakBefore, paragraphs.get(1).getParagraphFormat().getPageBreakBefore()); + } + + @DataProvider(name = "pageBreakBeforeDataProvider") + public static Object[][] pageBreakBeforeDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "widowControlDataProvider") + public void widowControl(boolean widowControl) throws Exception { + //ExStart + //ExFor:ParagraphFormat.WidowControl + //ExSummary:Shows how to enable widow/orphan control for a paragraph. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // When we write the text that does not fit onto one page, one line may spill over onto the next page. + // The single line that ends up on the next page is called an "Orphan", + // and the previous line where the orphan broke off is called a "Widow". + // We can fix orphans and widows by rearranging text via font size, spacing, or page margins. + // If we wish to preserve our document's dimensions, we can set this flag to "true" + // to push widows onto the same page as their respective orphans. + // Leave this flag as "false" will leave widow/orphan pairs in text. + // Every paragraph has this setting accessible in Microsoft Word via Home -> Paragraph -> Paragraph Settings + // (button on bottom right hand corner of "Paragraph" tab) -> "Widow/Orphan control". + builder.getParagraphFormat().setWidowControl(widowControl); + + // Insert text that produces an orphan and a widow. + builder.getFont().setSize(68.0); + builder.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + + doc.save(getArtifactsDir() + "ParagraphFormat.WidowControl.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "ParagraphFormat.WidowControl.docx"); + + Assert.assertEquals(widowControl, doc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat().getWidowControl()); + } + + @DataProvider(name = "widowControlDataProvider") + public static Object[][] widowControlDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void linesToDrop() throws Exception { + //ExStart + //ExFor:ParagraphFormat.LinesToDrop + //ExSummary:Shows how to set the size of a drop cap. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Modify the "LinesToDrop" property to designate a paragraph as a drop cap, + // which will turn it into a large capital letter that will decorate the next paragraph. + // Give this property a value of 4 to give the drop cap the height of four text lines. + builder.getParagraphFormat().setLinesToDrop(4); + builder.writeln("H"); + + // Reset the "LinesToDrop" property to 0 to turn the next paragraph into an ordinary paragraph. + // The text in this paragraph will wrap around the drop cap. + builder.getParagraphFormat().setLinesToDrop(0); + builder.writeln("ello world!"); + + doc.save(getArtifactsDir() + "ParagraphFormat.LinesToDrop.odt"); + //ExEnd + + doc = new Document(getArtifactsDir() + "ParagraphFormat.LinesToDrop.odt"); + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + Assert.assertEquals(4, paragraphs.get(0).getParagraphFormat().getLinesToDrop()); + Assert.assertEquals(0, paragraphs.get(1).getParagraphFormat().getLinesToDrop()); + } + + @Test(dataProvider = "suppressHyphensDataProvider") + public void suppressHyphens(boolean suppressAutoHyphens) throws Exception { + //ExStart + //ExFor:ParagraphFormat.SuppressAutoHyphens + //ExSummary:Shows how to suppress hyphenation for a paragraph. + Hyphenation.registerDictionary("de-CH", getMyDir() + "hyph_de_CH.dic"); + + Assert.assertTrue(Hyphenation.isDictionaryRegistered("de-CH")); + + // Open a document containing text with a locale matching that of our dictionary. + // When we save this document to a fixed page save format, its text will have hyphenation. + Document doc = new Document(getMyDir() + "German text.docx"); + + // We can set the "SuppressAutoHyphens" property to "true" to disable hyphenation + // for a specific paragraph while keeping it enabled for the rest of the document. + // The default value for this property is "false", + // which means every paragraph by default uses hyphenation if any is available. + doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat().setSuppressAutoHyphens(suppressAutoHyphens); + + doc.save(getArtifactsDir() + "ParagraphFormat.SuppressHyphens.pdf"); + //ExEnd + + com.aspose.pdf.Document pdfDoc = new com.aspose.pdf.Document(getArtifactsDir() + "ParagraphFormat.SuppressHyphens.pdf"); + TextAbsorber textAbsorber = new TextAbsorber(); + textAbsorber.visit(pdfDoc); + + if (suppressAutoHyphens) + Assert.assertTrue(textAbsorber.getText().contains("La ob storen an deinen am sachen. \r\n" + + "Doppelte um da am spateren verlogen \r\n" + + "gekommen achtzehn blaulich.")); + else + Assert.assertTrue(textAbsorber.getText().contains("La ob storen an deinen am sachen. Dop\u00ad\r\n" + + "pelte um da am spateren verlogen ge\u00ad\r\n" + + "kommen achtzehn blaulich.")); + + pdfDoc.close(); + } + + @DataProvider(name = "suppressHyphensDataProvider") + public static Object[][] suppressHyphensDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void paragraphSpacingAndIndents() throws Exception { + //ExStart + //ExFor:ParagraphFormat.CharacterUnitLeftIndent + //ExFor:ParagraphFormat.CharacterUnitRightIndent + //ExFor:ParagraphFormat.CharacterUnitFirstLineIndent + //ExFor:ParagraphFormat.LineUnitBefore + //ExFor:ParagraphFormat.LineUnitAfter + //ExSummary:Shows how to change paragraph spacing and indents. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + ParagraphFormat format = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat(); + + // Below are five different spacing options, along with the properties that their configuration indirectly affects. + // 1 - Left indent: + Assert.assertEquals(format.getLeftIndent(), 0.0d); + + format.setCharacterUnitLeftIndent(10.0); + + Assert.assertEquals(format.getLeftIndent(), 120.0d); + + // 2 - Right indent: + Assert.assertEquals(format.getRightIndent(), 0.0d); + + format.setCharacterUnitRightIndent(-5.5); + + Assert.assertEquals(format.getRightIndent(), -66.0d); + + // 3 - Hanging indent: + Assert.assertEquals(format.getFirstLineIndent(), 0.0d); + + format.setCharacterUnitFirstLineIndent(20.3); + + Assert.assertEquals(format.getFirstLineIndent(), 243.59d, 0.1d); + + // 4 - Line spacing before paragraphs: + Assert.assertEquals(format.getSpaceBefore(), 0.0d); + + format.setLineUnitBefore(5.1); + + Assert.assertEquals(format.getSpaceBefore(), 61.1d, 0.1d); + + // 5 - Line spacing after paragraphs: + Assert.assertEquals(format.getSpaceAfter(), 0.0d); + + format.setLineUnitAfter(10.9); + + Assert.assertEquals(format.getSpaceAfter(), 130.8d, 0.1d); + + builder.writeln("Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + builder.write("测试文档测试文档测试文档测试文档测试文档测试文档测试文档测试文档测试" + + "文档测试文档测试文档测试文档测试文档测试文档测试文档测试文档测试文档测试文档"); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + format = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat(); + + Assert.assertEquals(format.getCharacterUnitLeftIndent(), 10.0d); + Assert.assertEquals(format.getLeftIndent(), 120.0d); + + Assert.assertEquals(format.getCharacterUnitRightIndent(), -5.5d); + Assert.assertEquals(format.getRightIndent(), -66.0d); + + Assert.assertEquals(format.getCharacterUnitFirstLineIndent(), 20.3d); + Assert.assertEquals(format.getFirstLineIndent(), 243.59d, 0.1d); + + Assert.assertEquals(format.getLineUnitBefore(), 5.1d, 0.1d); + Assert.assertEquals(format.getSpaceBefore(), 61.1d, 0.1d); + + Assert.assertEquals(format.getLineUnitAfter(), 10.9d); + Assert.assertEquals(format.getSpaceAfter(), 130.8d, 0.1d); + } + + @Test + public void paragraphBaselineAlignment() throws Exception + { + //ExStart + //ExFor:BaselineAlignment + //ExFor:ParagraphFormat.BaselineAlignment + //ExSummary:Shows how to set fonts vertical position on a line. + Document doc = new Document(getMyDir() + "Office math.docx"); + + ParagraphFormat format = doc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat(); + if (format.getBaselineAlignment() == BaselineAlignment.AUTO) + { + format.setBaselineAlignment(BaselineAlignment.TOP); + } + + doc.save(getArtifactsDir() + "ParagraphFormat.ParagraphBaselineAlignment.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "ParagraphFormat.ParagraphBaselineAlignment.docx"); + format = doc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat(); + Assert.assertEquals(BaselineAlignment.TOP, format.getBaselineAlignment()); + } + + @Test + public void mirrorIndents() throws Exception + { + //ExStart:MirrorIndents + //GistId:31b7350f8d91d4b12eb43978940d566a + //ExFor:ParagraphFormat.MirrorIndents + //ExSummary:Show how to make left and right indents the same. + Document doc = new Document(getMyDir() + "Document.docx"); + ParagraphFormat format = doc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat(); + + format.setMirrorIndents(true); + + doc.save(getArtifactsDir() + "ParagraphFormat.MirrorIndents.docx"); + //ExEnd:MirrorIndents + + doc = new Document(getArtifactsDir() + "ParagraphFormat.MirrorIndents.docx"); + format = doc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat(); + + Assert.assertEquals(true, format.getMirrorIndents()); + } +} + diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExPclSaveOptions.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExPclSaveOptions.java new file mode 100644 index 00000000..02355bad --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExPclSaveOptions.java @@ -0,0 +1,85 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.annotations.Test; + +public class ExPclSaveOptions extends ApiExampleBase { + @Test + public void rasterizeElements() throws Exception { + //ExStart + //ExFor:PclSaveOptions + //ExFor:PclSaveOptions.SaveFormat + //ExFor:PclSaveOptions.RasterizeTransformedElements + //ExSummary:Shows how to rasterize complex elements while saving a document to PCL. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PclSaveOptions saveOptions = new PclSaveOptions(); + saveOptions.setSaveFormat(SaveFormat.PCL); + saveOptions.setRasterizeTransformedElements(true); + + doc.save(getArtifactsDir() + "PclSaveOptions.RasterizeElements.pcl", saveOptions); + //ExEnd + } + + @Test + public void fallbackFontName() throws Exception { + //ExStart + //ExFor:PclSaveOptions.FallbackFontName + //ExSummary:Shows how to declare a font that a printer will apply to printed text as a substitute should its original font be unavailable. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Non-existent font"); + builder.write("Hello world!"); + + PclSaveOptions saveOptions = new PclSaveOptions(); + saveOptions.setFallbackFontName("Times New Roman"); + + // This document will instruct the printer to apply "Times New Roman" to the text with the missing font. + // Should "Times New Roman" also be unavailable, the printer will default to the "Arial" font. + doc.save(getArtifactsDir() + "PclSaveOptions.SetPrinterFont.pcl", saveOptions); + //ExEnd + } + + @Test + public void addPrinterFont() throws Exception { + //ExStart + //ExFor:PclSaveOptions.AddPrinterFont(string, string) + //ExSummary:Shows how to get a printer to substitute all instances of a specific font with a different font. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Courier"); + builder.write("Hello world!"); + + PclSaveOptions saveOptions = new PclSaveOptions(); + saveOptions.addPrinterFont("Courier New", "Courier"); + + // When printing this document, the printer will use the "Courier New" font + // to access places where our document used the "Courier" font. + doc.save(getArtifactsDir() + "PclSaveOptions.AddPrinterFont.pcl", saveOptions); + //ExEnd + } + + @Test(description = "This test is a manual check that PaperTray information is preserved in the output pcl document.") + public void getPreservedPaperTrayInformation() throws Exception { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // Paper tray information is now preserved when saving document to PCL format. + // Following information is transferred from document's model to PCL file. + for (Section section : doc.getSections()) { + section.getPageSetup().setFirstPageTray(15); + section.getPageSetup().setOtherPagesTray(12); + } + + doc.save(getArtifactsDir() + "PclSaveOptions.GetPreservedPaperTrayInformation.pcl"); + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExPdfLoadOptions.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExPdfLoadOptions.java new file mode 100644 index 00000000..9eb1bb3b --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExPdfLoadOptions.java @@ -0,0 +1,50 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +@Test +class ExPdfLoadOptions extends ApiExampleBase { + @Test (dataProvider = "skipPdfImagesDataProvider") + public void skipPdfImages(boolean isSkipPdfImages) throws Exception { + //ExStart + //ExFor:PdfLoadOptions + //ExFor:PdfLoadOptions.SkipPdfImages + //ExFor:PdfLoadOptions.PageIndex + //ExFor:PdfLoadOptions.PageCount + //ExSummary:Shows how to skip images during loading PDF files. + PdfLoadOptions options = new PdfLoadOptions(); + options.setSkipPdfImages(isSkipPdfImages); + options.setPageIndex(0); + options.setPageCount(1); + + Document doc = new Document(getMyDir() + "Images.pdf", options); + NodeCollection shapeCollection = doc.getChildNodes(NodeType.SHAPE, true); + + if (isSkipPdfImages) + Assert.assertEquals(shapeCollection.getCount(), 0); + else + Assert.assertNotEquals(shapeCollection.getCount(), 0); + //ExEnd + } + + @DataProvider(name = "skipPdfImagesDataProvider") + public static Object[][] skipPdfImagesDataProvider() { + return new Object[][] + { + {true}, + {false}, + }; + } +} + diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExPdfSaveOptions.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExPdfSaveOptions.java new file mode 100644 index 00000000..9f3f60d4 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExPdfSaveOptions.java @@ -0,0 +1,2557 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.pdf.Font; +import com.aspose.pdf.*; +import com.aspose.pdf.exceptions.InvalidPasswordException; +import com.aspose.pdf.facades.Bookmarks; +import com.aspose.pdf.facades.PdfBookmarkEditor; +import com.aspose.pdf.operators.SetGlyphsPositionShowText; +import com.aspose.words.Document; +import com.aspose.words.FolderFontSource; +import com.aspose.words.PdfSaveOptions; +import com.aspose.words.SaveFormat; +import com.aspose.words.SaveOptions; +import com.aspose.words.WarningInfo; +import com.aspose.words.WarningType; +import com.aspose.words.*; +import org.apache.commons.collections4.IterableUtils; +import org.apache.poi.util.LocaleUtil; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +public class ExPdfSaveOptions extends ApiExampleBase { + @Test + public void onePage() throws Exception { + //ExStart + //ExFor:FixedPageSaveOptions.PageSet + //ExFor:Document.Save(Stream, SaveOptions) + //ExSummary:Shows how to convert only some of the pages in a document to PDF. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Page 1."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 2."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 3."); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "PageIndex" to "1" to render a portion of the document starting from the second page. + options.setPageSet(new PageSet(1)); + + // This document will contain one page starting from page two, which will only contain the second page. + doc.save(new FileOutputStream(getArtifactsDir() + "PdfSaveOptions.OnePage.pdf"), options); + //ExEnd + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.OnePage.pdf"); + + Assert.assertEquals(1, pdfDocument.getPages().size()); + + TextFragmentAbsorber textFragmentAbsorber = new TextFragmentAbsorber(); + pdfDocument.getPages().accept(textFragmentAbsorber); + + Assert.assertEquals("Page 2.", textFragmentAbsorber.getText()); + + pdfDocument.close(); + } + + @Test + public void headingsOutlineLevels() throws Exception { + //ExStart + //ExFor:ParagraphFormat.IsHeading + //ExFor:PdfSaveOptions.OutlineOptions + //ExFor:PdfSaveOptions.SaveFormat + //ExSummary:Shows how to limit the headings' level that will appear in the outline of a saved PDF document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert headings that can serve as TOC entries of levels 1, 2, and then 3. + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + + Assert.assertTrue(builder.getParagraphFormat().isHeading()); + + builder.writeln("Heading 1"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); + + builder.writeln("Heading 1.1"); + builder.writeln("Heading 1.2"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_3); + + builder.writeln("Heading 1.2.1"); + builder.writeln("Heading 1.2.2"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setSaveFormat(SaveFormat.PDF); + + // The output PDF document will contain an outline, which is a table of contents that lists headings in the document body. + // Clicking on an entry in this outline will take us to the location of its respective heading. + // Set the "HeadingsOutlineLevels" property to "2" to exclude all headings whose levels are above 2 from the outline. + // The last two headings we have inserted above will not appear. + saveOptions.getOutlineOptions().setHeadingsOutlineLevels(2); + + doc.save(getArtifactsDir() + "PdfSaveOptions.HeadingsOutlineLevels.pdf", saveOptions); + //ExEnd + + PdfBookmarkEditor bookmarkEditor = new PdfBookmarkEditor(); + bookmarkEditor.bindPdf(getArtifactsDir() + "PdfSaveOptions.HeadingsOutlineLevels.pdf"); + + Bookmarks bookmarks = bookmarkEditor.extractBookmarks(); + + Assert.assertEquals(3, bookmarks.size()); + + bookmarkEditor.close(); + } + + @Test(dataProvider = "createMissingOutlineLevelsDataProvider") + public void createMissingOutlineLevels(boolean createMissingOutlineLevels) throws Exception { + //ExStart + //ExFor:OutlineOptions.CreateMissingOutlineLevels + //ExFor:PdfSaveOptions.OutlineOptions + //ExSummary:Shows how to work with outline levels that do not contain any corresponding headings when saving a PDF document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert headings that can serve as TOC entries of levels 1 and 5. + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + + Assert.assertTrue(builder.getParagraphFormat().isHeading()); + + builder.writeln("Heading 1"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_5); + + builder.writeln("Heading 1.1.1.1.1"); + builder.writeln("Heading 1.1.1.1.2"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + + // The output PDF document will contain an outline, which is a table of contents that lists headings in the document body. + // Clicking on an entry in this outline will take us to the location of its respective heading. + // Set the "HeadingsOutlineLevels" property to "5" to include all headings of levels 5 and below in the outline. + saveOptions.getOutlineOptions().setHeadingsOutlineLevels(5); + + // This document contains headings of levels 1 and 5, and no headings with levels of 2, 3, and 4. + // The output PDF document will treat outline levels 2, 3, and 4 as "missing". + // Set the "CreateMissingOutlineLevels" property to "true" to include all missing levels in the outline, + // leaving blank outline entries since there are no usable headings. + // Set the "CreateMissingOutlineLevels" property to "false" to ignore missing outline levels, + // and treat the outline level 5 headings as level 2. + saveOptions.getOutlineOptions().setCreateMissingOutlineLevels(createMissingOutlineLevels); + + doc.save(getArtifactsDir() + "PdfSaveOptions.CreateMissingOutlineLevels.pdf", saveOptions); + //ExEnd + + PdfBookmarkEditor bookmarkEditor = new PdfBookmarkEditor(); + bookmarkEditor.bindPdf(getArtifactsDir() + "PdfSaveOptions.CreateMissingOutlineLevels.pdf"); + + Bookmarks bookmarks = bookmarkEditor.extractBookmarks(); + + Assert.assertEquals(createMissingOutlineLevels ? 6 : 3, bookmarks.size()); + + bookmarkEditor.close(); + } + + @DataProvider(name = "createMissingOutlineLevelsDataProvider") + public static Object[][] createMissingOutlineLevelsDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "tableHeadingOutlinesDataProvider") + public void tableHeadingOutlines(boolean createOutlinesForHeadingsInTables) throws Exception { + //ExStart + //ExFor:OutlineOptions.CreateOutlinesForHeadingsInTables + //ExSummary:Shows how to create PDF document outline entries for headings inside tables. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a table with three rows. The first row, + // whose text we will format in a heading-type style, will serve as the column header. + builder.startTable(); + builder.insertCell(); + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + builder.write("Customers"); + builder.endRow(); + builder.insertCell(); + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.NORMAL); + builder.write("John Doe"); + builder.endRow(); + builder.insertCell(); + builder.write("Jane Doe"); + builder.endTable(); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions pdfSaveOptions = new PdfSaveOptions(); + + // The output PDF document will contain an outline, which is a table of contents that lists headings in the document body. + // Clicking on an entry in this outline will take us to the location of its respective heading. + // Set the "HeadingsOutlineLevels" property to "1" to get the outline + // to only register headings with heading levels that are no larger than 1. + pdfSaveOptions.getOutlineOptions().setHeadingsOutlineLevels(1); + + // Set the "CreateOutlinesForHeadingsInTables" property to "false" to exclude all headings within tables, + // such as the one we have created above from the outline. + // Set the "CreateOutlinesForHeadingsInTables" property to "true" to include all headings within tables + // in the outline, provided that they have a heading level that is no larger than the value of the "HeadingsOutlineLevels" property. + pdfSaveOptions.getOutlineOptions().setCreateOutlinesForHeadingsInTables(createOutlinesForHeadingsInTables); + + doc.save(getArtifactsDir() + "PdfSaveOptions.TableHeadingOutlines.pdf", pdfSaveOptions); + //ExEnd + + com.aspose.pdf.Document pdfDoc = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.TableHeadingOutlines.pdf"); + + if (createOutlinesForHeadingsInTables) { + Assert.assertEquals(1, pdfDoc.getOutlines().size()); + Assert.assertEquals("Customers", pdfDoc.getOutlines().get_Item(1).getTitle()); + } else + Assert.assertEquals(0, pdfDoc.getOutlines().size()); + + TableAbsorber tableAbsorber = new TableAbsorber(); + tableAbsorber.visit(pdfDoc.getPages().get_Item(1)); + + Assert.assertEquals("Customers", tableAbsorber.getTableList().get(0).getRowList().get(0).getCellList().get(0).getTextFragments().get_Item(1).getText()); + Assert.assertEquals("John Doe", tableAbsorber.getTableList().get(0).getRowList().get(1).getCellList().get(0).getTextFragments().get_Item(1).getText()); + Assert.assertEquals("Jane Doe", tableAbsorber.getTableList().get(0).getRowList().get(2).getCellList().get(0).getTextFragments().get_Item(1).getText()); + + pdfDoc.close(); + } + + @DataProvider(name = "tableHeadingOutlinesDataProvider") + public static Object[][] tableHeadingOutlinesDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void expandedOutlineLevels() throws Exception { + //ExStart + //ExFor:Document.Save(String, SaveOptions) + //ExFor:PdfSaveOptions + //ExFor:OutlineOptions.HeadingsOutlineLevels + //ExFor:OutlineOptions.ExpandedOutlineLevels + //ExSummary:Shows how to convert a whole document to PDF with three levels in the document outline. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert headings of levels 1 to 5. + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + + Assert.assertTrue(builder.getParagraphFormat().isHeading()); + + builder.writeln("Heading 1"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); + + builder.writeln("Heading 1.1"); + builder.writeln("Heading 1.2"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_3); + + builder.writeln("Heading 1.2.1"); + builder.writeln("Heading 1.2.2"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_4); + + builder.writeln("Heading 1.2.2.1"); + builder.writeln("Heading 1.2.2.2"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_5); + + builder.writeln("Heading 1.2.2.2.1"); + builder.writeln("Heading 1.2.2.2.2"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // The output PDF document will contain an outline, which is a table of contents that lists headings in the document body. + // Clicking on an entry in this outline will take us to the location of its respective heading. + // Set the "HeadingsOutlineLevels" property to "4" to exclude all headings whose levels are above 4 from the outline. + options.getOutlineOptions().setHeadingsOutlineLevels(4); + + // If an outline entry has subsequent entries of a higher level inbetween itself and the next entry of the same or lower level, + // an arrow will appear to the left of the entry. This entry is the "owner" of several such "sub-entries". + // In our document, the outline entries from the 5th heading level are sub-entries of the second 4th level outline entry, + // the 4th and 5th heading level entries are sub-entries of the second 3rd level entry, and so on. + // In the outline, we can click on the arrow of the "owner" entry to collapse/expand all its sub-entries. + // Set the "ExpandedOutlineLevels" property to "2" to automatically expand all heading level 2 and lower outline entries + // and collapse all level and 3 and higher entries when we open the document. + options.getOutlineOptions().setExpandedOutlineLevels(2); + + doc.save(getArtifactsDir() + "PdfSaveOptions.ExpandedOutlineLevels.pdf", options); + //ExEnd + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.ExpandedOutlineLevels.pdf"); + + Assert.assertEquals(1, pdfDocument.getOutlines().size()); + Assert.assertEquals(5, pdfDocument.getOutlines().getVisibleCount()); + + Assert.assertTrue(pdfDocument.getOutlines().get_Item(1).getOpen()); + Assert.assertEquals(1, pdfDocument.getOutlines().get_Item(1).getLevel()); + + Assert.assertFalse(pdfDocument.getOutlines().get_Item(1).get_Item(1).getOpen()); + Assert.assertEquals(2, pdfDocument.getOutlines().get_Item(1).get_Item(1).getLevel()); + + Assert.assertTrue(pdfDocument.getOutlines().get_Item(1).get_Item(2).getOpen()); + Assert.assertEquals(2, pdfDocument.getOutlines().get_Item(1).get_Item(2).getLevel()); + + pdfDocument.close(); + } + + @Test(dataProvider = "updateFieldsDataProvider") + public void updateFields(boolean updateFields) throws Exception { + //ExStart + //ExFor:PdfSaveOptions.Clone + //ExFor:SaveOptions.UpdateFields + //ExSummary:Shows how to update all the fields in a document immediately before saving it to PDF. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert text with PAGE and NUMPAGES fields. These fields do not display the correct value in real time. + // We will need to manually update them using updating methods such as "Field.Update()", and "Document.UpdateFields()" + // each time we need them to display accurate values. + builder.write("Page "); + builder.insertField("PAGE", ""); + builder.write(" of "); + builder.insertField("NUMPAGES", ""); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Hello World!"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "UpdateFields" property to "false" to not update all the fields in a document right before a save operation. + // This is the preferable option if we know that all our fields will be up to date before saving. + // Set the "UpdateFields" property to "true" to iterate through all the document + // fields and update them before we save it as a PDF. This will make sure that all the fields will display + // the most accurate values in the PDF. + options.setUpdateFields(updateFields); + + // We can clone PdfSaveOptions objects. + Assert.assertNotSame(options, options.deepClone()); + + doc.save(getArtifactsDir() + "PdfSaveOptions.UpdateFields.pdf", options); + //ExEnd + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.UpdateFields.pdf"); + + TextFragmentAbsorber textFragmentAbsorber = new TextFragmentAbsorber(); + pdfDocument.getPages().accept(textFragmentAbsorber); + + Assert.assertEquals(updateFields ? "Page 1 of 2" : "Page of ", textFragmentAbsorber.getTextFragments().get_Item(1).getText()); + + pdfDocument.close(); + } + + @DataProvider(name = "updateFieldsDataProvider") + public static Object[][] updateFieldsDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "preserveFormFieldsDataProvider") + public void preserveFormFields(boolean preserveFormFields) throws Exception { + //ExStart + //ExFor:PdfSaveOptions.PreserveFormFields + //ExSummary:Shows how to save a document to the PDF format using the Save method and the PdfSaveOptions class. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Please select a fruit: "); + + // Insert a combo box which will allow a user to choose an option from a collection of strings. + builder.insertComboBox("MyComboBox", new String[]{"Apple", "Banana", "Cherry"}, 0); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions pdfOptions = new PdfSaveOptions(); + + // Set the "PreserveFormFields" property to "true" to save form fields as interactive objects in the output PDF. + // Set the "PreserveFormFields" property to "false" to freeze all form fields in the document at + // their current values and display them as plain text in the output PDF. + pdfOptions.setPreserveFormFields(preserveFormFields); + + doc.save(getArtifactsDir() + "PdfSaveOptions.PreserveFormFields.pdf", pdfOptions); + //ExEnd + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.PreserveFormFields.pdf"); + + Assert.assertEquals(1, pdfDocument.getPages().size()); + + TextFragmentAbsorber textFragmentAbsorber = new TextFragmentAbsorber(); + pdfDocument.getPages().accept(textFragmentAbsorber); + + if (preserveFormFields) { + Assert.assertEquals("Please select a fruit: ", textFragmentAbsorber.getText()); + + com.aspose.pdf.Form form = pdfDocument.getForm(); + Assert.assertEquals(1, form.size()); + + ComboBoxField field = (ComboBoxField) form.getFields()[0]; + + Assert.assertEquals("MyComboBox", field.getFullName()); + Assert.assertEquals(3, field.getOptions().size()); + Assert.assertEquals("Apple", field.getValue()); + } else { + Assert.assertEquals("Please select a fruit: Apple", textFragmentAbsorber.getText()); + Assert.assertThrows(AssertionError.class, () -> TestUtil.fileContainsString("/Widget", + getArtifactsDir() + "PdfSaveOptions.PreserveFormFields.pdf")); + + Assert.assertEquals(0, pdfDocument.getForm().size()); + } + + pdfDocument.close(); + } + + @DataProvider(name = "preserveFormFieldsDataProvider") + public static Object[][] preserveFormFieldsDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "complianceDataProvider") + public void compliance(int pdfCompliance) throws Exception { + //ExStart + //ExFor:PdfSaveOptions.Compliance + //ExFor:PdfCompliance + //ExSummary:Shows how to set the PDF standards compliance level of saved PDF documents. + Document doc = new Document(getMyDir() + "Images.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + // Note that some PdfSaveOptions are prohibited when saving to one of the standards and automatically fixed. + // Use IWarningCallback to know which options are automatically fixed. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + + // Set the "Compliance" property to "PdfCompliance.PdfA1b" to comply with the "PDF/A-1b" standard, + // which aims to preserve the visual appearance of the document as Aspose.Words convert it to PDF. + // Set the "Compliance" property to "PdfCompliance.Pdf17" to comply with the "1.7" standard. + // Set the "Compliance" property to "PdfCompliance.PdfA1a" to comply with the "PDF/A-1a" standard, + // which complies with "PDF/A-1b" as well as preserving the document structure of the original document. + // Set the "Compliance" property to "PdfCompliance.PdfUa1" to comply with the "PDF/UA-1" (ISO 14289-1) standard, + // which aims to define represent electronic documents in PDF that allow the file to be accessible. + // Set the "Compliance" property to "PdfCompliance.Pdf20" to comply with the "PDF 2.0" (ISO 32000-2) standard. + // Set the "Compliance" property to "PdfCompliance.PdfA4" to comply with the "PDF/A-4" (ISO 19004:2020) standard, + // which preserving document static visual appearance over time. + // Set the "Compliance" property to "PdfCompliance.PdfA4Ua2" to comply with both PDF/A-4 (ISO 19005-4:2020) + // and PDF/UA-2 (ISO 14289-2:2024) standards. + // Set the "Compliance" property to "PdfCompliance.PdfUa2" to comply with the PDF/UA-2 (ISO 14289-2:2024) standard. + // This helps with making documents searchable but may significantly increase the size of already large documents. + saveOptions.setCompliance(pdfCompliance); + + doc.save(getArtifactsDir() + "PdfSaveOptions.Compliance.pdf", saveOptions); + //ExEnd + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.Compliance.pdf"); + + switch (pdfCompliance) { + case PdfCompliance.PDF_17: + Assert.assertEquals(PdfFormat.v_1_7, pdfDocument.getPdfFormat()); + Assert.assertEquals("1.7", pdfDocument.getVersion()); + break; + case PdfCompliance.PDF_A_2_A: + Assert.assertEquals(PdfFormat.PDF_A_2A, pdfDocument.getPdfFormat()); + Assert.assertEquals("1.7", pdfDocument.getVersion()); + break; + case PdfCompliance.PDF_A_2_U: + Assert.assertEquals(PdfFormat.PDF_A_2U, pdfDocument.getPdfFormat()); + Assert.assertEquals("1.7", pdfDocument.getVersion()); + break; + case PdfCompliance.PDF_A_3_A: + Assert.assertEquals(PdfFormat.PDF_A_3A, pdfDocument.getPdfFormat()); + Assert.assertEquals("1.7", pdfDocument.getVersion()); + break; + case PdfCompliance.PDF_A_3_U: + Assert.assertEquals(PdfFormat.PDF_A_3U, pdfDocument.getPdfFormat()); + Assert.assertEquals("1.7", pdfDocument.getVersion()); + break; + case PdfCompliance.PDF_UA_1: + Assert.assertEquals(PdfFormat.PDF_UA_1, pdfDocument.getPdfFormat()); + Assert.assertEquals("1.7", pdfDocument.getVersion()); + break; + case PdfCompliance.PDF_20: + Assert.assertEquals(PdfFormat.v_2_0, pdfDocument.getPdfFormat()); + Assert.assertEquals("2.0", pdfDocument.getVersion()); + break; + case PdfCompliance.PDF_A_4: + Assert.assertEquals(PdfFormat.PDF_A_4, pdfDocument.getPdfFormat()); + Assert.assertEquals("2.0", pdfDocument.getVersion()); + break; + case PdfCompliance.PDF_A_4_F: + Assert.assertEquals(PdfFormat.PDF_A_4F, pdfDocument.getPdfFormat()); + Assert.assertEquals("2.0", pdfDocument.getVersion()); + break; + case PdfCompliance.PDF_A_4_UA_2: + Assert.assertEquals(PdfFormat.PDF_UA_1, pdfDocument.getPdfFormat()); + Assert.assertEquals("2.0", pdfDocument.getVersion()); + break; + case PdfCompliance.PDF_UA_2: + Assert.assertEquals(PdfFormat.PDF_UA_1, pdfDocument.getPdfFormat()); + Assert.assertEquals("2.0", pdfDocument.getVersion()); + break; + } + + pdfDocument.close(); + } + + @DataProvider(name = "complianceDataProvider") + public static Object[][] complianceDataProvider() { + return new Object[][] + { + {PdfCompliance.PDF_A_2_U}, + {PdfCompliance.PDF_A_3_A}, + {PdfCompliance.PDF_A_3_U}, + {PdfCompliance.PDF_17}, + {PdfCompliance.PDF_A_2_A}, + {PdfCompliance.PDF_UA_1}, + {PdfCompliance.PDF_20}, + {PdfCompliance.PDF_A_4}, + {PdfCompliance.PDF_A_4_F}, + {PdfCompliance.PDF_A_4_UA_2}, + {PdfCompliance.PDF_UA_2}, + }; + } + + @Test(dataProvider = "textCompressionDataProvider") + public void textCompression(int pdfTextCompression) throws Exception { + //ExStart + //ExFor:PdfSaveOptions + //ExFor:PdfSaveOptions.TextCompression + //ExFor:PdfTextCompression + //ExSummary:Shows how to apply text compression when saving a document to PDF. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + for (int i = 0; i < 100; i++) + builder.writeln("Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "TextCompression" property to "PdfTextCompression.None" to not apply any + // compression to text when we save the document to PDF. + // Set the "TextCompression" property to "PdfTextCompression.Flate" to apply ZIP compression + // to text when we save the document to PDF. The larger the document, the bigger the impact that this will have. + options.setTextCompression(pdfTextCompression); + + doc.save(getArtifactsDir() + "PdfSaveOptions.TextCompression.pdf", options); + //ExEnd + + long testedFileLenght = new File(getArtifactsDir() + "PdfSaveOptions.TextCompression.pdf").length(); + switch (pdfTextCompression) { + case PdfTextCompression.NONE: + Assert.assertTrue( testedFileLenght < 68000); + TestUtil.fileContainsString("<>stream", + getArtifactsDir() + "PdfSaveOptions.TextCompression.pdf"); + break; + case PdfTextCompression.FLATE: + Assert.assertTrue(testedFileLenght < 30000); + TestUtil.fileContainsString("<>stream", + getArtifactsDir() + "PdfSaveOptions.TextCompression.pdf"); + break; + } + } + + @DataProvider(name = "textCompressionDataProvider") + public static Object[][] textCompressionDataProvider() { + return new Object[][] + { + {PdfTextCompression.NONE}, + {PdfTextCompression.FLATE}, + }; + } + + @Test(enabled = false, dataProvider = "imageCompressionDataProvider") + public void imageCompression(int pdfImageCompression) throws Exception { + //ExStart + //ExFor:PdfSaveOptions.ImageCompression + //ExFor:PdfSaveOptions.JpegQuality + //ExFor:PdfImageCompression + //ExSummary:Shows how to specify a compression type for all images in a document that we are converting to PDF. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Jpeg image:"); + builder.insertImage(getImageDir() + "Logo.jpg"); + builder.insertParagraph(); + builder.writeln("Png image:"); + builder.insertImage(getImageDir() + "Transparent background logo.png"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions pdfSaveOptions = new PdfSaveOptions(); + + // Set the "ImageCompression" property to "PdfImageCompression.Auto" to use the + // "ImageCompression" property to control the quality of the Jpeg images that end up in the output PDF. + // Set the "ImageCompression" property to "PdfImageCompression.Jpeg" to use the + // "ImageCompression" property to control the quality of all images that end up in the output PDF. + pdfSaveOptions.setImageCompression(pdfImageCompression); + + // Set the "JpegQuality" property to "10" to strengthen compression at the cost of image quality. + pdfSaveOptions.setJpegQuality(10); + + doc.save(getArtifactsDir() + "PdfSaveOptions.ImageCompression.pdf", pdfSaveOptions); + //ExEnd + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.ImageCompression.pdf"); + + try (InputStream firstImage = pdfDocument.getPages().get_Item(1).getResources().getImages().get_Item(1).toStream()) { + TestUtil.verifyImage(400, 400, firstImage); + } + + switch (pdfImageCompression) { + case PdfImageCompression.AUTO: + Assert.assertTrue(new File(getArtifactsDir() + "PdfSaveOptions.ImageCompression.pdf").length() < 51500); + break; + case PdfImageCompression.JPEG: + Assert.assertTrue(new File(getArtifactsDir() + "PdfSaveOptions.ImageCompression.pdf").length() <= 42000); + try (InputStream secondImage = pdfDocument.getPages().get_Item(1).getResources().getImages().get_Item(2).toStream()) { + TestUtil.verifyImage(400, 400, secondImage); + } + break; + } + + pdfDocument.close(); + } + + @DataProvider(name = "imageCompressionDataProvider") + public static Object[][] imageCompressionDataProvider() { + return new Object[][] + { + {PdfImageCompression.AUTO}, + {PdfImageCompression.JPEG}, + }; + } + + @Test(dataProvider = "imageColorSpaceExportModeDataProvider") + public void imageColorSpaceExportMode(int pdfImageColorSpaceExportMode) throws Exception { + //ExStart + //ExFor:PdfImageColorSpaceExportMode + //ExFor:PdfSaveOptions.ImageColorSpaceExportMode + //ExSummary:Shows how to set a different color space for images in a document as we export it to PDF. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Jpeg image:"); + builder.insertImage(getImageDir() + "Logo.jpg"); + builder.insertParagraph(); + builder.writeln("Png image:"); + builder.insertImage(getImageDir() + "Transparent background logo.png"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions pdfSaveOptions = new PdfSaveOptions(); + + // Set the "ImageColorSpaceExportMode" property to "PdfImageColorSpaceExportMode.Auto" to get Aspose.Words to + // automatically select the color space for images in the document that it converts to PDF. + // In most cases, the color space will be RGB. + // Set the "ImageColorSpaceExportMode" property to "PdfImageColorSpaceExportMode.SimpleCmyk" + // to use the CMYK color space for all images in the saved PDF. + // Aspose.Words will also apply Flate compression to all images and ignore the "ImageCompression" property's value. + pdfSaveOptions.setImageColorSpaceExportMode(pdfImageColorSpaceExportMode); + + doc.save(getArtifactsDir() + "PdfSaveOptions.ImageColorSpaceExportMode.pdf", pdfSaveOptions); + //ExEnd + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.ImageColorSpaceExportMode.pdf"); + XImage pdfDocImage = pdfDocument.getPages().get_Item(1).getResources().getImages().get_Item(1); + + Assert.assertEquals(400, pdfDocImage.getWidth()); + Assert.assertEquals(400, pdfDocImage.getHeight()); + Assert.assertEquals(ColorType.Rgb, pdfDocImage.getColorType()); + + pdfDocImage = pdfDocument.getPages().get_Item(1).getResources().getImages().get_Item(2); + + Assert.assertEquals(400, pdfDocImage.getWidth()); + Assert.assertEquals(400, pdfDocImage.getHeight()); + Assert.assertEquals(ColorType.Rgb, pdfDocImage.getColorType()); + + pdfDocument.close(); + } + + @DataProvider(name = "imageColorSpaceExportModeDataProvider") + public static Object[][] imageColorSpaceExportModeDataProvider() { + return new Object[][] + { + {PdfImageColorSpaceExportMode.AUTO}, + {PdfImageColorSpaceExportMode.SIMPLE_CMYK}, + }; + } + + @Test + public void downsampleOptions() throws Exception { + //ExStart + //ExFor:DownsampleOptions + //ExFor:DownsampleOptions.DownsampleImages + //ExFor:DownsampleOptions.Resolution + //ExFor:DownsampleOptions.ResolutionThreshold + //ExFor:PdfSaveOptions.DownsampleOptions + //ExSummary:Shows how to change the resolution of images in the PDF document. + Document doc = new Document(getMyDir() + "Images.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // By default, Aspose.Words downsample all images in a document that we save to PDF to 220 ppi. + Assert.assertTrue(options.getDownsampleOptions().getDownsampleImages()); + Assert.assertEquals(220, options.getDownsampleOptions().getResolution()); + Assert.assertEquals(0, options.getDownsampleOptions().getResolutionThreshold()); + + doc.save(getArtifactsDir() + "PdfSaveOptions.DownsampleOptions.Default.pdf", options); + + // Set the "Resolution" property to "36" to downsample all images to 36 ppi. + options.getDownsampleOptions().setResolution(36); + + // Set the "ResolutionThreshold" property to only apply the downsampling to + // images with a resolution that is above 128 ppi. + options.getDownsampleOptions().setResolutionThreshold(128); + + // Only the first two images from the document will be downsampled at this stage. + doc.save(getArtifactsDir() + "PdfSaveOptions.DownsampleOptions.LowerResolution.pdf", options); + //ExEnd + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.DownsampleOptions.Default.pdf"); + XImage pdfDocImage = pdfDocument.getPages().get_Item(1).getResources().getImages().get_Item(1); + + Assert.assertEquals(ColorType.Rgb, pdfDocImage.getColorType()); + + pdfDocument.close(); + } + + @Test(dataProvider = "colorRenderingDataProvider") + public void colorRendering(int colorMode) throws Exception { + //ExStart + //ExFor:PdfSaveOptions + //ExFor:ColorMode + //ExFor:FixedPageSaveOptions.ColorMode + //ExSummary:Shows how to change image color with saving options property. + Document doc = new Document(getMyDir() + "Images.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + // Set the "ColorMode" property to "Grayscale" to render all images from the document in black and white. + // The size of the output document may be larger with this setting. + // Set the "ColorMode" property to "Normal" to render all images in color. + PdfSaveOptions pdfSaveOptions = new PdfSaveOptions(); + { + pdfSaveOptions.setColorMode(colorMode); + } + + doc.save(getArtifactsDir() + "PdfSaveOptions.ColorRendering.pdf", pdfSaveOptions); + //ExEnd + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.ColorRendering.pdf"); + XImage pdfDocImage = pdfDocument.getPages().get_Item(1).getResources().getImages().get_Item(1); + + switch (colorMode) { + case ColorMode.NORMAL: + Assert.assertEquals(ColorType.Rgb, pdfDocImage.getColorType()); + break; + case ColorMode.GRAYSCALE: + Assert.assertEquals(ColorType.Grayscale, pdfDocImage.getColorType()); + break; + } + + pdfDocument.close(); + } + + @DataProvider(name = "colorRenderingDataProvider") + public static Object[][] colorRenderingDataProvider() { + return new Object[][] + { + {ColorMode.GRAYSCALE}, + {ColorMode.NORMAL}, + }; + } + + @Test(dataProvider = "docTitleDataProvider") + public void docTitle(boolean displayDocTitle) throws Exception { + //ExStart + //ExFor:PdfSaveOptions.DisplayDocTitle + //ExSummary:Shows how to display the title of the document as the title bar. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + doc.getBuiltInDocumentProperties().setTitle("Windows bar pdf title"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + // Set the "DisplayDocTitle" to "true" to get some PDF readers, such as Adobe Acrobat Pro, + // to display the value of the document's "Title" built-in property in the tab that belongs to this document. + // Set the "DisplayDocTitle" to "false" to get such readers to display the document's filename. + PdfSaveOptions pdfSaveOptions = new PdfSaveOptions(); + { + pdfSaveOptions.setDisplayDocTitle(displayDocTitle); + } + + doc.save(getArtifactsDir() + "PdfSaveOptions.DocTitle.pdf", pdfSaveOptions); + //ExEnd + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.DocTitle.pdf"); + + Assert.assertEquals(displayDocTitle, pdfDocument.isDisplayDocTitle()); + Assert.assertEquals("Windows bar pdf title", pdfDocument.getInfo().getTitle()); + + pdfDocument.close(); + } + + @DataProvider(name = "docTitleDataProvider") + public static Object[][] docTitleDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "memoryOptimizationDataProvider") + public void memoryOptimization(boolean memoryOptimization) throws Exception { + //ExStart + //ExFor:SaveOptions.CreateSaveOptions(SaveFormat) + //ExFor:SaveOptions.MemoryOptimization + //ExSummary:Shows an option to optimize memory consumption when rendering large documents to PDF. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + SaveOptions saveOptions = SaveOptions.createSaveOptions(SaveFormat.PDF); + + // Set the "MemoryOptimization" property to "true" to lower the memory footprint of large documents' saving operations + // at the cost of increasing the duration of the operation. + // Set the "MemoryOptimization" property to "false" to save the document as a PDF normally. + saveOptions.setMemoryOptimization(memoryOptimization); + + doc.save(getArtifactsDir() + "PdfSaveOptions.MemoryOptimization.pdf", saveOptions); + //ExEnd + } + + @DataProvider(name = "memoryOptimizationDataProvider") + public static Object[][] memoryOptimizationDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "escapeUriDataProvider") + public void escapeUri(String uri, String result) throws Exception { + //ExStart + //ExFor:PdfSaveOptions + //ExSummary:Shows how to escape hyperlinks in the document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertHyperlink("Testlink", uri, false); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + doc.save(getArtifactsDir() + "PdfSaveOptions.EscapedUri.pdf", options); + //ExEnd + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.EscapedUri.pdf"); + + Page page = pdfDocument.getPages().get_Item(1); + LinkAnnotation linkAnnot = (LinkAnnotation) page.getAnnotations().get_Item(1); + + GoToURIAction action = (GoToURIAction) linkAnnot.getAction(); + + Assert.assertEquals(result, action.getURI()); + + pdfDocument.close(); + } + + @DataProvider(name = "escapeUriDataProvider") + public static Object[][] escapeUriDataProvider() { + return new Object[][] + { + {"https://www.google.com/search?q= aspose", "https://www.google.com/search?q=%20aspose"}, + {"https://www.google.com/search?q=%20aspose", "https://www.google.com/search?q=%20aspose"}, + }; + } + + @Test(dataProvider = "openHyperlinksInNewWindowDataProvider") + public void openHyperlinksInNewWindow(boolean openHyperlinksInNewWindow) throws Exception { + //ExStart + //ExFor:PdfSaveOptions.OpenHyperlinksInNewWindow + //ExSummary:Shows how to save hyperlinks in a document we convert to PDF so that they open new pages when we click on them. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertHyperlink("Testlink", "https://www.google.com/search?q=%20aspose", false); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "OpenHyperlinksInNewWindow" property to "true" to save all hyperlinks using Javascript code + // that forces readers to open these links in new windows/browser tabs. + // Set the "OpenHyperlinksInNewWindow" property to "false" to save all hyperlinks normally. + options.setOpenHyperlinksInNewWindow(openHyperlinksInNewWindow); + + doc.save(getArtifactsDir() + "PdfSaveOptions.OpenHyperlinksInNewWindow.pdf", options); + //ExEnd + + if (openHyperlinksInNewWindow) + TestUtil.fileContainsString( + "<>/A<>>>", + getArtifactsDir() + "PdfSaveOptions.OpenHyperlinksInNewWindow.pdf"); + else + TestUtil.fileContainsString( + "<>/A<>>>", + getArtifactsDir() + "PdfSaveOptions.OpenHyperlinksInNewWindow.pdf"); + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.OpenHyperlinksInNewWindow.pdf"); + + Page page = pdfDocument.getPages().get_Item(1); + LinkAnnotation linkAnnot = (LinkAnnotation) page.getAnnotations().get_Item(1); + + Assert.assertEquals(openHyperlinksInNewWindow ? JavascriptAction.class : GoToURIAction.class, + linkAnnot.getAction().getClass()); + + pdfDocument.close(); + } + + @DataProvider(name = "openHyperlinksInNewWindowDataProvider") + public static Object[][] openHyperlinksInNewWindowDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + //ExStart + //ExFor:MetafileRenderingMode + //ExFor:MetafileRenderingOptions + //ExFor:MetafileRenderingOptions.EmulateRasterOperations + //ExFor:MetafileRenderingOptions.RenderingMode + //ExFor:IWarningCallback + //ExFor:FixedPageSaveOptions.MetafileRenderingOptions + //ExSummary:Shows added a fallback to bitmap rendering and changing type of warnings about unsupported metafile records. + @Test(groups = "SkipMono") //ExSkip + public void handleBinaryRasterWarnings() throws Exception { + Document doc = new Document(getMyDir() + "WMF with image.docx"); + + MetafileRenderingOptions metafileRenderingOptions = new MetafileRenderingOptions(); + + // Set the "EmulateRasterOperations" property to "false" to fall back to bitmap when + // it encounters a metafile, which will require raster operations to render in the output PDF. + metafileRenderingOptions.setEmulateRasterOperations(false); + + // Set the "RenderingMode" property to "VectorWithFallback" to try to render every metafile using vector graphics. + metafileRenderingOptions.setRenderingMode(MetafileRenderingMode.VECTOR_WITH_FALLBACK); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF and applies the configuration + // in our MetafileRenderingOptions object to the saving operation. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setMetafileRenderingOptions(metafileRenderingOptions); + + HandleDocumentWarnings callback = new HandleDocumentWarnings(); + doc.setWarningCallback(callback); + + doc.save(getArtifactsDir() + "PdfSaveOptions.HandleBinaryRasterWarnings.pdf", saveOptions); + + Assert.assertEquals(1, callback.mWarnings.getCount()); + Assert.assertEquals("'R2_XORPEN' binary raster operation is not supported.", + callback.mWarnings.get(0).getDescription()); + } + + /// + /// Prints and collects formatting loss-related warnings that occur upon saving a document. + /// + public static class HandleDocumentWarnings implements IWarningCallback { + public void warning(WarningInfo info) { + if (info.getWarningType() == WarningType.MINOR_FORMATTING_LOSS) { + System.out.println("Unsupported operation: " + info.getDescription()); + this.mWarnings.warning(info); + } + } + + public WarningInfoCollection mWarnings = new WarningInfoCollection(); + } + //ExEnd + + @Test(dataProvider = "headerFooterBookmarksExportModeDataProvider") + public void headerFooterBookmarksExportMode(final int headerFooterBookmarksExportMode) throws Exception { + //ExStart + //ExFor:HeaderFooterBookmarksExportMode + //ExFor:OutlineOptions + //ExFor:OutlineOptions.DefaultBookmarksOutlineLevel + //ExFor:PdfSaveOptions.HeaderFooterBookmarksExportMode + //ExFor:PdfSaveOptions.PageMode + //ExFor:PdfPageMode + //ExSummary:Shows to process bookmarks in headers/footers in a document that we are rendering to PDF. + Document doc = new Document(getMyDir() + "Bookmarks in headers and footers.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + + // Set the "PageMode" property to "PdfPageMode.UseOutlines" to display the outline navigation pane in the output PDF. + saveOptions.setPageMode(PdfPageMode.USE_OUTLINES); + + // Set the "DefaultBookmarksOutlineLevel" property to "1" to display all + // bookmarks at the first level of the outline in the output PDF. + saveOptions.getOutlineOptions().setDefaultBookmarksOutlineLevel(1); + + // Set the "HeaderFooterBookmarksExportMode" property to "HeaderFooterBookmarksExportMode.None" to + // not export any bookmarks that are inside headers/footers. + // Set the "HeaderFooterBookmarksExportMode" property to "HeaderFooterBookmarksExportMode.First" to + // only export bookmarks in the first section's header/footers. + // Set the "HeaderFooterBookmarksExportMode" property to "HeaderFooterBookmarksExportMode.All" to + // export bookmarks that are in all headers/footers. + saveOptions.setHeaderFooterBookmarksExportMode(headerFooterBookmarksExportMode); + + doc.save(getArtifactsDir() + "PdfSaveOptions.HeaderFooterBookmarksExportMode.pdf", saveOptions); + //ExEnd + + com.aspose.pdf.Document pdfDoc = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.HeaderFooterBookmarksExportMode.pdf"); + String inputDocLocaleName = LocaleUtil.getLocaleFromLCID(doc.getStyles().getDefaultFont().getLocaleId()); + + TextFragmentAbsorber textFragmentAbsorber = new TextFragmentAbsorber(); + pdfDoc.getPages().accept(textFragmentAbsorber); + switch (headerFooterBookmarksExportMode) { + case com.aspose.words.HeaderFooterBookmarksExportMode.NONE: + TestUtil.fileContainsString(MessageFormat.format("<>\r\n", inputDocLocaleName), + getArtifactsDir() + "PdfSaveOptions.HeaderFooterBookmarksExportMode.pdf"); + + Assert.assertEquals(0, pdfDoc.getOutlines().size()); + break; + case com.aspose.words.HeaderFooterBookmarksExportMode.FIRST: + case com.aspose.words.HeaderFooterBookmarksExportMode.ALL: + TestUtil.fileContainsString( + MessageFormat.format("<>", inputDocLocaleName), + getArtifactsDir() + "PdfSaveOptions.HeaderFooterBookmarksExportMode.pdf"); + + OutlineCollection outlineItemCollection = pdfDoc.getOutlines(); + + Assert.assertEquals(4, outlineItemCollection.size()); + Assert.assertEquals("Bookmark_1", outlineItemCollection.get_Item(1).getTitle()); + Assert.assertEquals("1 XYZ 233 806 0", outlineItemCollection.get_Item(1).getDestination().toString()); + + Assert.assertEquals("Bookmark_2", outlineItemCollection.get_Item(2).getTitle()); + Assert.assertEquals("1 XYZ 84 47 0", outlineItemCollection.get_Item(2).getDestination().toString()); + + Assert.assertEquals("Bookmark_3", outlineItemCollection.get_Item(3).getTitle()); + Assert.assertEquals("2 XYZ 85 806 0", outlineItemCollection.get_Item(3).getDestination().toString()); + + Assert.assertEquals("Bookmark_4", outlineItemCollection.get_Item(4).getTitle()); + Assert.assertEquals("2 XYZ 85 48 0", outlineItemCollection.get_Item(4).getDestination().toString()); + break; + } + pdfDoc.close(); + } + + @DataProvider(name = "headerFooterBookmarksExportModeDataProvider") + public static Object[][] headerFooterBookmarksExportModeDataProvider() { + return new Object[][] + { + {com.aspose.words.HeaderFooterBookmarksExportMode.NONE}, + {com.aspose.words.HeaderFooterBookmarksExportMode.FIRST}, + {com.aspose.words.HeaderFooterBookmarksExportMode.ALL}, + }; + } + + @Test + public void unsupportedImageFormatWarning() throws Exception { + Document doc = new Document(getMyDir() + "Corrupted image.docx"); + + SaveWarningCallback saveWarningCallback = new SaveWarningCallback(); + doc.setWarningCallback(saveWarningCallback); + + doc.save(getArtifactsDir() + "PdfSaveOption.UnsupportedImageFormatWarning.pdf", SaveFormat.PDF); + + Assert.assertEquals(saveWarningCallback.mSaveWarnings.get(0).getDescription(), + "Image can not be processed. Possibly unsupported image format."); + } + + public static class SaveWarningCallback implements IWarningCallback { + public void warning(final WarningInfo info) { + if (info.getWarningType() == WarningType.MINOR_FORMATTING_LOSS) { + System.out.println(MessageFormat.format("{0}: {1}.", info.getWarningType(), info.getDescription())); + mSaveWarnings.warning(info); + } + } + + WarningInfoCollection mSaveWarnings = new WarningInfoCollection(); + } + + @Test (dataProvider = "emulateRenderingToSizeOnPageDataProvider") + public void emulateRenderingToSizeOnPage(boolean renderToSize) throws Exception + { + //ExStart + //ExFor:MetafileRenderingOptions.EmulateRenderingToSizeOnPage + //ExFor:MetafileRenderingOptions.EmulateRenderingToSizeOnPageResolution + //ExSummary:Shows how to display of the metafile according to the size on page. + Document doc = new Document(getMyDir() + "WMF with text.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + + // Set the "EmulateRenderingToSizeOnPage" property to "true" + // to emulate rendering according to the metafile size on page. + // Set the "EmulateRenderingToSizeOnPage" property to "false" + // to emulate metafile rendering to its default size in pixels. + saveOptions.getMetafileRenderingOptions().setEmulateRenderingToSizeOnPage(renderToSize); + saveOptions.getMetafileRenderingOptions().setEmulateRenderingToSizeOnPageResolution(50); + + doc.save(getArtifactsDir() + "PdfSaveOptions.EmulateRenderingToSizeOnPage.pdf", saveOptions); + //ExEnd + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.EmulateRenderingToSizeOnPage.pdf"); + TextFragmentAbsorber textAbsorber = new TextFragmentAbsorber(); + + pdfDocument.getPages().get_Item(1).accept(textAbsorber); + Rectangle textFragmentRectangle = textAbsorber.getTextFragments().get_Item(3).getRectangle(); + + Assert.assertEquals(renderToSize ? 1.585d : 5.045d, textFragmentRectangle.getWidth(), 0.001d); + + pdfDocument.close(); + } + + @DataProvider(name = "emulateRenderingToSizeOnPageDataProvider") + public static Object[][] emulateRenderingToSizeOnPageDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "embedFullFontsDataProvider") + public void embedFullFonts(boolean embedFullFonts) throws Exception { + //ExStart + //ExFor:PdfSaveOptions.#ctor + //ExFor:PdfSaveOptions.EmbedFullFonts + //ExSummary:Shows how to enable or disable subsetting when embedding fonts while rendering a document to PDF. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Arial"); + builder.writeln("Hello world!"); + builder.getFont().setName("Arvo"); + builder.writeln("The quick brown fox jumps over the lazy dog."); + + // Configure our font sources to ensure that we have access to both the fonts in this document. + FontSourceBase[] originalFontsSources = FontSettings.getDefaultInstance().getFontsSources(); + FolderFontSource folderFontSource = new FolderFontSource(getFontsDir(), true); + FontSettings.getDefaultInstance().setFontsSources(new FontSourceBase[]{originalFontsSources[0], folderFontSource}); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Since our document contains a custom font, embedding in the output document may be desirable. + // Set the "EmbedFullFonts" property to "true" to embed every glyph of every embedded font in the output PDF. + // The document's size may become very large, but we will have full use of all fonts if we edit the PDF. + // Set the "EmbedFullFonts" property to "false" to apply subsetting to fonts, saving only the glyphs + // that the document is using. The file will be considerably smaller, + // but we may need access to any custom fonts if we edit the document. + options.setEmbedFullFonts(embedFullFonts); + + doc.save(getArtifactsDir() + "PdfSaveOptions.EmbedFullFonts.pdf", options); + + if (embedFullFonts) + Assert.assertTrue(new File(getArtifactsDir() + "PdfSaveOptions.EmbedFullFonts.pdf").length() < 571000); + else + Assert.assertTrue(new File(getArtifactsDir() + "PdfSaveOptions.EmbedFullFonts.pdf").length() < 25000); + + // Restore the original font sources. + FontSettings.getDefaultInstance().setFontsSources(originalFontsSources); + //ExEnd + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.EmbedFullFonts.pdf"); + + Font[] pdfDocFonts = pdfDocument.getFontUtilities().getAllFonts(); + + Assert.assertEquals("ArialMT", pdfDocFonts[0].getFontName()); + Assert.assertNotEquals(embedFullFonts, pdfDocFonts[0].isSubset()); + + Assert.assertEquals("Arvo", pdfDocFonts[1].getFontName()); + Assert.assertNotEquals(embedFullFonts, pdfDocFonts[1].isSubset()); + + pdfDocument.close(); + } + + @DataProvider(name = "embedFullFontsDataProvider") + public static Object[][] embedFullFontsDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "embedWindowsFontsDataProvider") + public void embedWindowsFonts(int pdfFontEmbeddingMode) throws Exception { + //ExStart + //ExFor:PdfSaveOptions.FontEmbeddingMode + //ExFor:PdfFontEmbeddingMode + //ExSummary:Shows how to set Aspose.Words to skip embedding Arial and Times New Roman fonts into a PDF document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // "Arial" is a standard font, and "Courier New" is a nonstandard font. + builder.getFont().setName("Arial"); + builder.writeln("Hello world!"); + builder.getFont().setName("Courier New"); + builder.writeln("The quick brown fox jumps over the lazy dog."); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "EmbedFullFonts" property to "true" to embed every glyph of every embedded font in the output PDF. + options.setEmbedFullFonts(true); + + // Set the "FontEmbeddingMode" property to "EmbedAll" to embed all fonts in the output PDF. + // Set the "FontEmbeddingMode" property to "EmbedNonstandard" to only allow nonstandard fonts' embedding in the output PDF. + // Set the "FontEmbeddingMode" property to "EmbedNone" to not embed any fonts in the output PDF. + options.setFontEmbeddingMode(pdfFontEmbeddingMode); + + doc.save(getArtifactsDir() + "PdfSaveOptions.EmbedWindowsFonts.pdf", options); + + switch (pdfFontEmbeddingMode) { + case PdfFontEmbeddingMode.EMBED_ALL: + Assert.assertTrue(new File(getArtifactsDir() + "PdfSaveOptions.EmbedWindowsFonts.pdf").length() < 1031200); + break; + case PdfFontEmbeddingMode.EMBED_NONSTANDARD: + Assert.assertTrue(new File(getArtifactsDir() + "PdfSaveOptions.EmbedWindowsFonts.pdf").length() < 491800); + break; + case PdfFontEmbeddingMode.EMBED_NONE: + Assert.assertTrue(new File(getArtifactsDir() + "PdfSaveOptions.EmbedWindowsFonts.pdf").length() <= 4258); + break; + } + //ExEnd + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.EmbedWindowsFonts.pdf"); + + com.aspose.pdf.Font[] pdfDocFonts = pdfDocument.getFontUtilities().getAllFonts(); + + Assert.assertEquals("ArialMT", pdfDocFonts[0].getFontName()); + Assert.assertEquals(pdfFontEmbeddingMode == PdfFontEmbeddingMode.EMBED_ALL, + pdfDocFonts[0].isEmbedded()); + + Assert.assertEquals("CourierNewPSMT", pdfDocFonts[1].getFontName()); + Assert.assertEquals(pdfFontEmbeddingMode == PdfFontEmbeddingMode.EMBED_ALL || pdfFontEmbeddingMode == PdfFontEmbeddingMode.EMBED_NONSTANDARD, + pdfDocFonts[1].isEmbedded()); + + pdfDocument.close(); + } + + @DataProvider(name = "embedWindowsFontsDataProvider") + public static Object[][] embedWindowsFontsDataProvider() { + return new Object[][] + { + {PdfFontEmbeddingMode.EMBED_ALL}, + {PdfFontEmbeddingMode.EMBED_NONE}, + {PdfFontEmbeddingMode.EMBED_NONSTANDARD}, + }; + } + + @Test(dataProvider = "embedCoreFontsDataProvider") + public void embedCoreFonts(boolean useCoreFonts) throws Exception { + //ExStart + //ExFor:PdfSaveOptions.UseCoreFonts + //ExSummary:Shows how enable/disable PDF Type 1 font substitution. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Arial"); + builder.writeln("Hello world!"); + builder.getFont().setName("Courier New"); + builder.writeln("The quick brown fox jumps over the lazy dog."); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "UseCoreFonts" property to "true" to replace some fonts, + // including the two fonts in our document, with their PDF Type 1 equivalents. + // Set the "UseCoreFonts" property to "false" to not apply PDF Type 1 fonts. + options.setUseCoreFonts(useCoreFonts); + + doc.save(getArtifactsDir() + "PdfSaveOptions.EmbedCoreFonts.pdf", options); + + if (useCoreFonts) + Assert.assertTrue(new File(getArtifactsDir() + "PdfSaveOptions.EmbedCoreFonts.pdf").length() < 3000); + else + Assert.assertTrue(new File(getArtifactsDir() + "PdfSaveOptions.EmbedCoreFonts.pdf").length() < 33200); + //ExEnd + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.EmbedCoreFonts.pdf"); + + Font[] pdfDocFonts = pdfDocument.getFontUtilities().getAllFonts(); + + if (useCoreFonts) { + Assert.assertEquals("Helvetica", pdfDocFonts[0].getFontName()); + Assert.assertEquals("Courier", pdfDocFonts[1].getFontName()); + } else { + Assert.assertEquals("ArialMT", pdfDocFonts[0].getFontName()); + Assert.assertEquals("CourierNewPSMT", pdfDocFonts[1].getFontName()); + } + + Assert.assertNotEquals(useCoreFonts, pdfDocFonts[0].isEmbedded()); + Assert.assertNotEquals(useCoreFonts, pdfDocFonts[1].isEmbedded()); + + pdfDocument.close(); + } + + @DataProvider(name = "embedCoreFontsDataProvider") + public static Object[][] embedCoreFontsDataProvider() { + return new Object[][] + { + {true}, + {false} + }; + } + + @Test(dataProvider = "additionalTextPositioningDataProvider") + public void additionalTextPositioning(boolean applyAdditionalTextPositioning) throws Exception { + //ExStart + //ExFor:PdfSaveOptions.AdditionalTextPositioning + //ExSummary:Show how to write additional text positioning operators. + Document doc = new Document(getMyDir() + "Text positioning operators.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setTextCompression(PdfTextCompression.NONE); + + // Set the "AdditionalTextPositioning" property to "true" to attempt to fix incorrect + // element positioning in the output PDF, should there be any, at the cost of increased file size. + // Set the "AdditionalTextPositioning" property to "false" to render the document as usual. + saveOptions.setAdditionalTextPositioning(applyAdditionalTextPositioning); + + doc.save(getArtifactsDir() + "PdfSaveOptions.AdditionalTextPositioning.pdf", saveOptions); + //ExEnd + + com.aspose.pdf.Document pdfDocument = + new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.AdditionalTextPositioning.pdf"); + TextFragmentAbsorber textAbsorber = new TextFragmentAbsorber(); + + pdfDocument.getPages().get_Item(1).accept(textAbsorber); + + SetGlyphsPositionShowText tjOperator = + (SetGlyphsPositionShowText) textAbsorber.getTextFragments().get_Item(1).getPage().getContents().get_Item(71); + + if (applyAdditionalTextPositioning) { + Assert.assertTrue(new File(getArtifactsDir() + "PdfSaveOptions.AdditionalTextPositioning.pdf").length() < 102000); + Assert.assertEquals( + "[0 (S) 0 (a) 0 (m) 0 (s) 0 (t) 0 (a) -1 (g) 1 (,) 0 ( ) 0 (1) 0 (0) 0 (.) 0 ( ) 0 (N) 0 (o) 0 (v) 0 (e) 0 (m) 0 (b) 0 (e) 0 (r) -1 ( ) 1 (2) -1 (0) 0 (1) 0 (8)] TJ", + tjOperator.toString()); + } else { + Assert.assertTrue(new File(getArtifactsDir() + "PdfSaveOptions.AdditionalTextPositioning.pdf").length() < 99200); + Assert.assertEquals("[(Samsta) -1 (g) 1 (, 10. November) -1 ( ) 1 (2) -1 (018)] TJ", tjOperator.toString()); + } + + pdfDocument.close(); + } + + @DataProvider(name = "additionalTextPositioningDataProvider") + public static Object[][] additionalTextPositioningDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "saveAsPdfBookFoldDataProvider") + public void saveAsPdfBookFold(boolean renderTextAsBookfold) throws Exception { + //ExStart + //ExFor:PdfSaveOptions.UseBookFoldPrintingSettings + //ExSummary:Shows how to save a document to the PDF format in the form of a book fold. + Document doc = new Document(getMyDir() + "Paragraphs.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "UseBookFoldPrintingSettings" property to "true" to arrange the contents + // in the output PDF in a way that helps us use it to make a booklet. + // Set the "UseBookFoldPrintingSettings" property to "false" to render the PDF normally. + options.setUseBookFoldPrintingSettings(renderTextAsBookfold); + + // If we are rendering the document as a booklet, we must set the "MultiplePages" + // properties of the page setup objects of all sections to "MultiplePagesType.BookFoldPrinting". + if (renderTextAsBookfold) + for (Section s : doc.getSections()) { + s.getPageSetup().setMultiplePages(MultiplePagesType.BOOK_FOLD_PRINTING); + } + + // Once we print this document on both sides of the pages, we can fold all the pages down the middle at once, + // and the contents will line up in a way that creates a booklet. + doc.save(getArtifactsDir() + "PdfSaveOptions.SaveAsPdfBookFold.pdf", options); + //ExEnd + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.SaveAsPdfBookFold.pdf"); + TextAbsorber textAbsorber = new TextAbsorber(); + + pdfDocument.getPages().accept(textAbsorber); + + if (renderTextAsBookfold) { + Assert.assertTrue(textAbsorber.getText().indexOf("Heading #1") < textAbsorber.getText().indexOf("Heading #2")); + Assert.assertTrue(textAbsorber.getText().indexOf("Heading #2") < textAbsorber.getText().indexOf("Heading #3")); + Assert.assertTrue(textAbsorber.getText().indexOf("Heading #3") < textAbsorber.getText().indexOf("Heading #4")); + Assert.assertTrue(textAbsorber.getText().indexOf("Heading #4") < textAbsorber.getText().indexOf("Heading #5")); + Assert.assertTrue(textAbsorber.getText().indexOf("Heading #5") < textAbsorber.getText().indexOf("Heading #6")); + Assert.assertTrue(textAbsorber.getText().indexOf("Heading #6") < textAbsorber.getText().indexOf("Heading #7")); + Assert.assertFalse(textAbsorber.getText().indexOf("Heading #7") < textAbsorber.getText().indexOf("Heading #8")); + Assert.assertTrue(textAbsorber.getText().indexOf("Heading #8") < textAbsorber.getText().indexOf("Heading #9")); + Assert.assertFalse(textAbsorber.getText().indexOf("Heading #9") < textAbsorber.getText().indexOf("Heading #10")); + } else { + Assert.assertTrue(textAbsorber.getText().indexOf("Heading #1") < textAbsorber.getText().indexOf("Heading #2")); + Assert.assertTrue(textAbsorber.getText().indexOf("Heading #2") < textAbsorber.getText().indexOf("Heading #3")); + Assert.assertTrue(textAbsorber.getText().indexOf("Heading #3") < textAbsorber.getText().indexOf("Heading #4")); + Assert.assertTrue(textAbsorber.getText().indexOf("Heading #4") < textAbsorber.getText().indexOf("Heading #5")); + Assert.assertTrue(textAbsorber.getText().indexOf("Heading #5") < textAbsorber.getText().indexOf("Heading #6")); + Assert.assertTrue(textAbsorber.getText().indexOf("Heading #6") < textAbsorber.getText().indexOf("Heading #7")); + Assert.assertTrue(textAbsorber.getText().indexOf("Heading #7") < textAbsorber.getText().indexOf("Heading #8")); + Assert.assertTrue(textAbsorber.getText().indexOf("Heading #8") < textAbsorber.getText().indexOf("Heading #9")); + Assert.assertTrue(textAbsorber.getText().indexOf("Heading #9") < textAbsorber.getText().indexOf("Heading #10")); + } + + pdfDocument.close(); + } + + @DataProvider(name = "saveAsPdfBookFoldDataProvider") + public static Object[][] saveAsPdfBookFoldDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void zoomBehaviour() throws Exception { + //ExStart + //ExFor:PdfSaveOptions.ZoomBehavior + //ExFor:PdfSaveOptions.ZoomFactor + //ExFor:PdfZoomBehavior + //ExSummary:Shows how to set the default zooming that a reader applies when opening a rendered PDF document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + // Set the "ZoomBehavior" property to "PdfZoomBehavior.ZoomFactor" to get a PDF reader to + // apply a percentage-based zoom factor when we open the document with it. + // Set the "ZoomFactor" property to "25" to give the zoom factor a value of 25%. + PdfSaveOptions options = new PdfSaveOptions(); + { + options.setZoomBehavior(PdfZoomBehavior.ZOOM_FACTOR); + options.setZoomFactor(25); + } + + // When we open this document using a reader such as Adobe Acrobat, we will see the document scaled at 1/4 of its actual size. + doc.save(getArtifactsDir() + "PdfSaveOptions.ZoomBehaviour.pdf", options); + //ExEnd + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.ZoomBehaviour.pdf"); + GoToAction action = (GoToAction) pdfDocument.getOpenAction(); + + Assert.assertEquals(0.25d, ((XYZExplicitDestination) action.getDestination()).getZoom()); + + pdfDocument.close(); + } + + @Test(dataProvider = "pageModeDataProvider") + public void pageMode(int pageMode) throws Exception { + //ExStart + //ExFor:PdfSaveOptions.PageMode + //ExFor:PdfPageMode + //ExSummary:Shows how to set instructions for some PDF readers to follow when opening an output document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "PageMode" property to "PdfPageMode.FullScreen" to get the PDF reader to open the saved + // document in full-screen mode, which takes over the monitor's display and has no controls visible. + // Set the "PageMode" property to "PdfPageMode.UseThumbs" to get the PDF reader to display a separate panel + // with a thumbnail for each page in the document. + // Set the "PageMode" property to "PdfPageMode.UseOC" to get the PDF reader to display a separate panel + // that allows us to work with any layers present in the document. + // Set the "PageMode" property to "PdfPageMode.UseOutlines" to get the PDF reader + // also to display the outline, if possible. + // Set the "PageMode" property to "PdfPageMode.UseNone" to get the PDF reader to display just the document itself. + // Set the "PageMode" property to "PdfPageMode.UseAttachments" to make visible attachments panel. + options.setPageMode(pageMode); + + doc.save(getArtifactsDir() + "PdfSaveOptions.PageMode.pdf", options); + //ExEnd + + String docLocaleName = LocaleUtil.getLocaleFromLCID(doc.getStyles().getDefaultFont().getLocaleId()); + + switch (pageMode) { + case PdfPageMode.FULL_SCREEN: + TestUtil.fileContainsString( + MessageFormat.format("<>\r\n", docLocaleName), + getArtifactsDir() + "PdfSaveOptions.PageMode.pdf"); + break; + case PdfPageMode.USE_THUMBS: + TestUtil.fileContainsString( + MessageFormat.format("<>", docLocaleName), + getArtifactsDir() + "PdfSaveOptions.PageMode.pdf"); + break; + case PdfPageMode.USE_OC: + TestUtil.fileContainsString( + MessageFormat.format("<>\r\n", docLocaleName), + getArtifactsDir() + "PdfSaveOptions.PageMode.pdf"); + break; + case PdfPageMode.USE_OUTLINES: + case PdfPageMode.USE_NONE: + TestUtil.fileContainsString(MessageFormat.format("<>\r\n", docLocaleName), + getArtifactsDir() + "PdfSaveOptions.PageMode.pdf"); + break; + case PdfPageMode.USE_ATTACHMENTS: + TestUtil.fileContainsString( + MessageFormat.format("<>\r\n", docLocaleName), + getArtifactsDir() + "PdfSaveOptions.PageMode.pdf"); + break; + } + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.PageMode.pdf"); + + switch (pageMode) { + case PdfPageMode.USE_NONE: + case PdfPageMode.USE_OUTLINES: + Assert.assertEquals(PageMode.UseNone, pdfDocument.getPageMode()); + break; + case PdfPageMode.USE_THUMBS: + Assert.assertEquals(PageMode.UseThumbs, pdfDocument.getPageMode()); + break; + case PdfPageMode.FULL_SCREEN: + Assert.assertEquals(PageMode.FullScreen, pdfDocument.getPageMode()); + break; + case PdfPageMode.USE_OC: + Assert.assertEquals(PageMode.UseOC, pdfDocument.getPageMode()); + break; + case PdfPageMode.USE_ATTACHMENTS: + Assert.assertEquals(PageMode.UseAttachments, pdfDocument.getPageMode()); + break; + } + + pdfDocument.close(); + } + + @DataProvider(name = "pageModeDataProvider") + public static Object[][] pageModeDataProvider() { + return new Object[][] + { + {PdfPageMode.FULL_SCREEN}, + {PdfPageMode.USE_THUMBS}, + {PdfPageMode.USE_OC}, + {PdfPageMode.USE_OUTLINES}, + {PdfPageMode.USE_NONE}, + {PdfPageMode.USE_ATTACHMENTS} + }; + } + + @Test(dataProvider = "noteHyperlinksDataProvider") + public void noteHyperlinks(boolean createNoteHyperlinks) throws Exception { + //ExStart + //ExFor:PdfSaveOptions.CreateNoteHyperlinks + //ExSummary:Shows how to make footnotes and endnotes function as hyperlinks. + Document doc = new Document(getMyDir() + "Footnotes and endnotes.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "CreateNoteHyperlinks" property to "true" to turn all footnote/endnote symbols + // in the text act as links that, upon clicking, take us to their respective footnotes/endnotes. + // Set the "CreateNoteHyperlinks" property to "false" not to have footnote/endnote symbols link to anything. + options.setCreateNoteHyperlinks(createNoteHyperlinks); + + doc.save(getArtifactsDir() + "PdfSaveOptions.NoteHyperlinks.pdf", options); + //ExEnd + + if (createNoteHyperlinks) { + TestUtil.fileContainsString( + "<>/Dest[5 0 R /XYZ 85 677 0]>>", + getArtifactsDir() + "PdfSaveOptions.NoteHyperlinks.pdf"); + TestUtil.fileContainsString( + "<>/Dest[5 0 R /XYZ 85 79 0]>>", + getArtifactsDir() + "PdfSaveOptions.NoteHyperlinks.pdf"); + TestUtil.fileContainsString( + "<>/Dest[5 0 R /XYZ 85 654 0]>>", + getArtifactsDir() + "PdfSaveOptions.NoteHyperlinks.pdf"); + TestUtil.fileContainsString( + "<>/Dest[5 0 R /XYZ 85 68 0]>>", + getArtifactsDir() + "PdfSaveOptions.NoteHyperlinks.pdf"); + TestUtil.fileContainsString( + "<>/Dest[5 0 R /XYZ 202 733 0]>>", + getArtifactsDir() + "PdfSaveOptions.NoteHyperlinks.pdf"); + TestUtil.fileContainsString( + "<>/Dest[5 0 R /XYZ 258 711 0]>>", + getArtifactsDir() + "PdfSaveOptions.NoteHyperlinks.pdf"); + TestUtil.fileContainsString( + "<>/Dest[5 0 R /XYZ 157 733 0]>>", + getArtifactsDir() + "PdfSaveOptions.NoteHyperlinks.pdf"); + TestUtil.fileContainsString( + "<>/Dest[5 0 R /XYZ 212 711 0]>>", + getArtifactsDir() + "PdfSaveOptions.NoteHyperlinks.pdf"); + } else { + Assert.assertThrows(AssertionError.class, () -> TestUtil.fileContainsString("< linkAnnotations = (List) (List) annotationSelector.getSelected(); + + if (createNoteHyperlinks) { + Assert.assertEquals(8, IterableUtils.countMatches(linkAnnotations, a -> a.getAnnotationType() == AnnotationType.Link)); + + Assert.assertEquals("1 XYZ 85 677 0", linkAnnotations.get(0).getDestination().toString()); + Assert.assertEquals("1 XYZ 85 79 0", linkAnnotations.get(1).getDestination().toString()); + Assert.assertEquals("1 XYZ 85 654 0", linkAnnotations.get(2).getDestination().toString()); + Assert.assertEquals("1 XYZ 85 68 0", linkAnnotations.get(3).getDestination().toString()); + Assert.assertEquals("1 XYZ 202 733 0", linkAnnotations.get(4).getDestination().toString()); + Assert.assertEquals("1 XYZ 258 711 0", linkAnnotations.get(5).getDestination().toString()); + Assert.assertEquals("1 XYZ 157 733 0", linkAnnotations.get(6).getDestination().toString()); + Assert.assertEquals("1 XYZ 212 711 0", linkAnnotations.get(7).getDestination().toString()); + } else { + Assert.assertEquals(0, annotationSelector.getSelected().size()); + } + + pdfDocument.close(); + } + + @DataProvider(name = "noteHyperlinksDataProvider") + public static Object[][] noteHyperlinksDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "customPropertiesExportDataProvider") + public void customPropertiesExport(int pdfCustomPropertiesExportMode) throws Exception { + //ExStart + //ExFor:PdfCustomPropertiesExport + //ExFor:PdfSaveOptions.CustomPropertiesExport + //ExSummary:Shows how to export custom properties while converting a document to PDF. + Document doc = new Document(); + + doc.getCustomDocumentProperties().add("Company", "My value"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "CustomPropertiesExport" property to "PdfCustomPropertiesExport.None" to discard + // custom document properties as we save the document to .PDF. + // Set the "CustomPropertiesExport" property to "PdfCustomPropertiesExport.Standard" + // to preserve custom properties within the output PDF document. + // Set the "CustomPropertiesExport" property to "PdfCustomPropertiesExport.Metadata" + // to preserve custom properties in an XMP packet. + options.setCustomPropertiesExport(pdfCustomPropertiesExportMode); + + doc.save(getArtifactsDir() + "PdfSaveOptions.CustomPropertiesExport.pdf", options); + //ExEnd + + switch (pdfCustomPropertiesExportMode) { + case PdfCustomPropertiesExport.NONE: + Assert.assertThrows(AssertionError.class, () -> TestUtil.fileContainsString( + doc.getCustomDocumentProperties().get(0).getName(), + getArtifactsDir() + "PdfSaveOptions.CustomPropertiesExport.pdf")); + Assert.assertThrows(AssertionError.class, () -> TestUtil.fileContainsString( + "<>", + getArtifactsDir() + "PdfSaveOptions.CustomPropertiesExport.pdf")); + break; + case PdfCustomPropertiesExport.STANDARD: + TestUtil.fileContainsString( + "<>", + getArtifactsDir() + "PdfSaveOptions.CustomPropertiesExport.pdf"); + break; + case PdfCustomPropertiesExport.METADATA: + TestUtil.fileContainsString("<>", + getArtifactsDir() + "PdfSaveOptions.CustomPropertiesExport.pdf"); + break; + } + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.CustomPropertiesExport.pdf"); + + Assert.assertEquals("Aspose.Words", pdfDocument.getInfo().getCreator()); + Assert.assertTrue(pdfDocument.getInfo().getProducer().startsWith("Aspose.Words")); + + switch (pdfCustomPropertiesExportMode) { + case PdfCustomPropertiesExport.NONE: + Assert.assertEquals(2, pdfDocument.getInfo().size()); + Assert.assertEquals(3, pdfDocument.getMetadata().size()); + break; + case PdfCustomPropertiesExport.METADATA: + Assert.assertEquals(2, pdfDocument.getInfo().size()); + Assert.assertEquals(4, pdfDocument.getMetadata().size()); + + Assert.assertEquals("Aspose.Words", pdfDocument.getMetadata().get_Item("xmp:CreatorTool").toString()); + Assert.assertEquals("Company", pdfDocument.getMetadata().get_Item("custprops:Property1").toString()); + break; + case PdfCustomPropertiesExport.STANDARD: + Assert.assertEquals(3, pdfDocument.getInfo().size()); + Assert.assertEquals(3, pdfDocument.getMetadata().size()); + + Assert.assertEquals("My value", pdfDocument.getInfo().get_Item("Company")); + break; + } + + pdfDocument.close(); + } + + @DataProvider(name = "customPropertiesExportDataProvider") + public static Object[][] customPropertiesExportDataProvider() { + return new Object[][] + { + {PdfCustomPropertiesExport.NONE}, + {PdfCustomPropertiesExport.STANDARD}, + {PdfCustomPropertiesExport.METADATA}, + }; + } + + @Test(dataProvider = "drawingMLEffectsDataProvider") + public void drawingMLEffects(int effectsRenderingMode) throws Exception { + //ExStart + //ExFor:DmlRenderingMode + //ExFor:DmlEffectsRenderingMode + //ExFor:PdfSaveOptions.DmlEffectsRenderingMode + //ExFor:SaveOptions.DmlEffectsRenderingMode + //ExFor:SaveOptions.DmlRenderingMode + //ExSummary:Shows how to configure the rendering quality of DrawingML effects in a document as we save it to PDF. + Document doc = new Document(getMyDir() + "DrawingML shape effects.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "DmlEffectsRenderingMode" property to "DmlEffectsRenderingMode.None" to discard all DrawingML effects. + // Set the "DmlEffectsRenderingMode" property to "DmlEffectsRenderingMode.Simplified" + // to render a simplified version of DrawingML effects. + // Set the "DmlEffectsRenderingMode" property to "DmlEffectsRenderingMode.Fine" to + // render DrawingML effects with more accuracy and also with more processing cost. + options.setDmlEffectsRenderingMode(effectsRenderingMode); + + Assert.assertEquals(DmlRenderingMode.DRAWING_ML, options.getDmlRenderingMode()); + + doc.save(getArtifactsDir() + "PdfSaveOptions.DrawingMLEffects.pdf", options); + //ExEnd + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.DrawingMLEffects.pdf"); + + ImagePlacementAbsorber imb = new ImagePlacementAbsorber(); + imb.visit(pdfDocument.getPages().get_Item(1)); + + TableAbsorber ttb = new TableAbsorber(); + ttb.visit(pdfDocument.getPages().get_Item(1)); + + switch (effectsRenderingMode) { + case DmlEffectsRenderingMode.NONE: + case DmlEffectsRenderingMode.SIMPLIFIED: + TestUtil.fileContainsString("<>>>/Group<>>>", + getArtifactsDir() + "PdfSaveOptions.DrawingMLEffects.pdf"); + Assert.assertEquals(0, imb.getImagePlacements().size()); + Assert.assertEquals(28, ttb.getTableList().size()); + break; + case DmlEffectsRenderingMode.FINE: + TestUtil.fileContainsString( + "<>/XObject<>>>/Group<>>>", + getArtifactsDir() + "PdfSaveOptions.DrawingMLEffects.pdf"); + Assert.assertEquals(21, imb.getImagePlacements().size()); + Assert.assertEquals(4, ttb.getTableList().size()); + break; + } + + pdfDocument.close(); + } + + @DataProvider(name = "drawingMLEffectsDataProvider") + public static Object[][] drawingMLEffectsDataProvider() { + return new Object[][] + { + {DmlEffectsRenderingMode.NONE}, + {DmlEffectsRenderingMode.SIMPLIFIED}, + {DmlEffectsRenderingMode.FINE}, + }; + } + + @Test(dataProvider = "drawingMLFallbackDataProvider") + public void drawingMLFallback(int dmlRenderingMode) throws Exception { + //ExStart + //ExFor:DmlRenderingMode + //ExFor:SaveOptions.DmlRenderingMode + //ExSummary:Shows how to render fallback shapes when saving to PDF. + Document doc = new Document(getMyDir() + "DrawingML shape fallbacks.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "DmlRenderingMode" property to "DmlRenderingMode.Fallback" + // to substitute DML shapes with their fallback shapes. + // Set the "DmlRenderingMode" property to "DmlRenderingMode.DrawingML" + // to render the DML shapes themselves. + options.setDmlRenderingMode(dmlRenderingMode); + + doc.save(getArtifactsDir() + "PdfSaveOptions.DrawingMLFallback.pdf", options); + //ExEnd + + switch (dmlRenderingMode) { + case DmlRenderingMode.DRAWING_ML: + TestUtil.fileContainsString( + "<>>>/Group<>>>", + getArtifactsDir() + "PdfSaveOptions.DrawingMLFallback.pdf"); + break; + case DmlRenderingMode.FALLBACK: + TestUtil.fileContainsString( + "<>/ExtGState<>>>/Group<>>>", + getArtifactsDir() + "PdfSaveOptions.DrawingMLFallback.pdf"); + break; + } + + com.aspose.pdf.Document pdfDocument = + new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.DrawingMLFallback.pdf"); + + ImagePlacementAbsorber imagePlacementAbsorber = new ImagePlacementAbsorber(); + imagePlacementAbsorber.visit(pdfDocument.getPages().get_Item(1)); + + TableAbsorber tableAbsorber = new TableAbsorber(); + tableAbsorber.visit(pdfDocument.getPages().get_Item(1)); + + switch (dmlRenderingMode) { + case DmlRenderingMode.DRAWING_ML: + Assert.assertEquals(6, tableAbsorber.getTableList().size()); + break; + case DmlRenderingMode.FALLBACK: + Assert.assertEquals(12, tableAbsorber.getTableList().size()); + break; + } + + pdfDocument.close(); + } + + @DataProvider(name = "drawingMLFallbackDataProvider") + public static Object[][] drawingMLFallbackDataProvider() { + return new Object[][] + { + {DmlRenderingMode.FALLBACK}, + {DmlRenderingMode.DRAWING_ML}, + }; + } + + @Test(dataProvider = "exportDocumentStructureDataProvider") + public void exportDocumentStructure(boolean exportDocumentStructure) throws Exception { + //ExStart + //ExFor:PdfSaveOptions.ExportDocumentStructure + //ExSummary:Shows how to preserve document structure elements, which can assist in programmatically interpreting our document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 1")); + builder.writeln("Hello world!"); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Normal")); + builder.write( + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "ExportDocumentStructure" property to "true" to make the document structure, such tags, available via the + // "Content" navigation pane of Adobe Acrobat at the cost of increased file size. + // Set the "ExportDocumentStructure" property to "false" to not export the document structure. + options.setExportDocumentStructure(exportDocumentStructure); + + // Suppose we export document structure while saving this document. In that case, + // we can open it using Adobe Acrobat and find tags for elements such as the heading + // and the next paragraph via "View" -> "Show/Hide" -> "Navigation panes" -> "Tags". + doc.save(getArtifactsDir() + "PdfSaveOptions.ExportDocumentStructure.pdf", options); + //ExEnd + + if (exportDocumentStructure) + { + TestUtil.fileContainsString("<>/ExtGState<>>>/Group<>/StructParents 0/Tabs/S>>", + getArtifactsDir() + "PdfSaveOptions.ExportDocumentStructure.pdf"); + } + else + { + TestUtil.fileContainsString("<>>>/Group<>>>", + getArtifactsDir() + "PdfSaveOptions.ExportDocumentStructure.pdf"); + } + } + + @DataProvider(name = "exportDocumentStructureDataProvider") + public static Object[][] exportDocumentStructureDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "preblendImagesDataProvider") + public void preblendImages(boolean preblendImages) throws Exception { + //ExStart + //ExFor:PdfSaveOptions.PreblendImages + //ExSummary:Shows how to preblend images with transparent backgrounds while saving a document to PDF. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertImage(getImageDir() + "Transparent background logo.png"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "PreblendImages" property to "true" to preblend transparent images + // with a background, which may reduce artifacts. + // Set the "PreblendImages" property to "false" to render transparent images normally. + options.setPreblendImages(preblendImages); + + doc.save(getArtifactsDir() + "PdfSaveOptions.PreblendImages.pdf", options); + //ExEnd + } + + @DataProvider(name = "preblendImagesDataProvider") + public static Object[][] preblendImagesDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "interpolateImagesDataProvider") + public void interpolateImages(boolean interpolateImages) throws Exception { + //ExStart + //ExFor:PdfSaveOptions.InterpolateImages + //ExSummary:Shows how to perform interpolation on images while saving a document to PDF. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + BufferedImage img = ImageIO.read(new File(getImageDir() + "Transparent background logo.png")); + builder.insertImage(img); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + + // Set the "InterpolateImages" property to "true" to get the reader that opens this document to interpolate images. + // Their resolution should be lower than that of the device that is displaying the document. + // Set the "InterpolateImages" property to "false" to make it so that the reader does not apply any interpolation. + saveOptions.setInterpolateImages(interpolateImages); + + // When we open this document with a reader such as Adobe Acrobat, we will need to zoom in on the image + // to see the interpolation effect if we saved the document with it enabled. + doc.save(getArtifactsDir() + "PdfSaveOptions.InterpolateImages.pdf", saveOptions); + //ExEnd + + if (interpolateImages) + { + TestUtil.fileContainsString("<>", + getArtifactsDir() + "PdfSaveOptions.InterpolateImages.pdf"); + } + else + { + TestUtil.fileContainsString("<>", + getArtifactsDir() + "PdfSaveOptions.InterpolateImages.pdf"); + } + } + + @DataProvider(name = "interpolateImagesDataProvider") + public static Object[][] interpolateImagesDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(groups = "SkipMono") + public void dml3DEffectsRenderingModeTest() throws Exception { + //ExStart + //ExFor:Dml3DEffectsRenderingMode + //ExFor:SaveOptions.Dml3DEffectsRenderingMode + //ExSummary:Shows how 3D effects are rendered. + Document doc = new Document(getMyDir() + "DrawingML shape 3D effects.docx"); + + RenderCallback warningCallback = new RenderCallback(); + doc.setWarningCallback(warningCallback); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setDml3DEffectsRenderingMode(Dml3DEffectsRenderingMode.ADVANCED); + + doc.save(getArtifactsDir() + "PdfSaveOptions.Dml3DEffectsRenderingModeTest.pdf", saveOptions); + //ExEnd + + Assert.assertEquals(38, warningCallback.getCount()); + } + + public static class RenderCallback implements IWarningCallback { + public void warning(WarningInfo info) { + System.out.println(MessageFormat.format("{0}: {1}.", info.getWarningType(), info.getDescription())); + mWarnings.add(info); + } + + public int getCount() { + return mWarnings.size(); + } + + private final ArrayList mWarnings = new ArrayList<>(); + } + + + @Test + public void pdfDigitalSignature() throws Exception { + //ExStart + //ExFor:PdfDigitalSignatureDetails + //ExFor:PdfDigitalSignatureDetails.#ctor + //ExFor:PdfDigitalSignatureDetails.#ctor(CertificateHolder, String, String, DateTime) + //ExFor:PdfDigitalSignatureDetails.HashAlgorithm + //ExFor:PdfDigitalSignatureDetails.Location + //ExFor:PdfDigitalSignatureDetails.Reason + //ExFor:PdfDigitalSignatureDetails.SignatureDate + //ExFor:PdfDigitalSignatureHashAlgorithm + //ExFor:PdfSaveOptions.DigitalSignatureDetails + //ExFor:PdfDigitalSignatureDetails.CertificateHolder + //ExSummary:Shows how to sign a generated PDF document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Contents of signed PDF."); + + CertificateHolder certificateHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Configure the "DigitalSignatureDetails" object of the "SaveOptions" object to + // digitally sign the document as we render it with the "Save" method. + Calendar calendar = Calendar.getInstance(); + calendar.set(2015, Calendar.JULY, 20); + Date signingTime = calendar.getTime(); + options.setDigitalSignatureDetails(new PdfDigitalSignatureDetails(certificateHolder, "Test Signing", "My Office", signingTime)); + options.getDigitalSignatureDetails().setHashAlgorithm(PdfDigitalSignatureHashAlgorithm.RIPE_MD_160); + + Assert.assertEquals(options.getDigitalSignatureDetails().getReason(), "Test Signing"); + Assert.assertEquals(options.getDigitalSignatureDetails().getLocation(), "My Office"); + Assert.assertEquals(DocumentHelper.getLocalDate(options.getDigitalSignatureDetails().getSignatureDate()), DocumentHelper.getLocalDate(signingTime)); + + doc.save(getArtifactsDir() + "PdfSaveOptions.PdfDigitalSignature.pdf", options); + //ExEnd + + Assert.assertFalse(FileFormatUtil.detectFileFormat(getArtifactsDir() + "PdfSaveOptions.PdfDigitalSignature.pdf") + .hasDigitalSignature()); + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.PdfDigitalSignature.pdf"); + + Assert.assertTrue(pdfDocument.getForm().getSignaturesExist()); + + SignatureField signatureField = (SignatureField) pdfDocument.getForm().get(1); + + Assert.assertEquals("AsposeDigitalSignature", signatureField.getFullName()); + Assert.assertEquals("AsposeDigitalSignature", signatureField.getPartialName()); + Assert.assertEquals(com.aspose.pdf.PKCS7Detached.class.getName(), signatureField.getSignature().getClass().getName()); + Assert.assertEquals(DocumentHelper.getLocalDate(signatureField.getSignature().getDate()), DocumentHelper.getLocalDate(signingTime)); + Assert.assertEquals("þÿ\u0000M\u0000o\u0000r\u0000z\0a\u0000l\u0000.\u0000M\0e", signatureField.getSignature().getAuthority()); + Assert.assertEquals("þÿ\u0000M\u0000y\u0000 \u0000O\0f\0f\u0000i\0c\0e", signatureField.getSignature().getLocation()); + Assert.assertEquals("þÿ\u0000T\0e\u0000s\u0000t\u0000 \u0000S\u0000i\u0000g\u0000n\u0000i\u0000n\u0000g", signatureField.getSignature().getReason()); + + pdfDocument.close(); + } + + @Test + public void pdfDigitalSignatureTimestamp() throws Exception { + //ExStart + //ExFor:PdfDigitalSignatureDetails.TimestampSettings + //ExFor:PdfDigitalSignatureTimestampSettings + //ExFor:PdfDigitalSignatureTimestampSettings.#ctor + //ExFor:PdfDigitalSignatureTimestampSettings.#ctor(String,String,String) + //ExFor:PdfDigitalSignatureTimestampSettings.#ctor(String,String,String,TimeSpan) + //ExFor:PdfDigitalSignatureTimestampSettings.Password + //ExFor:PdfDigitalSignatureTimestampSettings.ServerUrl + //ExFor:PdfDigitalSignatureTimestampSettings.Timeout + //ExFor:PdfDigitalSignatureTimestampSettings.UserName + //ExSummary:Shows how to sign a saved PDF document digitally and timestamp it. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Signed PDF contents."); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Create a digital signature and assign it to our SaveOptions object to sign the document when we save it to PDF. + CertificateHolder certificateHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + options.setDigitalSignatureDetails(new PdfDigitalSignatureDetails(certificateHolder, "Test Signing", "Aspose Office", new Date())); + + // Create a timestamp authority-verified timestamp. + options.getDigitalSignatureDetails().setTimestampSettings(new PdfDigitalSignatureTimestampSettings("https://freetsa.org/tsr", "JohnDoe", "MyPassword")); + + // The default lifespan of the timestamp is 100 seconds. + Assert.assertEquals(options.getDigitalSignatureDetails().getTimestampSettings().getTimeout(), 100000); + + // We can set our own timeout period via the constructor. + options.getDigitalSignatureDetails().setTimestampSettings(new PdfDigitalSignatureTimestampSettings("https://freetsa.org/tsr", "JohnDoe", "MyPassword", (long) 1800.0)); + + Assert.assertEquals(options.getDigitalSignatureDetails().getTimestampSettings().getTimeout(), 1800); + Assert.assertEquals(options.getDigitalSignatureDetails().getTimestampSettings().getServerUrl(), "https://freetsa.org/tsr"); + Assert.assertEquals(options.getDigitalSignatureDetails().getTimestampSettings().getUserName(), "JohnDoe"); + Assert.assertEquals(options.getDigitalSignatureDetails().getTimestampSettings().getPassword(), "MyPassword"); + + // The "Save" method will apply our signature to the output document at this time. + doc.save(getArtifactsDir() + "PdfSaveOptions.PdfDigitalSignatureTimestamp.pdf", options); + //ExEnd + + Assert.assertFalse(FileFormatUtil.detectFileFormat(getArtifactsDir() + "PdfSaveOptions.PdfDigitalSignatureTimestamp.pdf").hasDigitalSignature()); + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.PdfDigitalSignatureTimestamp.pdf"); + + Assert.assertTrue(pdfDocument.getForm().getSignaturesExist()); + + SignatureField signatureField = (SignatureField) pdfDocument.getForm().get(1); + + Assert.assertEquals("AsposeDigitalSignature", signatureField.getFullName()); + Assert.assertEquals("AsposeDigitalSignature", signatureField.getPartialName()); + Assert.assertEquals(com.aspose.pdf.PKCS7Detached.class.getName(), signatureField.getSignature().getClass().getName()); + Assert.assertEquals("þÿ\u0000M\u0000o\u0000r\u0000z\0a\u0000l\u0000.\u0000M\0e", signatureField.getSignature().getAuthority()); + Assert.assertEquals("þÿ\0A\u0000s\u0000p\u0000o\u0000s\0e\u0000 \u0000O\0f\0f\u0000i\0c\0e", signatureField.getSignature().getLocation()); + Assert.assertEquals("þÿ\u0000T\0e\u0000s\u0000t\u0000 \u0000S\u0000i\u0000g\u0000n\u0000i\u0000n\u0000g", signatureField.getSignature().getReason()); + Assert.assertTrue(signatureField.getSignature().getTimestampSettings() == null); + + pdfDocument.close(); + } + + @Test(dataProvider = "renderMetafileDataProvider") + public void renderMetafile(int renderingMode) throws Exception { + //ExStart + //ExFor:EmfPlusDualRenderingMode + //ExFor:MetafileRenderingOptions.EmfPlusDualRenderingMode + //ExFor:MetafileRenderingOptions.UseEmfEmbeddedToWmf + //ExSummary:Shows how to configure Enhanced Windows Metafile-related rendering options when saving to PDF. + Document doc = new Document(getMyDir() + "EMF.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + + // Set the "EmfPlusDualRenderingMode" property to "EmfPlusDualRenderingMode.Emf" + // to only render the EMF part of an EMF+ dual metafile. + // Set the "EmfPlusDualRenderingMode" property to "EmfPlusDualRenderingMode.EmfPlus" to + // to render the EMF+ part of an EMF+ dual metafile. + // Set the "EmfPlusDualRenderingMode" property to "EmfPlusDualRenderingMode.EmfPlusWithFallback" + // to render the EMF+ part of an EMF+ dual metafile if all of the EMF+ records are supported. + // Otherwise, Aspose.Words will render the EMF part. + saveOptions.getMetafileRenderingOptions().setEmfPlusDualRenderingMode(renderingMode); + + // Set the "UseEmfEmbeddedToWmf" property to "true" to render embedded EMF data + // for metafiles that we can render as vector graphics. + saveOptions.getMetafileRenderingOptions().setUseEmfEmbeddedToWmf(true); + + doc.save(getArtifactsDir() + "PdfSaveOptions.RenderMetafile.pdf", saveOptions); + //ExEnd + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.RenderMetafile.pdf"); + + switch (renderingMode) { + case EmfPlusDualRenderingMode.EMF: + case EmfPlusDualRenderingMode.EMF_PLUS_WITH_FALLBACK: + case EmfPlusDualRenderingMode.EMF_PLUS: + Assert.assertEquals(0, pdfDocument.getPages().get_Item(1).getResources().getImages().size()); + TestUtil.fileContainsString("<>>>/Group<>>>", + getArtifactsDir() + "PdfSaveOptions.RenderMetafile.pdf"); + break; + } + + pdfDocument.close(); + } + + @DataProvider(name = "renderMetafileDataProvider") + public static Object[][] renderMetafileDataProvider() { + return new Object[][] + { + {EmfPlusDualRenderingMode.EMF}, + {EmfPlusDualRenderingMode.EMF_PLUS}, + {EmfPlusDualRenderingMode.EMF_PLUS_WITH_FALLBACK}, + }; + } + + @Test + public void encryptionPermissions() throws Exception { + //ExStart + //ExFor:PdfEncryptionDetails.#ctor(String,String,PdfPermissions) + //ExFor:PdfSaveOptions.EncryptionDetails + //ExFor:PdfEncryptionDetails.Permissions + //ExFor:PdfEncryptionDetails.OwnerPassword + //ExFor:PdfEncryptionDetails.UserPassword + //ExFor:PdfPermissions + //ExFor:PdfEncryptionDetails + //ExSummary:Shows how to set permissions on a saved PDF document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + + // Extend permissions to allow the editing of annotations. + PdfEncryptionDetails encryptionDetails = + new PdfEncryptionDetails("password", "", PdfPermissions.MODIFY_ANNOTATIONS | PdfPermissions.DOCUMENT_ASSEMBLY); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + + // Enable encryption via the "EncryptionDetails" property. + saveOptions.setEncryptionDetails(encryptionDetails); + + // When we open this document, we will need to provide the password before accessing its contents. + doc.save(getArtifactsDir() + "PdfSaveOptions.EncryptionPermissions.pdf", saveOptions); + //ExEnd + + Assert.assertThrows(InvalidPasswordException.class, () -> new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.EncryptionPermissions.pdf")); + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.EncryptionPermissions.pdf", "password"); + TextFragmentAbsorber textAbsorber = new TextFragmentAbsorber(); + + pdfDocument.getPages().get_Item(1).accept(textAbsorber); + + Assert.assertEquals("Hello world!", textAbsorber.getText()); + + pdfDocument.close(); + } + + @Test(dataProvider = "setNumeralFormatDataProvider") + public void setNumeralFormat(/*NumeralFormat*/int numeralFormat) throws Exception { + //ExStart + //ExFor:FixedPageSaveOptions.NumeralFormat + //ExFor:NumeralFormat + //ExSummary:Shows how to set the numeral format used when saving to PDF. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setLocaleId(1025); + builder.writeln("1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 50, 100"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "NumeralFormat" property to "NumeralFormat.ArabicIndic" to + // use glyphs from the U+0660 to U+0669 range as numbers. + // Set the "NumeralFormat" property to "NumeralFormat.Context" to + // look up the locale to determine what number of glyphs to use. + // Set the "NumeralFormat" property to "NumeralFormat.EasternArabicIndic" to + // use glyphs from the U+06F0 to U+06F9 range as numbers. + // Set the "NumeralFormat" property to "NumeralFormat.European" to use european numerals. + // Set the "NumeralFormat" property to "NumeralFormat.System" to determine the symbol set from regional settings. + options.setNumeralFormat(numeralFormat); + + doc.save(getArtifactsDir() + "PdfSaveOptions.SetNumeralFormat.pdf", options); + //ExEnd + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.SetNumeralFormat.pdf"); + TextFragmentAbsorber textAbsorber = new TextFragmentAbsorber(); + + pdfDocument.getPages().get_Item(1).accept(textAbsorber); + + switch (numeralFormat) { + case NumeralFormat.EUROPEAN: + Assert.assertEquals("1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 50, 100", textAbsorber.getText()); + break; + case NumeralFormat.ARABIC_INDIC: + Assert.assertEquals(", ٢, ٣, ٤, ٥, ٦, ٧, ٨, ٩, ١٠, ٥٠, ١١٠٠", textAbsorber.getText()); + break; + case NumeralFormat.EASTERN_ARABIC_INDIC: + Assert.assertEquals("۱۰۰ ,۵۰ ,۱۰ ,۹ ,۸ ,۷ ,۶ ,۵ ,۴ ,۳ ,۲ ,۱", textAbsorber.getText()); + break; + } + + pdfDocument.close(); + } + + @DataProvider(name = "setNumeralFormatDataProvider") + public static Object[][] setNumeralFormatDataProvider() { + return new Object[][] + { + {NumeralFormat.ARABIC_INDIC}, + {NumeralFormat.CONTEXT}, + {NumeralFormat.EASTERN_ARABIC_INDIC}, + {NumeralFormat.EUROPEAN}, + {NumeralFormat.SYSTEM}, + }; + } + + @Test + public void exportPageSet() throws Exception { + //ExStart + //ExFor:FixedPageSaveOptions.PageSet + //ExFor:PageSet.All + //ExFor:PageSet.Even + //ExFor:PageSet.Odd + //ExSummary:Shows how to export Odd pages from the document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + for (int i = 0; i < 5; i++) { + builder.writeln(MessageFormat.format("Page {0} ({1})", i + 1, (i % 2 == 0 ? "odd" : "even"))); + if (i < 4) + builder.insertBreak(BreakType.PAGE_BREAK); + } + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Below are three PageSet properties that we can use to filter out a set of pages from + // our document to save in an output PDF document based on the parity of their page numbers. + // 1 - Save only the even-numbered pages: + options.setPageSet(PageSet.getEven()); + + doc.save(getArtifactsDir() + "PdfSaveOptions.ExportPageSet.Even.pdf", options); + + // 2 - Save only the odd-numbered pages: + options.setPageSet(PageSet.getOdd()); + + doc.save(getArtifactsDir() + "PdfSaveOptions.ExportPageSet.Odd.pdf", options); + + // 3 - Save every page: + options.setPageSet(PageSet.getAll()); + + doc.save(getArtifactsDir() + "PdfSaveOptions.ExportPageSet.All.pdf", options); + //ExEnd + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.ExportPageSet.Even.pdf"); + TextAbsorber textAbsorber = new TextAbsorber(); + pdfDocument.getPages().accept(textAbsorber); + + Assert.assertEquals("Page 2 (even)\r\n" + + "Page 4 (even)", textAbsorber.getText()); + + pdfDocument.close(); + + pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.ExportPageSet.Odd.pdf"); + textAbsorber = new TextAbsorber(); + pdfDocument.getPages().accept(textAbsorber); + + Assert.assertEquals("Page 1 (odd)\r\n" + + "Page 3 (odd)\r\n" + + "Page 5 (odd)", textAbsorber.getText()); + + pdfDocument.close(); + + pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.ExportPageSet.All.pdf"); + textAbsorber = new TextAbsorber(); + pdfDocument.getPages().accept(textAbsorber); + + Assert.assertEquals("Page 1 (odd)\r\n" + + "Page 2 (even)\r\n" + + "Page 3 (odd)\r\n" + + "Page 4 (even)\r\n" + + "Page 5 (odd)", textAbsorber.getText()); + + pdfDocument.close(); + } + + @Test + public void exportLanguageToSpanTag() throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.ExportLanguageToSpanTag + //ExSummary:Shows how to create a "Span" tag in the document structure to export the text language. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + builder.writeln("Hola mundo!"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + { + // Note, when "ExportDocumentStructure" is false, "ExportLanguageToSpanTag" is ignored. + saveOptions.setExportDocumentStructure(true); saveOptions.setExportLanguageToSpanTag(true); + } + + doc.save(getArtifactsDir() + "PdfSaveOptions.ExportLanguageToSpanTag.pdf", saveOptions); + //ExEnd + } + + @Test + public void attachmentsEmbeddingMode() throws Exception + { + //ExStart:AttachmentsEmbeddingMode + //GistId:3c52d1e8d47af34d5026f3a951027f59 + //ExFor:PdfSaveOptions.AttachmentsEmbeddingMode + //ExSummary:Shows how to set a value determining how attachments are embedded to the PDF document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertOleObject(getMyDir() + "Spreadsheet.xlsx", "Excel.Sheet", false, true, null); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setAttachmentsEmbeddingMode(PdfAttachmentsEmbeddingMode.ANNOTATIONS); + + doc.save(getArtifactsDir() + "PdfSaveOptions.AttachmentsEmbeddingMode.pdf", saveOptions); + //ExEnd:AttachmentsEmbeddingMode + } + + @Test + public void cacheBackgroundGraphics() throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.CacheBackgroundGraphics + //ExSummary:Shows how to cache graphics placed in document's background. + Document doc = new Document(getMyDir() + "Background images.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setCacheBackgroundGraphics(true); + + doc.save(getArtifactsDir() + "PdfSaveOptions.CacheBackgroundGraphics.pdf", saveOptions); + + long asposeToPdfSize = new File(getArtifactsDir() + "PdfSaveOptions.CacheBackgroundGraphics.pdf").length(); + long wordToPdfSize = new File(getMyDir() + "Background images (word to pdf).pdf").length(); + + Assert.assertTrue(asposeToPdfSize < wordToPdfSize); + //ExEnd + } + + @Test + public void exportParagraphGraphicsToArtifact() throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.ExportParagraphGraphicsToArtifact + //ExSummary:Shows how to export paragraph graphics as artifact (underlines, text emphasis, etc.). + Document doc = new Document(getMyDir() + "PDF artifacts.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setExportDocumentStructure(true); + saveOptions.setExportParagraphGraphicsToArtifact(true); + saveOptions.setTextCompression(PdfTextCompression.NONE); + + doc.save(getArtifactsDir() + "PdfSaveOptions.ExportParagraphGraphicsToArtifact.pdf", saveOptions); + //ExEnd + + com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(getArtifactsDir() + "PdfSaveOptions.ExportParagraphGraphicsToArtifact.pdf"); + Assert.assertEquals(3, pdfDocument.getPages().get_Item(1).getArtifacts().size()); + pdfDocument.close(); + } + + @Test + public void pageLayout() throws Exception + { + //ExStart:PageLayout + //GistId:f0964b777330b758f6b82330b040b24c + //ExFor:PdfSaveOptions.PageLayout + //ExFor:PdfPageLayout + //ExSummary:Shows how to display pages when opened in a PDF reader. + Document doc = new Document(getMyDir() + "Big document.docx"); + + // Display the pages two at a time, with odd-numbered pages on the left. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setPageLayout(PdfPageLayout.TWO_PAGE_LEFT); + + doc.save(getArtifactsDir() + "PdfSaveOptions.PageLayout.pdf", saveOptions); + //ExEnd:PageLayout + } + + @Test + public void sdtTagAsFormFieldName() throws Exception + { + //ExStart:SdtTagAsFormFieldName + //GistId:0ede368e82d1e97d02e615a76923846b + //ExFor:PdfSaveOptions.UseSdtTagAsFormFieldName + //ExSummary:Shows how to use SDT control Tag or Id property as a name of form field in PDF. + Document doc = new Document(getMyDir() + "Form fields.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setPreserveFormFields(true); + // When set to 'false', SDT control Id property is used as a name of form field in PDF. + // When set to 'true', SDT control Tag property is used as a name of form field in PDF. + saveOptions.setUseSdtTagAsFormFieldName(true); + + doc.save(getArtifactsDir() + "PdfSaveOptions.SdtTagAsFormFieldName.pdf", saveOptions); + //ExEnd:SdtTagAsFormFieldName + } + + @Test + public void renderChoiceFormFieldBorder() throws Exception + { + //ExStart:RenderChoiceFormFieldBorder + //GistId:72d57eeddb7fb342fd51b26e5fcf9642 + //ExFor:PdfSaveOptions.RenderChoiceFormFieldBorder + //ExSummary:Shows how to render PDF choice form field border. + Document doc = new Document(getMyDir() + "Legacy drop-down.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setPreserveFormFields(true); + saveOptions.setRenderChoiceFormFieldBorder(true); + + doc.save(getArtifactsDir() + "PdfSaveOptions.RenderChoiceFormFieldBorder.pdf", saveOptions); + //ExEnd:RenderChoiceFormFieldBorder + } +} \ No newline at end of file diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExPlainTextDocument.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExPlainTextDocument.java new file mode 100644 index 00000000..ca289527 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExPlainTextDocument.java @@ -0,0 +1,145 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.io.FileInputStream; + +public class ExPlainTextDocument extends ApiExampleBase { + @Test + public void load() throws Exception { + //ExStart + //ExFor:PlainTextDocument + //ExFor:PlainTextDocument.#ctor(String) + //ExFor:PlainTextDocument.Text + //ExSummary:Shows how to load the contents of a Microsoft Word document in plaintext. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + doc.save(getArtifactsDir() + "PlainTextDocument.Load.docx"); + + PlainTextDocument plaintext = new PlainTextDocument(getArtifactsDir() + "PlainTextDocument.Load.docx"); + + Assert.assertEquals("Hello world!", plaintext.getText().trim()); + //ExEnd + } + + @Test + public void loadFromStream() throws Exception { + //ExStart + //ExFor:PlainTextDocument.#ctor(Stream) + //ExSummary:Shows how to load the contents of a Microsoft Word document in plaintext using stream. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + doc.save(getArtifactsDir() + "PlainTextDocument.LoadFromStream.docx"); + + try (FileInputStream stream = new FileInputStream(getArtifactsDir() + "PlainTextDocument.LoadFromStream.docx")) { + PlainTextDocument plaintext = new PlainTextDocument(stream); + + Assert.assertEquals("Hello world!", plaintext.getText().trim()); + } + //ExEnd + } + + @Test + public void loadEncrypted() throws Exception { + //ExStart + //ExFor:PlainTextDocument.#ctor(String, LoadOptions) + //ExSummary:Shows how to load the contents of an encrypted Microsoft Word document in plaintext. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + saveOptions.setPassword("MyPassword"); + + doc.save(getArtifactsDir() + "PlainTextDocument.LoadEncrypted.docx", saveOptions); + + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setPassword("MyPassword"); + + PlainTextDocument plaintext = new PlainTextDocument(getArtifactsDir() + "PlainTextDocument.LoadEncrypted.docx", loadOptions); + + Assert.assertEquals("Hello world!", plaintext.getText().trim()); + //ExEnd + } + + @Test + public void loadEncryptedUsingStream() throws Exception { + //ExStart + //ExFor:PlainTextDocument.#ctor(Stream, LoadOptions) + //ExSummary:Shows how to load the contents of an encrypted Microsoft Word document in plaintext using stream. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + saveOptions.setPassword("MyPassword"); + + doc.save(getArtifactsDir() + "PlainTextDocument.LoadFromStreamWithOptions.docx", saveOptions); + + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setPassword("MyPassword"); + + try (FileInputStream stream = new FileInputStream(getArtifactsDir() + "PlainTextDocument.LoadFromStreamWithOptions.docx")) { + PlainTextDocument plaintext = new PlainTextDocument(stream, loadOptions); + + Assert.assertEquals("Hello world!", plaintext.getText().trim()); + } + //ExEnd + } + + @Test + public void builtInProperties() throws Exception { + //ExStart + //ExFor:PlainTextDocument.BuiltInDocumentProperties + //ExSummary:Shows how to load the contents of a Microsoft Word document in plaintext and then access the original document's built-in properties. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + doc.getBuiltInDocumentProperties().setAuthor("John Doe"); + + doc.save(getArtifactsDir() + "PlainTextDocument.BuiltInProperties.docx"); + + PlainTextDocument plaintext = new PlainTextDocument(getArtifactsDir() + "PlainTextDocument.BuiltInProperties.docx"); + + Assert.assertEquals("Hello world!", plaintext.getText().trim()); + Assert.assertEquals("John Doe", plaintext.getBuiltInDocumentProperties().getAuthor()); + //ExEnd + } + + @Test + public void customDocumentProperties() throws Exception { + //ExStart + //ExFor:PlainTextDocument.CustomDocumentProperties + //ExSummary:Shows how to load the contents of a Microsoft Word document in plaintext and then access the original document's custom properties. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + doc.getCustomDocumentProperties().add("Location of writing", "123 Main St, London, UK"); + + doc.save(getArtifactsDir() + "PlainTextDocument.CustomDocumentProperties.docx"); + + PlainTextDocument plaintext = new PlainTextDocument(getArtifactsDir() + "PlainTextDocument.CustomDocumentProperties.docx"); + + Assert.assertEquals("Hello world!", plaintext.getText().trim()); + Assert.assertEquals("123 Main St, London, UK", plaintext.getCustomDocumentProperties().get("Location of writing").getValue()); + //ExEnd + } +} + diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExPsSaveOptions.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExPsSaveOptions.java new file mode 100644 index 00000000..f84a24a3 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExPsSaveOptions.java @@ -0,0 +1,57 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +@Test +public class ExPsSaveOptions extends ApiExampleBase { + @Test(dataProvider = "useBookFoldPrintingSettingsDataProvider") + public void useBookFoldPrintingSettings(boolean renderTextAsBookFold) throws Exception { + //ExStart + //ExFor:PsSaveOptions + //ExFor:PsSaveOptions.SaveFormat + //ExFor:PsSaveOptions.UseBookFoldPrintingSettings + //ExSummary:Shows how to save a document to the Postscript format in the form of a book fold. + Document doc = new Document(getMyDir() + "Paragraphs.docx"); + + // Create a "PsSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to PostScript. + // Set the "UseBookFoldPrintingSettings" property to "true" to arrange the contents + // in the output Postscript document in a way that helps us make a booklet out of it. + // Set the "UseBookFoldPrintingSettings" property to "false" to save the document normally. + PsSaveOptions saveOptions = new PsSaveOptions(); + { + saveOptions.setSaveFormat(SaveFormat.PS); + saveOptions.setUseBookFoldPrintingSettings(renderTextAsBookFold); + } + + // If we are rendering the document as a booklet, we must set the "MultiplePages" + // properties of the page setup objects of all sections to "MultiplePagesType.BookFoldPrinting". + for (Section s : doc.getSections()) { + s.getPageSetup().setMultiplePages(MultiplePagesType.BOOK_FOLD_PRINTING); + } + + // Once we print this document on both sides of the pages, we can fold all the pages down the middle at once, + // and the contents will line up in a way that creates a booklet. + doc.save(getArtifactsDir() + "PsSaveOptions.UseBookFoldPrintingSettings.ps", saveOptions); + //ExEnd + } + + @DataProvider(name = "useBookFoldPrintingSettingsDataProvider") + public static Object[][] useBookFoldPrintingSettingsDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExRange.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExRange.java new file mode 100644 index 00000000..366652df --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExRange.java @@ -0,0 +1,927 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.Shape; +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.awt.*; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public class ExRange extends ApiExampleBase { + @Test + public void replace() throws Exception { + //ExStart + //ExFor:Range.Replace(String, String) + //ExSummary:Shows how to perform a find-and-replace text operation on the contents of a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Greetings, _FullName_!"); + + // Perform a find-and-replace operation on our document's contents and verify the number of replacements that took place. + int replacementCount = doc.getRange().replace("_FullName_", "John Doe"); + + Assert.assertEquals(1, replacementCount); + Assert.assertEquals("Greetings, John Doe!", doc.getText().trim()); + //ExEnd + } + + @Test(dataProvider = "replaceMatchCaseDataProvider") + public void replaceMatchCase(boolean matchCase) throws Exception { + //ExStart + //ExFor:Range.Replace(String, String, FindReplaceOptions) + //ExFor:FindReplaceOptions + //ExFor:FindReplaceOptions.MatchCase + //ExSummary:Shows how to toggle case sensitivity when performing a find-and-replace operation. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Ruby bought a ruby necklace."); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Set the "MatchCase" flag to "true" to apply case sensitivity while finding strings to replace. + // Set the "MatchCase" flag to "false" to ignore character case while searching for text to replace. + options.setMatchCase(matchCase); + + doc.getRange().replace("Ruby", "Jade", options); + + Assert.assertEquals(matchCase ? "Jade bought a ruby necklace." : "Jade bought a Jade necklace.", + doc.getText().trim()); + //ExEnd + } + + @DataProvider(name = "replaceMatchCaseDataProvider") + public static Object[][] replaceMatchCaseDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "replaceFindWholeWordsOnlyDataProvider") + public void replaceFindWholeWordsOnly(boolean findWholeWordsOnly) throws Exception { + //ExStart + //ExFor:Range.Replace(String, String, FindReplaceOptions) + //ExFor:FindReplaceOptions + //ExFor:FindReplaceOptions.FindWholeWordsOnly + //ExSummary:Shows how to toggle standalone word-only find-and-replace operations. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Jackson will meet you in Jacksonville."); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Set the "FindWholeWordsOnly" flag to "true" to replace the found text if it is not a part of another word. + // Set the "FindWholeWordsOnly" flag to "false" to replace all text regardless of its surroundings. + options.setFindWholeWordsOnly(findWholeWordsOnly); + + doc.getRange().replace("Jackson", "Louis", options); + + Assert.assertEquals( + findWholeWordsOnly ? "Louis will meet you in Jacksonville." : "Louis will meet you in Louisville.", + doc.getText().trim()); + //ExEnd + } + + @DataProvider(name = "replaceFindWholeWordsOnlyDataProvider") + public static Object[][] replaceFindWholeWordsOnlyDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "ignoreDeletedDataProvider") + public void ignoreDeleted(boolean ignoreTextInsideDeleteRevisions) throws Exception { + //ExStart + //ExFor:FindReplaceOptions.IgnoreDeleted + //ExSummary:Shows how to include or ignore text inside delete revisions during a find-and-replace operation. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + builder.writeln("Hello again!"); + + // Start tracking revisions and remove the second paragraph, which will create a delete revision. + // That paragraph will persist in the document until we accept the delete revision. + doc.startTrackRevisions("John Doe", new Date()); + doc.getFirstSection().getBody().getParagraphs().get(1).remove(); + doc.stopTrackRevisions(); + + Assert.assertTrue(doc.getFirstSection().getBody().getParagraphs().get(1).isDeleteRevision()); + + // We can use a "FindReplaceOptions" object to modify the find and replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Set the "IgnoreDeleted" flag to "true" to get the find-and-replace + // operation to ignore paragraphs that are delete revisions. + // Set the "IgnoreDeleted" flag to "false" to get the find-and-replace + // operation to also search for text inside delete revisions. + options.setIgnoreDeleted(ignoreTextInsideDeleteRevisions); + + doc.getRange().replace("Hello", "Greetings", options); + + Assert.assertEquals( + ignoreTextInsideDeleteRevisions + ? "Greetings world!\rHello again!" + : "Greetings world!\rGreetings again!", doc.getText().trim()); + //ExEnd + } + + @DataProvider(name = "ignoreDeletedDataProvider") + public static Object[][] ignoreDeletedDataProvider() { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test(dataProvider = "ignoreInsertedDataProvider") + public void ignoreInserted(boolean ignoreTextInsideInsertRevisions) throws Exception { + //ExStart + //ExFor:FindReplaceOptions.IgnoreInserted + //ExSummary:Shows how to include or ignore text inside insert revisions during a find-and-replace operation. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + + // Start tracking revisions and insert a paragraph. That paragraph will be an insert revision. + doc.startTrackRevisions("John Doe", new Date()); + builder.writeln("Hello again!"); + doc.stopTrackRevisions(); + + Assert.assertTrue(doc.getFirstSection().getBody().getParagraphs().get(1).isInsertRevision()); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Set the "IgnoreInserted" flag to "true" to get the find-and-replace + // operation to ignore paragraphs that are insert revisions. + // Set the "IgnoreInserted" flag to "false" to get the find-and-replace + // operation to also search for text inside insert revisions. + options.setIgnoreInserted(ignoreTextInsideInsertRevisions); + + doc.getRange().replace("Hello", "Greetings", options); + + Assert.assertEquals( + ignoreTextInsideInsertRevisions + ? "Greetings world!\rHello again!" + : "Greetings world!\rGreetings again!", doc.getText().trim()); + //ExEnd + } + + @DataProvider(name = "ignoreInsertedDataProvider") + public static Object[][] ignoreInsertedDataProvider() { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test(dataProvider = "ignoreFieldsDataProvider") + public void ignoreFields(boolean ignoreTextInsideFields) throws Exception { + //ExStart + //ExFor:FindReplaceOptions.IgnoreFields + //ExSummary:Shows how to ignore text inside fields. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + builder.insertField("QUOTE", "Hello again!"); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Set the "IgnoreFields" flag to "true" to get the find-and-replace + // operation to ignore text inside fields. + // Set the "IgnoreFields" flag to "false" to get the find-and-replace + // operation to also search for text inside fields. + options.setIgnoreFields(ignoreTextInsideFields); + + doc.getRange().replace("Hello", "Greetings", options); + + Assert.assertEquals( + ignoreTextInsideFields + ? "Greetings world!\r\u0013QUOTE\u0014Hello again!" + : "Greetings world!\r\u0013QUOTE\u0014Greetings again!", doc.getText().trim()); + //ExEnd + } + + @DataProvider(name = "ignoreFieldsDataProvider") + public static Object[][] ignoreFieldsDataProvider() { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test (dataProvider = "ignoreFieldCodesDataProvider") + public void ignoreFieldCodes(boolean ignoreFieldCodes) throws Exception + { + //ExStart + //ExFor:FindReplaceOptions.IgnoreFieldCodes + //ExSummary:Shows how to ignore text inside field codes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField("INCLUDETEXT", "Test IT!"); + + FindReplaceOptions options = new FindReplaceOptions(); {options.setIgnoreFieldCodes(ignoreFieldCodes);} + + // Replace 'T' in document ignoring text inside field code or not. + doc.getRange().replace(Pattern.compile("T"), "*", options); + System.out.println(doc.getText()); + + Assert.assertEquals( + ignoreFieldCodes + ? "INCLUDETEXT\u0014*est I*!" + : "INCLUDE*EX*\u0014*est I*!", doc.getText().trim()); + //ExEnd + } + + @DataProvider(name = "ignoreFieldCodesDataProvider") + public static Object[][] ignoreFieldCodesDataProvider() { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test (dataProvider = "ignoreFootnoteDataProvider") + public void ignoreFootnote(boolean isIgnoreFootnotes) throws Exception { + //ExStart + //ExFor:FindReplaceOptions.IgnoreFootnotes + //ExSummary:Shows how to ignore footnotes during a find-and-replace operation. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + + builder.insertParagraph(); + + builder.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + builder.insertFootnote(FootnoteType.ENDNOTE, "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + + // Set the "IgnoreFootnotes" flag to "true" to get the find-and-replace + // operation to ignore text inside footnotes. + // Set the "IgnoreFootnotes" flag to "false" to get the find-and-replace + // operation to also search for text inside footnotes. + FindReplaceOptions options = new FindReplaceOptions(); + { + options.setIgnoreFootnotes(isIgnoreFootnotes); + } + doc.getRange().replace("Lorem ipsum", "Replaced Lorem ipsum", options); + //ExEnd + + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + for (Paragraph para : paragraphs) { + Assert.assertEquals("Replaced Lorem ipsum", para.getRuns().get(0).getText()); + } + + List footnotes = Arrays.stream(doc.getChildNodes(NodeType.FOOTNOTE, true).toArray()) + .filter(Footnote.class::isInstance) + .map(Footnote.class::cast) + .collect(Collectors.toList()); + + Assert.assertEquals( + isIgnoreFootnotes + ? "Lorem ipsum dolor sit amet, consectetur adipiscing elit." + : "Replaced Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + footnotes.get(0).toString(SaveFormat.TEXT).trim()); + Assert.assertEquals( + isIgnoreFootnotes + ? "Lorem ipsum dolor sit amet, consectetur adipiscing elit." + : "Replaced Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + footnotes.get(1).toString(SaveFormat.TEXT).trim()); + } + + @DataProvider(name = "ignoreFootnoteDataProvider") + public static Object[][] ignoreFootnoteDataProvider() throws Exception + { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test + public void ignoreShapes() throws Exception + { + //ExStart + //ExFor:FindReplaceOptions.IgnoreShapes + //ExSummary:Shows how to ignore shapes while replacing text. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + builder.insertShape(ShapeType.BALLOON, 200.0, 200.0); + builder.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + + FindReplaceOptions findReplaceOptions = new FindReplaceOptions(); { findReplaceOptions.setIgnoreShapes(true); } + builder.getDocument().getRange().replace("Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", findReplaceOptions); + Assert.assertEquals("Lorem ipsum dolor sit amet, consectetur adipiscing elit.", builder.getDocument().getText().trim()); + //ExEnd + } + + @Test + public void updateFieldsInRange() throws Exception + { + //ExStart + //ExFor:Range.UpdateFields + //ExSummary:Shows how to update all the fields in a range. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField(" DOCPROPERTY Category"); + builder.insertBreak(BreakType.SECTION_BREAK_EVEN_PAGE); + builder.insertField(" DOCPROPERTY Category"); + + // The above DOCPROPERTY fields will display the value of this built-in document property. + doc.getBuiltInDocumentProperties().setCategory("MyCategory"); + + // If we update the value of a document property, we will need to update all the DOCPROPERTY fields to display it. + Assert.assertEquals("", doc.getRange().getFields().get(0).getResult()); + Assert.assertEquals("", doc.getRange().getFields().get(1).getResult()); + + // Update all the fields that are in the range of the first section. + doc.getFirstSection().getRange().updateFields(); + + Assert.assertEquals("MyCategory", doc.getRange().getFields().get(0).getResult()); + Assert.assertEquals("", doc.getRange().getFields().get(1).getResult()); + //ExEnd + } + + @Test + public void replaceWithString() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("This one is sad."); + builder.writeln("That one is mad."); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setMatchCase(false); + options.setFindWholeWordsOnly(true); + + doc.getRange().replace("sad", "bad", options); + + doc.save(getArtifactsDir() + "Range.ReplaceWithString.docx"); + } + + @Test + public void replaceWithRegex() throws Exception { + //ExStart + //ExFor:Range.Replace(Regex, String) + //ExSummary:Shows how to replace all occurrences of a regular expression pattern with other text. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("I decided to get the curtains in gray, ideal for the grey-accented room."); + + doc.getRange().replace(Pattern.compile("gr(a|e)y"), "lavender"); + + Assert.assertEquals("I decided to get the curtains in lavender, ideal for the lavender-accented room.", doc.getText().trim()); + //ExEnd + } + + //ExStart + //ExFor:FindReplaceOptions.ReplacingCallback + //ExFor:Range.Replace(Regex, String, FindReplaceOptions) + //ExFor:ReplacingArgs.Replacement + //ExFor:IReplacingCallback + //ExFor:IReplacingCallback.Replacing + //ExFor:ReplacingArgs + //ExSummary:Shows how to replace all occurrences of a regular expression pattern with another string, while tracking all such replacements. + @Test //ExSkip + public void replaceWithCallback() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Our new location in New York City is opening tomorrow. " + + "Hope to see all our NYC-based customers at the opening!"); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Set a callback that tracks any replacements that the "Replace" method will make. + TextFindAndReplacementLogger logger = new TextFindAndReplacementLogger(); + options.setReplacingCallback(logger); + + doc.getRange().replace(Pattern.compile("New York City|NYC"), "Washington", options); + + Assert.assertEquals("Our new location in (Old value:\"New York City\") Washington is opening tomorrow. " + + "Hope to see all our (Old value:\"NYC\") Washington-based customers at the opening!", doc.getText().trim()); + + Assert.assertEquals("\"New York City\" converted to \"Washington\" 20 characters into a 21 node." + + "\"NYC\" converted to \"Washington\" 42 characters into a 21 node.", logger.getLog().trim()); + } + + /// + /// Maintains a log of every text replacement done by a find-and-replace operation + /// and notes the original matched text's value. + /// + private static class TextFindAndReplacementLogger implements IReplacingCallback { + public int replacing(ReplacingArgs args) { + mLog.append(MessageFormat.format("\"{0}\" converted to \"{1}\" {2} characters into a {3} node.", args.getMatch().group(0), args.getReplacement(), args.getMatchOffset(), args.getMatchNode().getNodeType())); + + args.setReplacement(MessageFormat.format("(Old value:\"{0}\") {1}", args.getMatch().group(0), args.getReplacement())); + return ReplaceAction.REPLACE; + } + + public String getLog() { + return mLog.toString(); + } + + private final StringBuilder mLog = new StringBuilder(); + } + //ExEnd + + //ExStart + //ExFor:FindReplaceOptions.ApplyFont + //ExFor:FindReplaceOptions.ReplacingCallback + //ExFor:ReplacingArgs.GroupIndex + //ExFor:ReplacingArgs.GroupName + //ExFor:ReplacingArgs.Match + //ExFor:ReplacingArgs.MatchOffset + //ExSummary:Shows how to apply a different font to new content via FindReplaceOptions. + @Test //ExSkip + public void convertNumbersToHexadecimal() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Arial"); + builder.writeln("Numbers that the find-and-replace operation will convert to hexadecimal and highlight:\n" + + "123, 456, 789 and 17379."); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Set the "HighlightColor" property to a background color that we want to apply to the operation's resulting text. + options.getApplyFont().setHighlightColor(Color.GRAY); + + NumberHexer numberHexer = new NumberHexer(); + options.setReplacingCallback(numberHexer); + + int replacementCount = doc.getRange().replace(Pattern.compile("[0-9]+"), "", options); + + System.out.println(numberHexer.getLog()); + + Assert.assertEquals(4, replacementCount); + Assert.assertEquals("Numbers that the find-and-replace operation will convert to hexadecimal and highlight:\r" + + "0x123, 0x456, 0x789 and 0x17,379.", doc.getText().trim()); + } + + /// + /// Replaces numeric find-and-replacement matches with their hexadecimal equivalents. + /// Maintains a log of every replacement. + /// + private static class NumberHexer implements IReplacingCallback { + public int replacing(ReplacingArgs args) { + mCurrentReplacementNumber++; + + int number = Integer.parseInt(args.getMatch().group(0)); + + args.setReplacement(MessageFormat.format("0x{0}", number)); + + mLog.append(MessageFormat.format("Match #{0}", mCurrentReplacementNumber)); + mLog.append(MessageFormat.format("\tOriginal value:\t{0}", args.getMatch().group(0))); + mLog.append(MessageFormat.format("\tReplacement:\t{0}", args.getReplacement())); + mLog.append(MessageFormat.format("\tOffset in parent {0} node:\t{1}", args.getMatchNode().getNodeType(), args.getMatchOffset())); + + return ReplaceAction.REPLACE; + } + + public String getLog() { + return mLog.toString(); + } + + private int mCurrentReplacementNumber; + private final StringBuilder mLog = new StringBuilder(); + } + //ExEnd + + @Test + public void applyParagraphFormat() throws Exception { + //ExStart + //ExFor:FindReplaceOptions.ApplyParagraphFormat + //ExFor:Range.Replace(String, String) + //ExSummary:Shows how to add formatting to paragraphs in which a find-and-replace operation has found matches. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Every paragraph that ends with a full stop like this one will be right aligned."); + builder.writeln("This one will not!"); + builder.write("This one also will."); + + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + Assert.assertEquals(ParagraphAlignment.LEFT, paragraphs.get(0).getParagraphFormat().getAlignment()); + Assert.assertEquals(ParagraphAlignment.LEFT, paragraphs.get(1).getParagraphFormat().getAlignment()); + Assert.assertEquals(ParagraphAlignment.LEFT, paragraphs.get(2).getParagraphFormat().getAlignment()); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Set the "Alignment" property to "ParagraphAlignment.Right" to right-align every paragraph + // that contains a match that the find-and-replace operation finds. + options.getApplyParagraphFormat().setAlignment(ParagraphAlignment.RIGHT); + + // Replace every full stop that is right before a paragraph break with an exclamation point. + int count = doc.getRange().replace(".&p", "!&p", options); + + Assert.assertEquals(2, count); + Assert.assertEquals(ParagraphAlignment.RIGHT, paragraphs.get(0).getParagraphFormat().getAlignment()); + Assert.assertEquals(ParagraphAlignment.LEFT, paragraphs.get(1).getParagraphFormat().getAlignment()); + Assert.assertEquals(ParagraphAlignment.RIGHT, paragraphs.get(2).getParagraphFormat().getAlignment()); + Assert.assertEquals("Every paragraph that ends with a full stop like this one will be right aligned!\r" + + "This one will not!\r" + + "This one also will!", doc.getText().trim()); + //ExEnd + } + + @Test + public void deleteSelection() throws Exception { + //ExStart + //ExFor:Node.Range + //ExFor:Range.Delete + //ExSummary:Shows how to delete all the nodes from a range. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Add text to the first section in the document, and then add another section. + builder.write("Section 1. "); + builder.insertBreak(BreakType.SECTION_BREAK_CONTINUOUS); + builder.write("Section 2."); + + Assert.assertEquals("Section 1. \fSection 2.", doc.getText().trim()); + + // Remove the first section entirely by removing all the nodes + // within its range, including the section itself. + doc.getSections().get(0).getRange().delete(); + + Assert.assertEquals(1, doc.getSections().getCount()); + Assert.assertEquals("Section 2.", doc.getText().trim()); + //ExEnd + } + + @Test + public void rangesGetText() throws Exception { + //ExStart + //ExFor:Range + //ExFor:Range.Text + //ExSummary:Shows how to get the text contents of all the nodes that a range covers. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Hello world!"); + + Assert.assertEquals("Hello world!", doc.getRange().getText().trim()); + //ExEnd + } + + //ExStart + //ExFor:FindReplaceOptions.UseLegacyOrder + //ExSummary:Shows how to change the searching order of nodes when performing a find-and-replace text operation. + @Test(dataProvider = "useLegacyOrderDataProvider") //ExSkip + public void useLegacyOrder(boolean useLegacyOrder) throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert three runs which we can search for using a regex pattern. + // Place one of those runs inside a text box. + builder.writeln("[tag 1]"); + Shape textBox = builder.insertShape(ShapeType.TEXT_BOX, 100.0, 50.0); + builder.writeln("[tag 2]"); + builder.moveTo(textBox.getFirstParagraph()); + builder.write("[tag 3]"); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Assign a custom callback to the "ReplacingCallback" property. + TextReplacementTracker callback = new TextReplacementTracker(); + options.setReplacingCallback(callback); + + // If we set the "UseLegacyOrder" property to "true", the + // find-and-replace operation will go through all the runs outside of a text box + // before going through the ones inside a text box. + // If we set the "UseLegacyOrder" property to "false", the + // find-and-replace operation will go over all the runs in a range in sequential order. + options.setUseLegacyOrder(useLegacyOrder); + + doc.getRange().replace("\\[tag d*\\]", "", options); + } + + @DataProvider(name = "useLegacyOrderDataProvider") //ExSkip + public static Object[][] useLegacyOrderDataProvider() { + return new Object[][] + { + {true}, + {false}, + }; + } + + /// + /// Records the order of all matches that occur during a find-and-replace operation. + /// + private static class TextReplacementTracker implements IReplacingCallback { + public int replacing(ReplacingArgs e) { + mMatches.add(e.getMatch().group(1)); + return ReplaceAction.REPLACE; + } + + public ArrayList getMatches() { + return mMatches; + } + + private ArrayList mMatches; + } + //ExEnd + + @Test(dataProvider = "useSubstitutionsDataProvider") + public void useSubstitutions(boolean useSubstitutions) throws Exception { + //ExStart + //ExFor:FindReplaceOptions.UseSubstitutions + //ExSummary:Shows how to replace the text with substitutions. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("John sold a car to Paul."); + builder.writeln("Jane sold a house to Joe."); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Set the "UseSubstitutions" property to "true" to get + // the find-and-replace operation to recognize substitution elements. + // Set the "UseSubstitutions" property to "false" to ignore substitution elements. + options.setUseSubstitutions(useSubstitutions); + + doc.getRange().replace(Pattern.compile("([A-z]+) sold a ([A-z]+) to ([A-z]+)"), "$3 bought a $2 from $1", options); + + Assert.assertEquals( + useSubstitutions + ? "Paul bought a car from John.\rJoe bought a house from Jane." + : "$3 bought a $2 from $1.\r$3 bought a $2 from $1.", doc.getText().trim()); + //ExEnd + } + + @DataProvider(name = "useSubstitutionsDataProvider") + public static Object[][] useSubstitutionsDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + //ExStart + //ExFor:Range.Replace(Regex, String, FindReplaceOptions) + //ExFor:IReplacingCallback + //ExFor:ReplaceAction + //ExFor:IReplacingCallback.Replacing + //ExFor:ReplacingArgs + //ExFor:ReplacingArgs.MatchNode + //ExSummary:Shows how to insert an entire document's contents as a replacement of a match in a find-and-replace operation. + @Test //ExSkip + public void insertDocumentAtReplace() throws Exception { + Document mainDoc = new Document(getMyDir() + "Document insertion destination.docx"); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + options.setReplacingCallback(new InsertDocumentAtReplaceHandler()); + + mainDoc.getRange().replace(Pattern.compile("\\[MY_DOCUMENT\\]"), "", options); + mainDoc.save(getArtifactsDir() + "InsertDocument.InsertDocumentAtReplace.docx"); + + testInsertDocumentAtReplace(new Document(getArtifactsDir() + "InsertDocument.InsertDocumentAtReplace.docx")); //ExSkip + } + + private static class InsertDocumentAtReplaceHandler implements IReplacingCallback { + public int replacing(ReplacingArgs args) throws Exception { + Document subDoc = new Document(getMyDir() + "Document.docx"); + + // Insert a document after the paragraph containing the matched text. + Paragraph para = (Paragraph) args.getMatchNode().getParentNode(); + insertDocument(para, subDoc); + + // Remove the paragraph with the matched text. + para.remove(); + + return ReplaceAction.SKIP; + } + } + + /// + /// Inserts all the nodes of another document after a paragraph or table. + /// + private static void insertDocument(Node insertionDestination, Document docToInsert) { + if (((insertionDestination.getNodeType()) == (NodeType.PARAGRAPH)) || ((insertionDestination.getNodeType()) == (NodeType.TABLE))) { + CompositeNode dstStory = insertionDestination.getParentNode(); + + NodeImporter importer = + new NodeImporter(docToInsert, insertionDestination.getDocument(), ImportFormatMode.KEEP_SOURCE_FORMATTING); + + for (Section srcSection : docToInsert.getSections()) + for (Node srcNode : srcSection.getBody()) { + // Skip the node if it is the last empty paragraph in a section. + if (((srcNode.getNodeType()) == (NodeType.PARAGRAPH))) { + Paragraph para = (Paragraph) srcNode; + if (para.isEndOfSection() && !para.hasChildNodes()) + continue; + } + + Node newNode = importer.importNode(srcNode, true); + + dstStory.insertAfter(newNode, insertionDestination); + insertionDestination = newNode; + } + } else { + throw new IllegalArgumentException("The destination node must be either a paragraph or table."); + } + } + //ExEnd + + private void testInsertDocumentAtReplace(Document doc) { + Assert.assertEquals("1) At text that can be identified by regex:\rHello World!\r" + + "2) At a MERGEFIELD:\r\u0013 MERGEFIELD Document_1 \\* MERGEFORMAT \u0014«Document_1»\u0015\r" + + "3) At a bookmark:", doc.getFirstSection().getBody().getText().trim()); + } + + //ExStart + //ExFor:FindReplaceOptions.Direction + //ExFor:FindReplaceDirection + //ExSummary:Shows how to determine which direction a find-and-replace operation traverses the document in. + @Test(dataProvider = "directionDataProvider") //ExSkip + public void direction(int findReplaceDirection) throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert three runs which we can search for using a regex pattern. + // Place one of those runs inside a text box. + builder.writeln("Match 1."); + builder.writeln("Match 2."); + builder.writeln("Match 3."); + builder.writeln("Match 4."); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Assign a custom callback to the "ReplacingCallback" property. + TextReplacementRecorder callback = new TextReplacementRecorder(); + options.setReplacingCallback(callback); + + // Set the "Direction" property to "FindReplaceDirection.Backward" to get the find-and-replace + // operation to start from the end of the range, and traverse back to the beginning. + // Set the "Direction" property to "FindReplaceDirection.Forward" to get the find-and-replace + // operation to start from the beginning of the range, and traverse to the end. + options.setDirection(findReplaceDirection); + + doc.getRange().replace(Pattern.compile("Match \\d*"), "Replacement", options); + + Assert.assertEquals("Replacement.\r" + + "Replacement.\r" + + "Replacement.\r" + + "Replacement.", doc.getText().trim()); + + switch (findReplaceDirection) { + case FindReplaceDirection.FORWARD: + Assert.assertEquals(new String[]{"Match 1", "Match 2", "Match 3", "Match 4"}, callback.getMatches().toArray()); + break; + case FindReplaceDirection.BACKWARD: + Assert.assertEquals(new String[]{"Match 4", "Match 3", "Match 2", "Match 1"}, callback.getMatches().toArray()); + break; + } + } + + @DataProvider(name = "directionDataProvider") //ExSkip + public static Object[][] directionDataProvider() { + return new Object[][] + { + {FindReplaceDirection.BACKWARD}, + {FindReplaceDirection.FORWARD}, + }; + } + + /// + /// Records all matches that occur during a find-and-replace operation in the order that they take place. + /// + private static class TextReplacementRecorder implements IReplacingCallback { + public int replacing(ReplacingArgs e) { + mMatches.add(e.getMatch().group(0)); + return ReplaceAction.REPLACE; + } + + public ArrayList getMatches() { + return mMatches; + } + private ArrayList mMatches = new ArrayList<>(); + } + //ExEnd + + //ExStart:MatchEndNode + //GistId:2af5a850f2e0a83c3b114274a838c092 + //ExFor:ReplacingArgs.MatchEndNode + //ExSummary:Shows how to get match end node. + @Test + public void matchEndNode() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("1"); + builder.writeln("2"); + builder.writeln("3"); + + ReplacingCallback replacingCallback = new ReplacingCallback(); + FindReplaceOptions opts = new FindReplaceOptions(); + opts.setReplacingCallback(replacingCallback); + + doc.getRange().replace(Pattern.compile("1[\\s\\S]*3"), "X", opts); + Assert.assertEquals("1", replacingCallback.getStartNodeText()); + Assert.assertEquals("3", replacingCallback.getEndNodeText()); + } + + /// + /// The replacing callback. + /// + private static class ReplacingCallback implements IReplacingCallback + { + public int replacing(ReplacingArgs e) + { + setStartNodeText(e.getMatchNode().getText().trim()); + setEndNodeText(e.getMatchEndNode().getText().trim()); + + return ReplaceAction.REPLACE; + } + + private String mStartNodeText; + String getStartNodeText() { return mStartNodeText; }; private void setStartNodeText(String value) { mStartNodeText = value; }; + + private String mEndNodeText; + String getEndNodeText() { return mEndNodeText; }; private void setEndNodeText(String value) { mEndNodeText = value; }; + } + //ExEnd:MatchEndNode + + @Test (dataProvider = "ignoreOfficeMathDataProvider") + public void ignoreOfficeMath(boolean isIgnoreOfficeMath) throws Exception + { + //ExStart:IgnoreOfficeMath + //GistId:571cc6e23284a2ec075d15d4c32e3bbf + //ExFor:FindReplaceOptions.IgnoreOfficeMath + //ExSummary:Shows how to find and replace text within OfficeMath. + Document doc = new Document(getMyDir() + "Office math.docx"); + + Assert.assertEquals("i+b-c≥iM+bM-cM", doc.getFirstSection().getBody().getFirstParagraph().getText().trim()); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setIgnoreOfficeMath(isIgnoreOfficeMath); + doc.getRange().replace("b", "x", options); + + if (isIgnoreOfficeMath) + Assert.assertEquals("i+b-c≥iM+bM-cM", doc.getFirstSection().getBody().getFirstParagraph().getText().trim()); + else + Assert.assertEquals("i+x-c≥iM+xM-cM", doc.getFirstSection().getBody().getFirstParagraph().getText().trim()); + //ExEnd:IgnoreOfficeMath + } + + @DataProvider(name = "ignoreOfficeMathDataProvider") + public static Object[][] ignoreOfficeMathDataProvider() { + return new Object[][] + { + {true}, + {false}, + }; + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExRenameMergeFields.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExRenameMergeFields.java new file mode 100644 index 00000000..02bd46d0 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExRenameMergeFields.java @@ -0,0 +1,165 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/// +/// Shows how to rename merge fields in a Word document. +/// +public class ExRenameMergeFields extends ApiExampleBase { + /// + /// Finds all merge fields in a Word document and changes their names. + /// + @Test + public void rename() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Dear "); + builder.insertField("MERGEFIELD FirstName "); + builder.write(" "); + builder.insertField("MERGEFIELD LastName "); + builder.writeln(","); + builder.insertField("MERGEFIELD CustomGreeting "); + + // Select all field start nodes so we can find the MERGEFIELDs. + NodeCollection fieldStarts = doc.getChildNodes(NodeType.FIELD_START, true); + for (FieldStart fieldStart : (Iterable) fieldStarts) { + if (fieldStart.getFieldType() == FieldType.FIELD_MERGE_FIELD) { + MergeField mergeField = new MergeField(fieldStart); + mergeField.setName(mergeField.getName() + "_Renamed"); + } + } + + doc.save(getArtifactsDir() + "RenameMergeFields.Rename.docx"); + } +} + +/** + * Represents a facade object for a merge field in a Microsoft Word document. + */ +class MergeField { + MergeField(final FieldStart fieldStart) { + if (fieldStart.equals(null)) { + throw new IllegalArgumentException("fieldStart"); + } + + if (fieldStart.getFieldType() != FieldType.FIELD_MERGE_FIELD) { + throw new IllegalArgumentException("Field start type must be FieldMergeField."); + } + + mFieldStart = fieldStart; + + // Find the field separator node. + mFieldSeparator = findNextSibling(mFieldStart, NodeType.FIELD_SEPARATOR); + if (mFieldSeparator == null) { + throw new IllegalStateException("Cannot find field separator."); + } + + // Find the field end node. Normally field end will always be found, but in the example document + // there happens to be a paragraph break included in the hyperlink and this puts the field end + // in the next paragraph. It will be much more complicated to handle fields which span several + // paragraphs correctly, but in this case allowing field end to be null is enough for our purposes. + mFieldEnd = findNextSibling(mFieldSeparator, NodeType.FIELD_END); + } + + /** + * Gets or sets the name of the merge field. + */ + String getName() { + String fieldResult = getTextSameParent(mFieldSeparator.getNextSibling(), mFieldEnd); + int startPos = fieldResult.indexOf("«"); + startPos = (startPos >= 0) ? startPos + 1 : 0; + + int endPos = fieldResult.indexOf("»"); + endPos = (endPos >= 0) ? endPos : fieldResult.length(); + + return fieldResult.substring(startPos, endPos); + } + + void setName(final String value) { + // Merge field name is stored in the field result which is a Run + // node between field separator and field end. + Run fieldResult = (Run) mFieldSeparator.getNextSibling(); + fieldResult.setText(java.text.MessageFormat.format("«{0}»", value)); + + // But sometimes the field result can consist of more than one run, delete these runs. + removeSameParent(fieldResult.getNextSibling(), mFieldEnd); + + updateFieldCode(value); + } + + private void updateFieldCode(final String fieldName) { + // Field code is stored in a Run node between field start and field separator. + Run fieldCode = (Run) mFieldStart.getNextSibling(); + Matcher matcher = G_REGEX.matcher(fieldCode.getText()); + + matcher.find(); + + String newFieldCode = java.text.MessageFormat.format(" {0}{1} ", matcher.group(1), fieldName); + fieldCode.setText(newFieldCode); + + // But sometimes the field code can consist of more than one run, delete these runs. + removeSameParent(fieldCode.getNextSibling(), mFieldSeparator); + } + + /** + * Goes through siblings starting from the start node until it finds a node of the specified type or null. + */ + private static Node findNextSibling(final Node startNode, final int nodeType) { + for (Node node = startNode; node != null; node = node.getNextSibling()) { + if (node.getNodeType() == nodeType) return node; + } + return null; + } + + /** + * Retrieves text from start up to but not including the end node. + */ + private static String getTextSameParent(final Node startNode, final Node endNode) { + if ((endNode != null) && (startNode.getParentNode() != endNode.getParentNode())) { + throw new IllegalArgumentException("Start and end nodes are expected to have the same parent."); + } + + StringBuilder builder = new StringBuilder(); + for (Node child = startNode; !child.equals(endNode); child = child.getNextSibling()) { + builder.append(child.getText()); + } + + return builder.toString(); + } + + /** + * Removes nodes from start up to but not including the end node. + * Start and end are assumed to have the same parent. + */ + private static void removeSameParent(final Node startNode, final Node endNode) { + if ((endNode != null) && (startNode.getParentNode() != endNode.getParentNode())) { + throw new IllegalArgumentException("Start and end nodes are expected to have the same parent."); + } + + Node curChild = startNode; + while ((curChild != null) && (curChild != endNode)) { + Node nextChild = curChild.getNextSibling(); + curChild.remove(); + curChild = nextChild; + } + } + + private final Node mFieldStart; + private final Node mFieldSeparator; + private final Node mFieldEnd; + + private static final Pattern G_REGEX = Pattern.compile("\\s*(MERGEFIELD\\s|)(\\s|)(\\S+)\\s+"); +} \ No newline at end of file diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExRendering.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExRendering.java new file mode 100644 index 00000000..5ef5d75e --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExRendering.java @@ -0,0 +1,118 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.ConvertUtil; +import com.aspose.words.Document; +import org.testng.annotations.Test; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.Point2D; +import java.awt.image.BufferedImage; +import java.io.File; + +public class ExRendering extends ApiExampleBase { + @Test + public void renderToSize() throws Exception { + //ExStart + //ExFor:Document.RenderToSize + //ExSummary:Shows how to render a document to a bitmap at a specified location and size. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + BufferedImage img = new BufferedImage(700, 700, BufferedImage.TYPE_INT_ARGB); + // User has some sort of a Graphics object + // In this case created from a bitmap + Graphics2D gr = img.createGraphics(); + try { + // The user can specify any options on the Graphics object including + // transform, antialiasing, page units, etc + gr.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + + // Offset the output 0.5" from the edge. + gr.translate(ConvertUtil.inchToPoint(0.5f), ConvertUtil.inchToPoint(0.5f)); + + // Rotate the output by 10 degrees. + gr.rotate(10.0 * Math.PI / 180.0, img.getWidth() / 2.0, img.getHeight() / 2.0); + + gr.setColor(Color.RED); + + // Draw a 3"x3" rectangle. + gr.drawRect(0, 0, (int) ConvertUtil.inchToPoint(3), (int) ConvertUtil.inchToPoint(3)); + + // Draw the first page of our document with the same dimensions and transformation as the rectangle. + // The rectangle will frame the first page. + float returnedScale = doc.renderToSize(0, gr, 0f, 0f, (float) ConvertUtil.inchToPoint(3), (float) ConvertUtil.inchToPoint(3)); + + ImageIO.write(img, "PNG", new File(getArtifactsDir() + "Rendering.RenderToSize.png")); + } finally { + if (gr != null) { + gr.dispose(); + } + } + //ExEnd + } + + @Test + public void thumbnails() throws Exception { + //ExStart + //ExFor:Document.RenderToScale + //ExSummary:Shows how to the individual pages of a document to graphics to create one image with thumbnails of all pages. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // Calculate the number of rows and columns that we will fill with thumbnails. + final int thumbColumns = 2; + int thumbRows = doc.getPageCount() / thumbColumns; + int remainder = doc.getPageCount() % thumbColumns; + + if (remainder > 0) thumbRows++; + + // Scale the thumbnails relative to the size of the first page. + float scale = 0.25f; + Dimension thumbSize = doc.getPageInfo(0).getSizeInPixels(scale, 96); + + // Calculate the size of the image that will contain all the thumbnails. + int imgWidth = (int) (thumbSize.getWidth() * thumbColumns); + int imgHeight = (int) (thumbSize.getHeight() * thumbRows); + + BufferedImage img = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_ARGB); + Graphics2D gr = img.createGraphics(); + try { + gr.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + + + gr.setColor(Color.white); + // Fill the background, which is transparent by default, in white. + gr.fillRect(0, 0, imgWidth, imgHeight); + + for (int pageIndex = 0; pageIndex < doc.getPageCount(); pageIndex++) { + int rowIdx = pageIndex / thumbColumns; + int columnIdx = pageIndex % thumbColumns; + + // Specify where we want the thumbnail to appear. + float thumbLeft = (float) (columnIdx * thumbSize.getWidth()); + float thumbTop = (float) (rowIdx * thumbSize.getHeight()); + + Point2D.Float size = doc.renderToScale(pageIndex, gr, thumbLeft, thumbTop, scale); + + gr.setColor(Color.black); + + // Render a page as a thumbnail, and then frame it in a rectangle of the same size. + gr.drawRect((int) thumbLeft, (int) thumbTop, (int) size.getX(), (int) size.getY()); + } + + ImageIO.write(img, "PNG", new File(getArtifactsDir() + "Rendering.Thumbnails.png")); + } finally { + if (gr != null) { + gr.dispose(); + } + } + //ExEnd + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExReplaceHyperlinks.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExReplaceHyperlinks.java new file mode 100644 index 00000000..88c18e5e --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExReplaceHyperlinks.java @@ -0,0 +1,199 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +//ExStart +//ExFor:NodeList +//ExFor:FieldStart +//ExSummary:Shows how to find all hyperlinks in a Word document, and then change their URLs and display names. + +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@Test //ExSkip +public class ExReplaceHyperlinks extends ApiExampleBase { + @Test //ExSkip + public void fields() throws Exception { + Document doc = new Document(getMyDir() + "Hyperlinks.docx"); + + // Hyperlinks in a Word documents are fields. To begin looking for hyperlinks, we must first find all the fields. + // Use the "SelectNodes" method to find all the fields in the document via an XPath. + NodeList fieldStarts = doc.selectNodes("//FieldStart"); + for (FieldStart fieldStart : (Iterable) fieldStarts) { + if (fieldStart.getFieldType() == FieldType.FIELD_HYPERLINK) { + Hyperlink hyperlink = new Hyperlink(fieldStart); + + // Hyperlinks that link to bookmarks do not have URLs. + if (hyperlink.isLocal()) continue; + + // Give each URL hyperlink a new URL and name. + hyperlink.setTarget(NEW_URL); + hyperlink.setName(NEW_NAME); + } + } + + doc.save(getArtifactsDir() + "ReplaceHyperlinks.Fields.docx"); + } + + private static final String NEW_URL = "http://www.aspose.com"; + private static final String NEW_NAME = "Aspose - The .NET & Java Component Publisher"; +} + + + +// This "facade" class makes it easier to work with a hyperlink field in a Word document. +//

          +// HYPERLINK fields contain and display hyperlinks in the document body. A field in Aspose.Words +// consists of several nodes, and it might be difficult to work with all those nodes directly. +// This implementation will work only if the hyperlink code and name each consist of only one Run node. +//

          +// The node structure for fields is as follows: +//

          +// [FieldStart][Run - field code][FieldSeparator][Run - field result][FieldEnd] +//

          +// Below are two example field codes of HYPERLINK fields: +// HYPERLINK "url" +// HYPERLINK \l "bookmark name" +//

          +// A field's "Result" property contains text that the field displays in the document body to the user. +class Hyperlink { + Hyperlink(final FieldStart fieldStart) throws Exception { + if (fieldStart == null) { + throw new IllegalArgumentException("fieldStart"); + } + + if (fieldStart.getFieldType() != FieldType.FIELD_HYPERLINK) { + throw new IllegalArgumentException("Field start type must be FieldHyperlink."); + } + + mFieldStart = fieldStart; + + // Find the field separator node. + mFieldSeparator = findNextSibling(mFieldStart, NodeType.FIELD_SEPARATOR); + if (mFieldSeparator == null) { + throw new IllegalStateException("Cannot find field separator."); + } + + // Normally, we can always find the field's end node, but the example document + // contains a paragraph break inside a hyperlink, which puts the field end + // in the next paragraph. It will be much more complicated to handle fields which span several + // paragraphs correctly. In this case allowing field end to be null is enough. + mFieldEnd = findNextSibling(mFieldSeparator, NodeType.FIELD_END); + + // Field code looks something like "HYPERLINK "http:\\www.myurl.com"", but it can consist of several runs. + String fieldCode = getTextSameParent(mFieldStart.getNextSibling(), mFieldSeparator); + Matcher matcher = G_REGEX.matcher(fieldCode.trim()); + matcher.find(); + + // The hyperlink is local if \l is present in the field code. + mIsLocal = (matcher.group(1) != null) && (matcher.group(1).length() > 0); + mTarget = matcher.group(2); + } + + // Gets or sets the display name of the hyperlink. + String getName() throws Exception { + return getTextSameParent(mFieldSeparator, mFieldEnd); + } + + void setName(final String value) throws Exception { + // Hyperlink display name is stored in the field result, which is a Run + // node between field separator and field end. + Run fieldResult = (Run) mFieldSeparator.getNextSibling(); + fieldResult.setText(value); + + // If the field result consists of more than one run, delete these runs. + removeSameParent(fieldResult.getNextSibling(), mFieldEnd); + } + + // Gets or sets the target URL or bookmark name of the hyperlink. + String getTarget() { + return mTarget; + } + + void setTarget(final String value) throws Exception { + mTarget = value; + updateFieldCode(); + } + + // True if the hyperlinks target is a bookmark inside the document. False if the hyperlink is a URL. + boolean isLocal() { + return mIsLocal; + } + + void isLocal(final boolean value) throws Exception { + mIsLocal = value; + updateFieldCode(); + } + + private void updateFieldCode() throws Exception { + // A field's field code is in a Run node between the field's start node and field separator. + Run fieldCode = (Run) mFieldStart.getNextSibling(); + fieldCode.setText(java.text.MessageFormat.format("HYPERLINK {0}\"{1}\"", ((mIsLocal) ? "\\l " : ""), mTarget)); + + // If the field code consists of more than one run, delete these runs. + removeSameParent(fieldCode.getNextSibling(), mFieldSeparator); + } + + // Goes through siblings starting from the start node until it finds a node of the specified type or null. + private static Node findNextSibling(final Node startNode, final int nodeType) { + for (Node node = startNode; node != null; node = node.getNextSibling()) { + if (node.getNodeType() == nodeType) return node; + } + return null; + } + + // Retrieves text from start up to but not including the end node. + private static String getTextSameParent(final Node startNode, final Node endNode) { + if ((endNode != null) && (startNode.getParentNode() != endNode.getParentNode())) { + throw new IllegalArgumentException("Start and end nodes are expected to have the same parent."); + } + + StringBuilder builder = new StringBuilder(); + for (Node child = startNode; !child.equals(endNode); child = child.getNextSibling()) { + builder.append(child.getText()); + } + + return builder.toString(); + } + + // Removes nodes from start up to but not including the end node. + // Assumes that the start and end nodes have the same parent. + private static void removeSameParent(final Node startNode, final Node endNode) { + if ((endNode != null) && (startNode.getParentNode() != endNode.getParentNode())) { + throw new IllegalArgumentException("Start and end nodes are expected to have the same parent."); + } + + Node curChild = startNode; + while ((curChild != null) && (curChild != endNode)) { + Node nextChild = curChild.getNextSibling(); + curChild.remove(); + curChild = nextChild; + } + } + + private final Node mFieldStart; + private final Node mFieldSeparator; + private final Node mFieldEnd; + private boolean mIsLocal; + private String mTarget; + + private static final Pattern G_REGEX = Pattern.compile( + "\\S+" + // One or more non spaces HYPERLINK or other word in other languages. + "\\s+" + // One or more spaces. + "(?:\"\"\\s+)?" + // Non-capturing optional "" and one or more spaces. + "(\\\\l\\s+)?" + // Optional \l flag followed by one or more spaces. + "\"" + // One apostrophe. + "([^\"]+)" + // One or more characters, excluding the apostrophe (hyperlink target). + "\"" // One closing apostrophe. + ); +} +//ExEnd \ No newline at end of file diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExReportingEngine.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExReportingEngine.java new file mode 100644 index 00000000..2921b4ec --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExReportingEngine.java @@ -0,0 +1,1240 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import TestData.Common; +import TestData.TestBuilders.ColorItemTestBuilder; +import TestData.TestBuilders.DocumentTestBuilder; +import TestData.TestBuilders.ImageTestBuilder; +import TestData.TestBuilders.NumericTestBuilder; +import TestData.TestClasses.*; +import com.aspose.words.Shape; +import com.aspose.words.*; +import com.aspose.words.net.System.Data.DataSet; +import org.apache.commons.io.FileUtils; +import org.omg.CORBA.Environment; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.text.MessageFormat; +import java.time.LocalDate; +import java.util.*; +import java.util.List; + +@Test +public class ExReportingEngine extends ApiExampleBase { + private final String mImage = getImageDir() + "Logo.jpg"; + private final String mDocument = getMyDir() + "Reporting engine template - Data table (Java).docx"; + + @Test + public void simpleCase() throws Exception { + Document doc = DocumentHelper.createSimpleDocument("<<[s.getName()]>> says: <<[s.getMessage()]>>"); + + MessageTestClass sender = new MessageTestClass("LINQ Reporting Engine", "Hello World"); + buildReport(doc, sender, "s", ReportBuildOptions.INLINE_ERROR_MESSAGES); + + ByteArrayOutputStream dstStream = new ByteArrayOutputStream(); + doc.save(dstStream, SaveFormat.DOCX); + + Assert.assertEquals(doc.getText(), "LINQ Reporting Engine says: Hello World\f"); + } + + @Test + public void stringFormat() throws Exception { + Document doc = DocumentHelper.createSimpleDocument( + "<<[s.getName()]:lower>> says: <<[s.getMessage()]:upper>>, <<[s.getMessage()]:caps>>, <<[s.getMessage()]:firstCap>>"); + + MessageTestClass sender = new MessageTestClass("LINQ Reporting Engine", "hello world"); + buildReport(doc, sender, "s"); + + ByteArrayOutputStream dstStream = new ByteArrayOutputStream(); + doc.save(dstStream, SaveFormat.DOCX); + + Assert.assertEquals(doc.getText(), "linq reporting engine says: HELLO WORLD, Hello World, Hello world\f"); + } + + @Test + public void numberFormat() throws Exception { + Document doc = DocumentHelper.createSimpleDocument( + "<<[s.getValue1()]:alphabetic>> : <<[s.getValue2()]:roman:lower>>, <<[s.getValue3()]:ordinal>>, <<[s.getValue1()]:ordinalText:upper>>" + + ", <<[s.getValue2()]:cardinal>>, <<[s.getValue3()]:hex>>, <<[s.getValue3()]:arabicDash>>"); + + NumericTestClass sender = new NumericTestBuilder() + .withValuesAndDate(1, 2.2, 200, null, LocalDate.of(2016, 9, 10)).build(); + buildReport(doc, sender, "s"); + + ByteArrayOutputStream dstStream = new ByteArrayOutputStream(); + doc.save(dstStream, SaveFormat.DOCX); + + Assert.assertEquals(doc.getText(), "A : ii, 200th, FIRST, Two, C8, - 200 -\f"); + } + + @Test + public void dataTableTest() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - Data table (Java).docx"); + + buildReport(doc, Common.getContracts(), "Contracts", new Class[]{ContractTestClass.class}); + + doc.save(getArtifactsDir() + "ReportingEngine.TestDataTable.docx"); + } + + @Test + public void progressiveTotal() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - Total (Java).docx"); + + buildReport(doc, Common.getContracts(), "Contracts", new Class[]{ContractTestClass.class}); + + doc.save(getArtifactsDir() + "ReportingEngine.Total.docx"); + } + + @Test + public void nestedDataTableTest() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - Nested data table (Java).docx"); + + buildReport(doc, Common.getManagers(), "Managers", new Class[]{ManagerTestClass.class, ContractTestClass.class}); + + doc.save(getArtifactsDir() + "ReportingEngine.TestNestedDataTable.docx"); + } + + @Test + public void restartingListNumberingDynamically() throws Exception { + Document template = new Document(getMyDir() + "Reporting engine template - List numbering (Java).docx"); + + buildReport(template, Common.getManagers(), "Managers", new Class[]{ManagerTestClass.class, ContractTestClass.class}, ReportBuildOptions.REMOVE_EMPTY_PARAGRAPHS); + + template.save(getArtifactsDir() + "ReportingEngine.RestartingListNumberingDynamically.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.RestartingListNumberingDynamically.docx", getGoldsDir() + "ReportingEngine.RestartingListNumberingDynamically Gold.docx")); + } + + @Test + public void restartingListNumberingDynamicallyWhileInsertingDocumentDynamically() throws Exception { + Document template = DocumentHelper.createSimpleDocument("<>"); + + DocumentTestClass doc = new DocumentTestBuilder() + .withDocument(new Document(getMyDir() + "Reporting engine template - List numbering (Java).docx")).build(); + + buildReport(template, new Object[]{doc, Common.getManagers()}, new String[]{"src", "Managers"}, new Class[]{ManagerTestClass.class, ContractTestClass.class}, ReportBuildOptions.REMOVE_EMPTY_PARAGRAPHS); + + template.save(getArtifactsDir() + "ReportingEngine.RestartingListNumberingDynamicallyWhileInsertingDocumentDynamically.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.RestartingListNumberingDynamicallyWhileInsertingDocumentDynamically.docx", getGoldsDir() + "ReportingEngine.RestartingListNumberingDynamicallyWhileInsertingDocumentDynamically Gold.docx")); + } + + @Test + public void restartingListNumberingDynamicallyWhileMultipleInsertionsDocumentDynamically() throws Exception { + Document mainTemplate = DocumentHelper.createSimpleDocument("<>"); + Document template1 = DocumentHelper.createSimpleDocument("<>"); + Document template2 = DocumentHelper.createSimpleDocument("<>"); + + DocumentTestClass doc = new DocumentTestBuilder() + .withDocument(new Document(getMyDir() + "Reporting engine template - List numbering (Java).docx")).build(); + + buildReport(mainTemplate, new Object[]{template1, template2, doc, Common.getManagers()}, new String[]{"src", "src1", "src2", "Managers"}, new Class[]{ManagerTestClass.class, ContractTestClass.class}, ReportBuildOptions.REMOVE_EMPTY_PARAGRAPHS); + + mainTemplate.save(getArtifactsDir() + "ReportingEngine.RestartingListNumberingDynamicallyWhileMultipleInsertionsDocumentDynamically.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.RestartingListNumberingDynamicallyWhileMultipleInsertionsDocumentDynamically.docx", getGoldsDir() + "ReportingEngine.RestartingListNumberingDynamicallyWhileInsertingDocumentDynamically Gold.docx")); + } + + @Test + public void chartTest() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - Chart (Java).docx"); + + buildReport(doc, Common.getManagers(), "managers", new Class[]{ManagerTestClass.class}); + + doc.save(getArtifactsDir() + "ReportingEngine.TestChart.docx"); + } + + @Test + public void bubbleChartTest() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - Bubble chart (Java).docx"); + + buildReport(doc, Common.getManagers(), "managers", new Class[]{ManagerTestClass.class}); + + doc.save(getArtifactsDir() + "ReportingEngine.TestBubbleChart.docx"); + } + + @Test + public void setChartSeriesColorsDynamically() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - Chart series color (Java).docx"); + + buildReport(doc, Common.getManagers(), "managers", new Class[]{ManagerTestClass.class}); + + doc.save(getArtifactsDir() + "ReportingEngine.SetChartSeriesColorDynamically.docx"); + } + + @Test + public void setPointColorsDynamically() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - Point color (Java).docx"); + + List colors = new ArrayList<>(); + colors.add(new ColorItemTestBuilder().withColorCodeAndValues("Black", Color.BLACK.getRGB(), 1.0, 2.5, 3.5).build()); + colors.add(new ColorItemTestBuilder().withColorCodeAndValues("Red", Color.RED.getRGB(), 2.0, 4.0, 2.5).build()); + colors.add(new ColorItemTestBuilder().withColorCodeAndValues("Green", Color.GREEN.getRGB(), 0.5, 1.5, 2.5).build()); + colors.add(new ColorItemTestBuilder().withColorCodeAndValues("Blue", Color.BLUE.getRGB(), 4.5, 3.5, 1.5).build()); + colors.add(new ColorItemTestBuilder().withColorCodeAndValues("Yellow", Color.YELLOW.getRGB(), 5.0, 2.5, 1.5).build()); + + buildReport(doc, colors, "colorItems", new Class[]{ColorItemTestClass.class}); + + doc.save(getArtifactsDir() + "ReportingEngine.SetPointColorDynamically.docx"); + } + + @Test(enabled = false, description = "WORDSNET-20810") + public void conditionalExpressionRemoveChartSeries() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - Chart series (Java)"); + + int condition = 2; + buildReport(doc, new Object[]{Common.getManagers(), condition}, new String[]{"managers", "condition"}, new Class[]{ManagerTestClass.class}); + + doc.save(getArtifactsDir() + "ReportingEngine.TestRemoveChartSeries.docx"); + } + + @Test + public void indexOf() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - Index of (Java).docx"); + + buildReport(doc, Common.getManagers(), "Managers", new Class[]{ManagerTestClass.class}); + + ByteArrayOutputStream dstStream = new ByteArrayOutputStream(); + doc.save(dstStream, SaveFormat.DOCX); + + Assert.assertEquals("The names are: John Smith, Tony Anderson, July James\f", doc.getText()); + } + + @Test + public void ifElse() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - If-else (Java).docx"); + + buildReport(doc, Common.getManagers(), "m", new Class[]{ManagerTestClass.class}); + + ByteArrayOutputStream dstStream = new ByteArrayOutputStream(); + doc.save(dstStream, SaveFormat.DOCX); + + Assert.assertEquals("You have chosen 3 item(s).\f", doc.getText()); + } + + @Test + public void ifElseWithoutData() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - If-else (Java).docx"); + + buildReport(doc, Common.getEmptyManagers(), "m", new Class[]{ManagerTestClass.class}); + + ByteArrayOutputStream dstStream = new ByteArrayOutputStream(); + doc.save(dstStream, SaveFormat.DOCX); + + Assert.assertEquals("You have chosen no items.\f", doc.getText()); + } + + @Test + public void extensionMethods() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - Extension methods (Java).docx"); + + buildReport(doc, Common.getManagers(), "Managers", new Class[]{ManagerTestClass.class}); + doc.save(getArtifactsDir() + "ReportingEngine.ExtensionMethods.docx"); + } + + @Test + public void operators() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - Operators (Java).docx"); + + NumericTestClass testData = new NumericTestBuilder().withValuesAndLogical(1, 2.0, 3, null, true).build(); + + buildReport(doc, testData, "ds", new Class[]{NumericTestBuilder.class}); + doc.save(getArtifactsDir() + "ReportingEngine.Operators.docx"); + } + + @Test + public void headerVariable() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Header variable (Java).docx"); + + buildReport(doc, new DataSet(), "", ReportBuildOptions.USE_LEGACY_HEADER_FOOTER_VISITING); + + doc.save(getArtifactsDir() + "ReportingEngine.HeaderVariable.docx"); + + Assert.assertEquals("Value of myHeaderVariable is: I am header variable", doc.getFirstSection().getBody().getFirstParagraph().getText().trim()); + } + + @Test + public void contextualObjectMemberAccess() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - Contextual object member access (Java).docx"); + + buildReport(doc, Common.getManagers(), "Managers", new Class[]{ManagerTestClass.class}); + + doc.save(getArtifactsDir() + "ReportingEngine.ContextualObjectMemberAccess.docx"); + } + + @Test + public void insertDocumentDynamicallyWithAdditionalTemplateChecking() throws Exception { + Document template = DocumentHelper.createSimpleDocument("<>"); + + DocumentTestClass doc = new DocumentTestBuilder() + .withDocument(new Document(mDocument)).build(); + + buildReport(template, new Object[]{doc, Common.getContracts()}, new String[]{"src", "Contracts"}, new Class[]{ContractTestClass.class}); + template.save( + getArtifactsDir() + "ReportingEngine.InsertDocumentDynamicallyWithAdditionalTemplateChecking.docx"); + } + + @Test + public void insertDocumentDynamicallyTrimLastParagraph() throws Exception + { + Document template = DocumentHelper.createSimpleDocument("<>"); + + DocumentTestClass doc = new DocumentTestBuilder() + .withDocument(new Document(mDocument)).build(); + + buildReport(template, doc, "src", new Class[]{DocumentTestClass.class}, ReportBuildOptions.REMOVE_EMPTY_PARAGRAPHS); + template.save(getArtifactsDir() + "ReportingEngine.InsertDocumentDynamically.docx"); + + template = new Document(getArtifactsDir() + "ReportingEngine.InsertDocumentDynamically.docx"); + Assert.assertEquals(1, template.getFirstSection().getBody().getParagraphs().getCount()); + } + + @Test + public void insertDocumentDynamically() throws Exception { + Document template = DocumentHelper.createSimpleDocument("<>"); + + DocumentTestClass doc = new DocumentTestBuilder() + .withDocument(new Document(mDocument)).build(); + + buildReport(template, doc, "src"); + template.save(getArtifactsDir() + "ReportingEngine.InsertDocumentDynamically.docx"); + } + + @Test + public void sourseListNumbering() throws Exception + { + //ExStart:SourseListNumbering + //GistId:f99d87e10ab87a581c52206321d8b617 + //ExFor:ReportingEngine.BuildReport(Document, Object[], String[]) + //ExSummary:Shows how to keep inserted numbering as is. + // By default, numbered lists from a template document are continued when their identifiers match those from a document being inserted. + // With "-sourceNumbering" numbering should be separated and kept as is. + Document template = DocumentHelper.createSimpleDocument("<>" + System.lineSeparator() + "<>"); + + DocumentTestClass doc = new DocumentTestBuilder() + .withDocument(new Document(getMyDir() + "List item.docx")).build(); + + ReportingEngine engine = new ReportingEngine(); { engine.setOptions(ReportBuildOptions.REMOVE_EMPTY_PARAGRAPHS); } + engine.buildReport(template, new Object[] { doc }, new String[] { "src" }); + + template.save(getArtifactsDir() + "ReportingEngine.SourseListNumbering.docx"); + //ExEnd:SourseListNumbering + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.SourseListNumbering.docx", getGoldsDir() + "ReportingEngine.SourseListNumbering Gold.docx")); + } + + @Test + public void insertDocumentDynamicallyByStream() throws Exception { + Document template = DocumentHelper.createSimpleDocument("<>"); + + DocumentTestClass docStream = new DocumentTestBuilder() + .withDocumentStream(new FileInputStream(mDocument)).build(); + + buildReport(template, docStream, "src"); + template.save(getArtifactsDir() + "ReportingEngine.InsertDocumentDynamically.docx"); + } + + @Test + public void insertDocumentDynamicallyByBytes() throws Exception { + Document template = DocumentHelper.createSimpleDocument("<>"); + + DocumentTestClass docBytes = new DocumentTestBuilder() + .withDocumentBytes(Files.readAllBytes(Paths.get(mDocument))).build(); + + buildReport(template, docBytes, "src"); + template.save(getArtifactsDir() + "ReportingEngine.InsertDocumentDynamically.docx"); + } + + @Test + public void insertDocumentDynamicallyByUri() throws Exception { + Document template = DocumentHelper.createSimpleDocument("<>"); + + DocumentTestClass docUri = new DocumentTestBuilder() + .withDocumentString("http://www.snee.com/xml/xslt/sample.doc").build(); + + buildReport(template, docUri, "src"); + template.save(getArtifactsDir() + "ReportingEngine.InsertDocumentDynamically.docx"); + } + + @Test + public void insertImageDynamically() throws Exception { + Document template = + DocumentHelper.createTemplateDocumentWithDrawObjects("<>", ShapeType.TEXT_BOX); + + ImageTestClass image = new ImageTestBuilder().withImage(mImage).build(); + buildReport(template, image, "src"); + + template.save(getArtifactsDir() + "ReportingEngine.InsertImageDynamically.docx"); + } + + @Test + public void insertImageDynamicallyByStream() throws Exception { + Document template = + DocumentHelper.createTemplateDocumentWithDrawObjects("<>", ShapeType.TEXT_BOX); + ImageTestClass imageStream = new ImageTestBuilder() + .withImageStream(new FileInputStream(mImage)).build(); + + buildReport(template, imageStream, "src"); + template.save(getArtifactsDir() + "ReportingEngine.InsertImageDynamically.docx"); + } + + @Test + public void insertImageDynamicallyByBytes() throws Exception { + Document template = + DocumentHelper.createTemplateDocumentWithDrawObjects("<>", ShapeType.TEXT_BOX); + ImageTestClass imageBytes = new ImageTestBuilder().withImageBytes(Files.readAllBytes(Paths.get(mImage))).build(); + + buildReport(template, imageBytes, "src"); + template.save(getArtifactsDir() + "ReportingEngine.InsertImageDynamically.docx"); + } + + @Test + public void insertImageDynamicallyByUri() throws Exception { + Document template = + DocumentHelper.createTemplateDocumentWithDrawObjects("<>", ShapeType.TEXT_BOX); + ImageTestClass imageUri = new ImageTestBuilder().withImageString("https://metrics.aspose.com/img/headergraphics.svg").build(); + + buildReport(template, imageUri, "src"); + template.save(getArtifactsDir() + "ReportingEngine.InsertImageDynamically.docx"); + } + + @Test + public void insertHyperlinksDynamically() throws Exception { + Document template = new Document(getMyDir() + "Reporting engine template - Inserting hyperlinks (Java).docx"); + buildReport(template, + new Object[] + { + "https://auckland.dynabic.com/wiki/display/org/Supported+dynamic+insertion+of+hyperlinks+for+LINQ+Reporting+Engine", + "Aspose" + }, + new String[] + { + "uri_expression", + "display_text_expression" + }); + + template.save(getArtifactsDir() + "ReportingEngine.InsertHyperlinksDynamically.docx"); + } + + @Test (dataProvider = "insertHtmlDinamicallyDataProvider") + public void insertHtmlDinamically(String templateText) throws Exception + { + String html = FileUtils.readFileToString(new File(getMyDir() + "Reporting engine template - Html (Java).html"), "utf-8"); + + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln(templateText); + + buildReport(doc, html, "html_text"); + doc.save(getArtifactsDir() + "ReportingEngine.InsertHtmlDinamically.docx"); + } + + @DataProvider(name = "insertHtmlDinamicallyDataProvider") + public static Object[][] insertHtmlDinamicallyDataProvider() { + return new Object[][] + { + {"<<[html_text] -html>>"}, + {"<>"}, + {"<>"}, + }; + } + + @Test(expectedExceptions = IllegalStateException.class) + public void withoutKnownType() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("<<[new Date()]:”dd.MM.yyyy”>>"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, ""); + } + + @Test + public void workWithKnownTypes() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("<<[new GregorianCalendar(2016, 0, 20).getTime()]:”dd.MM.yyyy”>>"); + builder.writeln("<<[new GregorianCalendar(2016, 0, 20).getTime()]:”dd”>>"); + builder.writeln("<<[new GregorianCalendar(2016, 0, 20).getTime()]:”MM”>>"); + builder.writeln("<<[new GregorianCalendar(2016, 0, 20).getTime()]:”yyyy”>>"); + builder.writeln("<<[new GregorianCalendar(2016, 1, 20).get(Calendar.MONTH)]>>"); + + buildReport(doc, "", new Class[]{GregorianCalendar.class, Calendar.class}); + + doc.save(getArtifactsDir() + "ReportingEngine.KnownTypes.docx"); + } + + @Test + public void workWithSingleColumnTableRow() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - Table row (Java).docx"); + buildReport(doc, Common.getManagers(), "Managers", new Class[]{ManagerTestClass.class}); + + doc.save(getArtifactsDir() + "ReportingEngine.SingleColumnTableRow.docx"); + } + + @Test + public void workWithSingleColumnTableRowGreedy() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - Table row greedy (Java).docx"); + buildReport(doc, Common.getManagers(), "Managers", new Class[]{ManagerTestClass.class}); + + doc.save(getArtifactsDir() + "ReportingEngine.SingleColumnTableRowGreedy.docx"); + } + + @Test + public void tableRowConditionalBlocks() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - Table row conditional blocks (Java).docx"); + + ArrayList clients = new ArrayList<>(); + clients.add(new ClientTestClass("John Monrou", "France", "27 RUE PASTEUR")); + clients.add(new ClientTestClass("James White", "England", "14 Tottenham Court Road")); + clients.add(new ClientTestClass("Kate Otts", "New Zealand", "Wellington 6004")); + + buildReport(doc, clients, "clients", new Class[]{ClientTestClass.class}); + + doc.save(getArtifactsDir() + "ReportingEngine.TableRowConditionalBlocks.docx"); + } + + @Test + public void ifGreedy() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - If greedy (Java).docx"); + + AsposeData obj = new AsposeData(); + obj.setList(new ArrayList<>()); + obj.getList().add("abc"); + + buildReport(doc, obj); + + doc.save(getArtifactsDir() + "ReportingEngine.IfGreedy.docx"); + } + + public static class AsposeData { + public ArrayList getList() { + return mList; + } + + public void setList(final ArrayList value) { + mList = value; + } + + private ArrayList mList; + } + + @Test + public void stretchImagefitHeight() throws Exception { + Document doc = + DocumentHelper.createTemplateDocumentWithDrawObjects("<>", + ShapeType.TEXT_BOX); + + ImageTestClass imageStream = new ImageTestBuilder() + .withImageStream(new FileInputStream(mImage)).build(); + buildReport(doc, imageStream, "src"); + + ByteArrayOutputStream dstStream = new ByteArrayOutputStream(); + doc.save(dstStream, SaveFormat.DOCX); + + ByteArrayInputStream byteStream = new ByteArrayInputStream(dstStream.toByteArray()); + + doc = new Document(byteStream); + NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); + + for (Object shapeNode : shapes) { + Shape shape = (Shape) shapeNode; + // Assert that the image is really insert in textbox + Assert.assertNotNull(shape.getFill().getImageBytes()); + + // Assert that width is keeped and height is changed + Assert.assertNotEquals(shape.getHeight(), 346.35); + Assert.assertEquals(shape.getWidth(), 431.5); + } + } + + @Test + public void stretchImagefitWidth() throws Exception { + Document doc = + DocumentHelper.createTemplateDocumentWithDrawObjects("<>", + ShapeType.TEXT_BOX); + + ImageTestClass imageStream = new ImageTestBuilder() + .withImageStream(new FileInputStream(mImage)).build(); + buildReport(doc, imageStream, "src"); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + doc.save(baos, SaveFormat.DOCX); + + ByteArrayInputStream docStream = new ByteArrayInputStream(baos.toByteArray()); + + doc = new Document(docStream); + NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); + + for (Object shapeNode : shapes) { + Shape shape = (Shape) shapeNode; + + // Assert that the image is really insert in textbox and + Assert.assertNotNull(shape.getFill().getImageBytes()); + + // Assert that height is keeped and width is changed + Assert.assertNotEquals(shape.getWidth(), 346.35); + Assert.assertEquals(shape.getHeight(), 431.5); + } + } + + @Test + public void stretchImagefitSize() throws Exception { + Document doc = + DocumentHelper.createTemplateDocumentWithDrawObjects("<>", + ShapeType.TEXT_BOX); + + ImageTestClass imageStream = new ImageTestBuilder() + .withImageStream(new FileInputStream(mImage)).build(); + buildReport(doc, imageStream, "src"); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + doc.save(baos, SaveFormat.DOCX); + + ByteArrayInputStream docStream = new ByteArrayInputStream(baos.toByteArray()); + + doc = new Document(docStream); + NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); + + for (Object shapeNode : shapes) { + Shape shape = (Shape) shapeNode; + + // Assert that the image is really insert in textbox + Assert.assertNotNull(shape.getFill().getImageBytes()); + + // Assert that height is changed and width is changed + Assert.assertNotEquals(346.35, shape.getHeight()); + Assert.assertNotEquals(431.5, shape.getWidth()); + } + } + + @Test + public void stretchImagefitSizeLim() throws Exception { + Document doc = + DocumentHelper.createTemplateDocumentWithDrawObjects("<>", + ShapeType.TEXT_BOX); + + ImageTestClass imageStream = new ImageTestBuilder() + .withImageStream(new FileInputStream(mImage)).build(); + buildReport(doc, imageStream, "src"); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + doc.save(baos, SaveFormat.DOCX); + + ByteArrayInputStream docStream = new ByteArrayInputStream(baos.toByteArray()); + + doc = new Document(docStream); + NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); + + for (Object shapeNode : shapes) { + Shape shape = (Shape) shapeNode; + + // Assert that the image is really insert in textbox + Assert.assertNotNull(shape.getFill().getImageBytes()); + + // Assert that textbox size are equal image size + Assert.assertEquals(shape.getHeight(), 300.0); + Assert.assertEquals(shape.getWidth(), 300.0); + } + } + + @Test(expectedExceptions = IllegalStateException.class) + public void withoutMissingMembers() throws Exception { + DocumentBuilder builder = new DocumentBuilder(); + + // Add templete to the document for reporting engine + DocumentHelper.insertBuilderText(builder, + new String[]{"<<[missingObject.First().id]>>", "<><<[id]>><>"}); + + // Assert that build report failed without "ReportBuildOptions.AllowMissingMembers" + buildReport(builder.getDocument(), new DataSet(), ""); + } + + @Test + public void missingMembers() throws Exception { + //ExStart:MissingMembers + //GistId:a76df4b18bee76d169e55cdf6af8129c + //ExFor:ReportingEngine.BuildReport(Document, Object, String) + //ExFor:ReportingEngine.MissingMemberMessage + //ExFor:ReportingEngine.Options + //ExSummary:Shows how to allow missinng members. + DocumentBuilder builder = new DocumentBuilder(); + builder.writeln("<<[missingObject.First().id]>>"); + builder.writeln("<><<[id]>><>"); + + ReportingEngine engine = new ReportingEngine(); { engine.setOptions(ReportBuildOptions.ALLOW_MISSING_MEMBERS); } + engine.setMissingMemberMessage("Missed"); + engine.buildReport(builder.getDocument(), new DataSet(), ""); + //ExEnd:MissingMembers + + // Assert that build report success with "ReportBuildOptions.AllowMissingMembers" + Assert.assertEquals("Missed", builder.getDocument().getText().trim()); + } + + @Test(dataProvider = "inlineErrorMessagesDataProvider") + public void inlineErrorMessages(String templateText, String result) throws Exception { + DocumentBuilder builder = new DocumentBuilder(); + DocumentHelper.insertBuilderText(builder, new String[]{templateText}); + + buildReport(builder.getDocument(), new DataSet(), "", ReportBuildOptions.INLINE_ERROR_MESSAGES); + + Assert.assertEquals(builder.getDocument().getFirstSection().getBody().getParagraphs().get(0).getText().replaceAll("\\s+$", ""), result); + } + + @DataProvider(name = "inlineErrorMessagesDataProvider") + public static Object[][] inlineErrorMessagesDataProvider() { + return new Object[][] + { + {"<<[missingObject.First().id]>>", "<<[missingObject.First( Error! Can not get the value of member 'missingObject' on type 'class com.aspose.words.net.System.Data.DataSet'. ).id]>>"}, + {"<<[new DateTime()]:\"dd.MM.yyyy\">>", "<<[new DateTime( Error! A type identifier is expected. )]:\"dd.MM.yyyy\">>"}, + {"<<]>>", "<<] Error! Character ']' is unexpected. >>"}, + {"<<[>>", "<<[>> Error! An expression is expected."}, + {"<<>>", "<<>> Error! Tag end is unexpected."}, + }; + } + + @Test + public void setBackgroundColorDynamically() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - Background color (Java).docx"); + + ArrayList colors = new ArrayList<>(); + colors.add(new ColorItemTestBuilder().withColor("Black", Color.BLACK).build()); + colors.add(new ColorItemTestBuilder().withColor("Red", new Color((255), (0), (0))).build()); + colors.add(new ColorItemTestBuilder().withColor("Empty", null).build()); + + buildReport(doc, colors, "Colors", new Class[]{ColorItemTestClass.class}); + + doc.save(getArtifactsDir() + "ReportingEngine.SetBackgroundColorDynamically.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.SetBackgroundColorDynamically.docx", + getGoldsDir() + "ReportingEngine.SetBackgroundColorDynamically Gold.docx")); + } + + @Test + public void setTextColorDynamically() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Text color (Java).docx"); + + ArrayList colors = new ArrayList<>(); + { + colors.add(new ColorItemTestBuilder().withColor("Black", Color.BLUE).build()); + colors.add(new ColorItemTestBuilder().withColor("Red", new Color((255), (0), (0))).build()); + colors.add(new ColorItemTestBuilder().withColor("Empty", null).build()); + } + + buildReport(doc, colors, "Colors", new Class[]{ColorItemTestClass.class}); + + doc.save(getArtifactsDir() + "ReportingEngine.SetTextColorDynamically.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.SetTextColorDynamically.docx", + getGoldsDir() + "ReportingEngine.SetTextColorDynamically Gold.docx")); + } + + @Test + public void doNotRemoveEmptyParagraphs() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - Remove empty paragraphs (Java).docx"); + + buildReport(doc, Common.getManagers(), "Managers", new Class[]{ManagerTestClass.class}); + + doc.save(getArtifactsDir() + "ReportingEngine.DoNotRemoveEmptyParagraphs.docx"); + } + + @Test + public void removeEmptyParagraphs() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - Remove empty paragraphs (Java).docx"); + + buildReport(doc, Common.getManagers(), "Managers", new Class[]{ManagerTestClass.class}, ReportBuildOptions.REMOVE_EMPTY_PARAGRAPHS); + + doc.save(getArtifactsDir() + "ReportingEngine.RemoveEmptyParagraphs.docx"); + } + + @Test(dataProvider = "mergingTableCellsDynamicallyDataProvider") + public void mergingTableCellsDynamically(final String value1, final String value2, final String resultDocumentName) throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - Merging table cells dynamically (Java).docx"); + + ArrayList clients = new ArrayList<>(); + clients.add(new ClientTestClass("John Monrou", "France", "27 RUE PASTEUR")); + clients.add(new ClientTestClass("James White", "New Zealand", "14 Tottenham Court Road")); + clients.add(new ClientTestClass("Kate Otts", "New Zealand", "Wellington 6004")); + + buildReport(doc, new Object[]{value1, value2, clients}, new String[]{"value1", "value2", "clients"}, new Class[]{ClientTestClass.class}); + + doc.save(getArtifactsDir() + resultDocumentName + FileFormatUtil.saveFormatToExtension(SaveFormat.DOCX)); + } + + @DataProvider(name = "mergingTableCellsDynamicallyDataProvider") + public static Object[][] mergingTableCellsDynamicallyDataProvider() { + return new Object[][] + { + {"Hello", "Hello", "ReportingEngine.MergingTableCellsDynamically.Merged"}, + {"Hello", "Name", "ReportingEngine.MergingTableCellsDynamically.NotMerged"} + }; + } + + @Test + public void xmlDataStringWithoutSchema() throws Exception + { + //ExStart + //ExFor:XmlDataSource + //ExFor:XmlDataSource.#ctor(String) + //ExSummary:Show how to use XML as a data source (string). + Document doc = new Document(getMyDir() + "Reporting engine template - XML data destination (Java).docx"); + + XmlDataSource dataSource = new XmlDataSource(getMyDir() + "List of people.xml"); + buildReport(doc, dataSource, "persons"); + + doc.save(getArtifactsDir() + "ReportingEngine.XmlDataString.docx"); + //ExEnd + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.XmlDataString.docx", + getGoldsDir() + "ReportingEngine.DataSource Gold.docx")); + } + + @Test + public void xmlDataStreamWithoutSchema() throws Exception + { + //ExStart + //ExFor:XmlDataSource + //ExFor:XmlDataSource.#ctor(Stream) + //ExSummary:Show how to use XML as a data source (stream). + Document doc = new Document(getMyDir() + "Reporting engine template - XML data destination (Java).docx"); + + InputStream stream = new FileInputStream(getMyDir() + "List of people.xml"); + try { + XmlDataSource dataSource = new XmlDataSource(stream); + buildReport(doc, dataSource, "persons"); + } finally { + stream.close(); + } + + doc.save(getArtifactsDir() + "ReportingEngine.XmlDataStream.docx"); + //ExEnd + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.XmlDataStream.docx", + getGoldsDir() + "ReportingEngine.DataSource Gold.docx")); + } + + @Test + public void xmlDataWithNestedElements() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - Data destination with nested elements (Java).docx"); + + XmlDataSource dataSource = new XmlDataSource(getMyDir() + "Nested elements.xml"); + buildReport(doc, dataSource, "managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.XmlDataWithNestedElements.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.XmlDataWithNestedElements.docx", + getGoldsDir() + "ReportingEngine.DataSourceWithNestedElements Gold.docx")); + } + + @Test + public void jsonDataString() throws Exception + { + //ExStart + //ExFor:JsonDataLoadOptions + //ExFor:JsonDataLoadOptions.#ctor + //ExFor:JsonDataLoadOptions.ExactDateTimeParseFormats + //ExFor:JsonDataLoadOptions.AlwaysGenerateRootObject + //ExFor:JsonDataLoadOptions.PreserveSpaces + //ExFor:JsonDataLoadOptions.SimpleValueParseMode + //ExFor:JsonDataSource + //ExFor:JsonDataSource.#ctor(String,JsonDataLoadOptions) + //ExFor:JsonSimpleValueParseMode + //ExSummary:Shows how to use JSON as a data source (string). + Document doc = new Document(getMyDir() + "Reporting engine template - JSON data destination (Java).docx"); + + JsonDataLoadOptions options = new JsonDataLoadOptions(); + { + options.setExactDateTimeParseFormats(Arrays.asList(new String[]{"MM/dd/yyyy", "MM.d.yy", "MM d yy"})); + } + + JsonDataSource dataSource = new JsonDataSource(getMyDir() + "List of people.json", options); + buildReport(doc, dataSource, "persons"); + + doc.save(getArtifactsDir() + "ReportingEngine.JsonDataString.docx"); + //ExEnd + } + + @Test + public void jsonDataStream() throws Exception + { + //ExStart + //ExFor:JsonDataSource.#ctor(Stream,JsonDataLoadOptions) + //ExSummary:Shows how to use JSON as a data source (stream). + Document doc = new Document(getMyDir() + "Reporting engine template - JSON data destination (Java).docx"); + + JsonDataLoadOptions options = new JsonDataLoadOptions(); + { + options.setExactDateTimeParseFormats(Arrays.asList(new String[]{"MM/dd/yyyy", "MM.d.yy", "MM d yy"})); + } + + InputStream stream = new FileInputStream(getMyDir() + "List of people.json"); + try { + JsonDataSource dataSource = new JsonDataSource(stream, options); + buildReport(doc, dataSource, "persons"); + } finally { + stream.close(); + } + + doc.save(getArtifactsDir() + "ReportingEngine.JsonDataStream.docx"); + //ExEnd + } + + @Test + public void jsonDataWithNestedElements() throws Exception { + Document doc = new Document(getMyDir() + "Reporting engine template - Data destination with nested elements (Java).docx"); + + JsonDataSource dataSource = new JsonDataSource(getMyDir() + "Nested elements.json"); + buildReport(doc, dataSource, "managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.JsonDataWithNestedElements.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.JsonDataWithNestedElements.docx", + getGoldsDir() + "ReportingEngine.DataSourceWithNestedElements Gold.docx")); + } + + @Test + public void jsonDataPreserveSpaces() throws Exception + { + final String TEMPLATE = "LINE BEFORE\r<<[LineWhitespace]>>\r<<[BlockWhitespace]>>LINE AFTER"; + final String EXPECTED_RESULT = "LINE BEFORE\r \r\r\r\r\rLINE AFTER"; + final String JSON = + "{" + + " \"LineWhitespace\" : \" \"," + + " \"BlockWhitespace\" : \"\r\n\r\n\r\n\r\n\"" + + "}"; + + ByteArrayInputStream stream = new ByteArrayInputStream(JSON.getBytes(StandardCharsets.UTF_8)); + try + { + JsonDataLoadOptions options = new JsonDataLoadOptions(); + options.setPreserveSpaces(true); + options.setSimpleValueParseMode(JsonSimpleValueParseMode.STRICT); + + JsonDataSource dataSource = new JsonDataSource(stream, options); + + DocumentBuilder builder = new DocumentBuilder(); + builder.write(TEMPLATE); + + buildReport(builder.getDocument(), dataSource, "ds"); + + Assert.assertEquals(EXPECTED_RESULT + ControlChar.SECTION_BREAK, builder.getDocument().getText()); + } + finally { if (stream != null) stream.close(); } + } + + @Test + public void csvDataString() throws Exception + { + //ExStart + //ExFor:CsvDataLoadOptions + //ExFor:CsvDataLoadOptions.#ctor + //ExFor:CsvDataLoadOptions.#ctor(Boolean) + //ExFor:CsvDataLoadOptions.Delimiter + //ExFor:CsvDataLoadOptions.CommentChar + //ExFor:CsvDataLoadOptions.HasHeaders + //ExFor:CsvDataLoadOptions.QuoteChar + //ExFor:CsvDataSource + //ExFor:CsvDataSource.#ctor(String,CsvDataLoadOptions) + //ExSummary:Shows how to use CSV as a data source (string). + Document doc = new Document(getMyDir() + "Reporting engine template - CSV data destination (Java).docx"); + + CsvDataLoadOptions loadOptions = new CsvDataLoadOptions(true); + loadOptions.setDelimiter(';'); + loadOptions.setCommentChar('$'); + loadOptions.hasHeaders(true); + loadOptions.setQuoteChar('"'); + + CsvDataSource dataSource = new CsvDataSource(getMyDir() + "List of people.csv", loadOptions); + buildReport(doc, dataSource, "persons"); + + doc.save(getArtifactsDir() + "ReportingEngine.CsvDataString.docx"); + //ExEnd + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.CsvDataString.docx", + getGoldsDir() + "ReportingEngine.CsvData Gold.docx")); + } + + @Test + public void csvDataStream() throws Exception + { + //ExStart + //ExFor:CsvDataSource.#ctor(Stream,CsvDataLoadOptions) + //ExSummary:Shows how to use CSV as a data source (stream). + Document doc = new Document(getMyDir() + "Reporting engine template - CSV data destination (Java).docx"); + + CsvDataLoadOptions loadOptions = new CsvDataLoadOptions(true); + loadOptions.setDelimiter(';'); + loadOptions.setCommentChar('$'); + + InputStream stream = new FileInputStream(getMyDir() + "List of people.csv"); + try { + CsvDataSource dataSource = new CsvDataSource(stream, loadOptions); + buildReport(doc, dataSource, "persons"); + } finally { + stream.close(); + } + + doc.save(getArtifactsDir() + "ReportingEngine.CsvDataStream.docx"); + //ExEnd + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.CsvDataStream.docx", + getGoldsDir() + "ReportingEngine.CsvData Gold.docx")); + } + + @Test (dataProvider = "insertComboboxDropdownListItemsDynamicallyDataProvider") + public void insertComboboxDropdownListItemsDynamically(int sdtType) throws Exception + { + final String TEMPLATE = + "<><><><><>"; + + SdtListItem[] staticItems = + { + new SdtListItem("1", "one"), + new SdtListItem("2", "two") + }; + + Document doc = new Document(); + + StructuredDocumentTag sdt = new StructuredDocumentTag(doc, sdtType, MarkupLevel.BLOCK); { sdt.setTitle(TEMPLATE); } + for (SdtListItem item : staticItems) + { + sdt.getListItems().add(item); + } + + doc.getFirstSection().getBody().appendChild(sdt); + + buildReport(doc, new Object(), ""); + + doc.save(getArtifactsDir() + MessageFormat.format("ReportingEngine.InsertComboboxDropdownListItemsDynamically_{0}.docx", sdtType)); + + doc = new Document(getArtifactsDir() + + MessageFormat.format("ReportingEngine.InsertComboboxDropdownListItemsDynamically_{0}.docx", sdtType)); + + sdt = (StructuredDocumentTag) doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + + SdtListItem[] expectedItems = + { + new SdtListItem("1", "one"), + new SdtListItem("2", "two"), + new SdtListItem("3", "three"), + new SdtListItem("5", "five") + }; + + Assert.assertEquals(expectedItems.length, sdt.getListItems().getCount()); + + for (int i = 0; i < expectedItems.length; i++) + { + Assert.assertEquals(expectedItems[i].getValue(), sdt.getListItems().get(i).getValue()); + Assert.assertEquals(expectedItems[i].getDisplayText(), sdt.getListItems().get(i).getDisplayText()); + } + } + + @DataProvider(name = "insertComboboxDropdownListItemsDynamicallyDataProvider") + public static Object[][] insertComboboxDropdownListItemsDynamicallyDataProvider() { + return new Object[][] + { + {SdtType.COMBO_BOX}, + {SdtType.DROP_DOWN_LIST}, + }; + } + + @Test + public void updateFieldsSyntaxAware() throws Exception + { + //ExStart:UpdateFieldsSyntaxAware + //ExFor:ReportingEngine.Options + //ExSummary:Shows how to set options for Reporting Engine + //GistId:66dd22f0854357e394a013b536e2181b + Document doc = new Document(getMyDir() + "Reporting engine template - Fields (Java).docx"); + + // Note that enabling of the option makes the engine to update fields while building a report, + // so there is no need to update fields separately after that. + ReportingEngine engine = new ReportingEngine(); + engine.setOptions(ReportBuildOptions.UPDATE_FIELDS_SYNTAX_AWARE); + engine.buildReport(doc, new String[] { "First topic", "Second topic", "Third topic" }, "topics"); + + doc.save(getArtifactsDir() + "ReportingEngine.UpdateFieldsSyntaxAware.docx"); + //ExEnd:UpdateFieldsSyntaxAware + } + + @Test + public void dollarTextFormat() throws Exception + { + //ExStart:DollarTextFormat + //GistId:f0964b777330b758f6b82330b040b24c + //ExFor:ReportingEngine.BuildReport(Document, Object, String) + //ExSummary:Shows how to display values as dollar text. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("<<[ds.getValue1()]:dollarText>>\r<<[ds.getValue2()]:dollarText>>"); + + NumericTestClass testData = new NumericTestBuilder().withValues(1234, 5621718.589).build(); + + ReportingEngine report = new ReportingEngine(); + report.getKnownTypes().add(NumericTestClass.class); + report.buildReport(doc, testData, "ds"); + + doc.save(getArtifactsDir() + "ReportingEngine.DollarTextFormat.docx"); + //ExEnd:DollarTextFormat + + Assert.assertEquals("one thousand two hundred thirty-four and 00/100\rfive million six hundred twenty-one thousand seven hundred eighteen and 59/100\r\f", doc.getText()); + } + + @Test (enabled = false, description = "To avoid exception with 'SetRestrictedTypes' after execution other tests.") + public void restrictedTypes() throws Exception + { + //ExStart:RestrictedTypes + //GistId:b9e728d2381f759edd5b31d64c1c4d3f + //ExFor:ReportingEngine.SetRestrictedTypes(Type[]) + //ExSummary:Shows how to deny access to members of types considered insecure. + Document doc = + DocumentHelper.createSimpleDocument( + "<><<[typeVar]>>"); + + // Note, that you can't set restricted types during or after building a report. + ReportingEngine.setRestrictedTypes(Class.class); + // We set "AllowMissingMembers" option to avoid exceptions during building a report. + ReportingEngine engine = new ReportingEngine(); + engine.setOptions(ReportBuildOptions.ALLOW_MISSING_MEMBERS); + engine.buildReport(doc, new Object()); + + // We get an empty string because we can't access the GetType() method. + Assert.assertEquals(doc.getText().trim(), ""); + //ExEnd:RestrictedTypes + } + + @Test + public void word2016Charts() throws Exception + { + //ExStart:Word2016Charts + //GistId:9c17d666c47318436785490829a3984f + //ExFor:ReportingEngine.BuildReport(Document, Object[], String[]) + //ExSummary:Shows how to work with charts from word 2016. + Document doc = new Document(getMyDir() + "Reporting engine template - Word 2016 Charts (Java).docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, new Object[] { Common.getShares(), Common.getShareQuotes() }, + new String[] { "shares", "quotes" }); + + doc.save(getArtifactsDir() + "ReportingEngine.Word2016Charts.docx"); + //ExEnd:Word2016Charts + } + + @Test + public void removeParagraphsSelectively() throws Exception + { + //ExStart:RemoveParagraphsSelectively + //GistId:a76df4b18bee76d169e55cdf6af8129c + //ExFor:ReportingEngine.BuildReport(Document, Object, String) + //ExSummary:Shows how to remove paragraphs selectively. + // Template contains tags with an exclamation mark. For such tags, empty paragraphs will be removed. + Document doc = new Document(getMyDir() + "Reporting engine template - Selective remove paragraphs.docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, false, "value"); + + doc.save(getArtifactsDir() + "ReportingEngine.SelectiveDeletionOfParagraphs.docx"); + //ExEnd:RemoveParagraphsSelectively + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.SelectiveDeletionOfParagraphs.docx", getGoldsDir() + "ReportingEngine.SelectiveDeletionOfParagraphs Gold.docx")); + } + + private static void buildReport(final Document document, final Object dataSource) throws Exception { + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(document, dataSource); + } + + private static void buildReport(final Document document, final Object dataSource, final String dataSourceName) throws Exception { + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(document, dataSource, dataSourceName); + } + + private static void buildReport(final Document document, final Object dataSource, final String dataSourceName, + final int reportBuildOptions) throws Exception { + ReportingEngine engine = new ReportingEngine(); + engine.setOptions(reportBuildOptions); + + engine.buildReport(document, dataSource, dataSourceName); + } + + private static void buildReport(final Document document, final Object dataSource, final Class[] knownTypes) throws Exception { + ReportingEngine engine = new ReportingEngine(); + + for (Class knownType : knownTypes) { + engine.getKnownTypes().add(knownType); + } + + engine.buildReport(document, dataSource); + } + + private static void buildReport(final Document document, final Object[] dataSource, final String[] dataSourceName) throws Exception { + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(document, dataSource, dataSourceName); + } + + private static void buildReport(final Document document, final Object[] dataSource, final String[] dataSourceName, + final Class[] knownTypes) throws Exception { + ReportingEngine engine = new ReportingEngine(); + + for (Class knownType : knownTypes) { + engine.getKnownTypes().add(knownType); + } + + engine.buildReport(document, dataSource, dataSourceName); + } + + private static void buildReport(final Document document, final Object dataSource, final String dataSourceName, + final Class[] knownTypes, final int reportBuildOptions) throws Exception { + ReportingEngine engine = new ReportingEngine(); + engine.setOptions(reportBuildOptions); + + for (Class knownType : knownTypes) { + engine.getKnownTypes().add(knownType); + } + + engine.buildReport(document, dataSource, dataSourceName); + } + + private static void buildReport(final Document document, final Object[] dataSource, final String[] dataSourceName, + final Class[] knownTypes, final int reportBuildOptions) throws Exception { + ReportingEngine engine = new ReportingEngine(); + engine.setOptions(reportBuildOptions); + + for (Class knownType : knownTypes) { + engine.getKnownTypes().add(knownType); + } + + engine.buildReport(document, dataSource, dataSourceName); + } + + private static void buildReport(final Document document, final Object dataSource, final String dataSourceName, + final Class[] knownTypes) throws Exception { + ReportingEngine engine = new ReportingEngine(); + + for (Class knownType : knownTypes) { + engine.getKnownTypes().add(knownType); + } + + engine.buildReport(document, dataSource, dataSourceName); + } +} \ No newline at end of file diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExRevision.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExRevision.java new file mode 100644 index 00000000..a8852311 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExRevision.java @@ -0,0 +1,776 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.text.MessageFormat; +import java.util.Date; +import java.util.Iterator; + +public class ExRevision extends ApiExampleBase { + @Test + public void revisions() throws Exception { + //ExStart + //ExFor:Revision + //ExFor:Revision.Accept + //ExFor:Revision.Author + //ExFor:Revision.DateTime + //ExFor:Revision.Group + //ExFor:Revision.Reject + //ExFor:Revision.RevisionType + //ExFor:RevisionCollection + //ExFor:RevisionCollection.Item(Int32) + //ExFor:RevisionCollection.Count + //ExFor:RevisionType + //ExFor:Document.HasRevisions + //ExFor:Document.TrackRevisions + //ExFor:Document.Revisions + //ExSummary:Shows how to work with revisions in a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Normal editing of the document does not count as a revision. + builder.write("This does not count as a revision. "); + + Assert.assertFalse(doc.hasRevisions()); + + // To register our edits as revisions, we need to declare an author, and then start tracking them. + doc.startTrackRevisions("John Doe", new Date()); + + builder.write("This is revision #1. "); + + Assert.assertTrue(doc.hasRevisions()); + Assert.assertEquals(1, doc.getRevisions().getCount()); + + // This flag corresponds to the "Review" -> "Tracking" -> "Track Changes" option in Microsoft Word. + // The "StartTrackRevisions" method does not affect its value, + // and the document is tracking revisions programmatically despite it having a value of "false". + // If we open this document using Microsoft Word, it will not be tracking revisions. + Assert.assertFalse(doc.getTrackRevisions()); + + // We have added text using the document builder, so the first revision is an insertion-type revision. + Revision revision = doc.getRevisions().get(0); + Assert.assertEquals("John Doe", revision.getAuthor()); + Assert.assertEquals("This is revision #1. ", revision.getParentNode().getText()); + Assert.assertEquals(RevisionType.INSERTION, revision.getRevisionType()); + Assert.assertEquals(revision.getDateTime().getDate(), new Date().getDate()); + Assert.assertEquals(doc.getRevisions().getGroups().get(0), revision.getGroup()); + + // Remove a run to create a deletion-type revision. + doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0).remove(); + + // Adding a new revision places it at the beginning of the revision collection. + Assert.assertEquals(RevisionType.DELETION, doc.getRevisions().get(0).getRevisionType()); + Assert.assertEquals(2, doc.getRevisions().getCount()); + + // Insert revisions show up in the document body even before we accept/reject the revision. + // Rejecting the revision will remove its nodes from the body. Conversely, nodes that make up delete revisions + // also linger in the document until we accept the revision. + Assert.assertEquals("This does not count as a revision. This is revision #1.", doc.getText().trim()); + + // Accepting the delete revision will remove its parent node from the paragraph text + // and then remove the collection's revision itself. + doc.getRevisions().get(0).accept(); + + Assert.assertEquals(1, doc.getRevisions().getCount()); + Assert.assertEquals("This is revision #1.", doc.getText().trim()); + + builder.writeln(""); + builder.write("This is revision #2."); + + // Now move the node to create a moving revision type. + Node node = doc.getFirstSection().getBody().getParagraphs().get(1); + Node endNode = doc.getFirstSection().getBody().getParagraphs().get(1).getNextSibling(); + Node referenceNode = doc.getFirstSection().getBody().getParagraphs().get(0); + + while (node != endNode) + { + Node nextNode = node.getNextSibling(); + doc.getFirstSection().getBody().insertBefore(node, referenceNode); + node = nextNode; + } + + Assert.assertEquals(RevisionType.MOVING, doc.getRevisions().get(0).getRevisionType()); + Assert.assertEquals(8, doc.getRevisions().getCount()); + Assert.assertEquals("This is revision #2.\rThis is revision #1. \rThis is revision #2.", doc.getText().trim()); + + // The moving revision is now at index 1. Reject the revision to discard its contents. + doc.getRevisions().get(1).reject(); + + Assert.assertEquals(6, doc.getRevisions().getCount()); + Assert.assertEquals("This is revision #1. \rThis is revision #2.", doc.getText().trim()); + //ExEnd + } + + @Test + public void revisionCollection() throws Exception { + //ExStart + //ExFor:Revision.ParentStyle + //ExFor:RevisionCollection.GetEnumerator + //ExFor:RevisionCollection.Groups + //ExFor:RevisionCollection.RejectAll + //ExFor:RevisionGroupCollection.GetEnumerator + //ExSummary:Shows how to work with a document's collection of revisions. + Document doc = new Document(getMyDir() + "Revisions.docx"); + RevisionCollection revisions = doc.getRevisions(); + + // This collection itself has a collection of revision groups. + // Each group is a sequence of adjacent revisions. + Assert.assertEquals(7, revisions.getGroups().getCount()); //ExSkip + System.out.println(MessageFormat.format("{0} revision groups:", revisions.getGroups().getCount())); + + // Iterate over the collection of groups and print the text that the revision concerns. + Iterator e = revisions.getGroups().iterator(); + + while (e.hasNext()) { + RevisionGroup revisionGroup = e.next(); + + System.out.println(MessageFormat.format("\tGroup type \"{0}\", ", revisionGroup.getRevisionType()) + + MessageFormat.format("author: {0}, contents: [{1}]", revisionGroup.getAuthor(), revisionGroup.getText().trim())); + } + + // Each Run that a revision affects gets a corresponding Revision object. + // The revisions' collection is considerably larger than the condensed form we printed above, + // depending on how many Runs we have segmented the document into during Microsoft Word editing. + Assert.assertEquals(11, revisions.getCount()); //ExSkip + System.out.println("\n{revisions.Count} revisions:"); + + Iterator e1 = revisions.iterator(); + + while (e1.hasNext()) { + Revision revision = e1.next(); + + // A StyleDefinitionChange strictly affects styles and not document nodes. This means the "ParentStyle" + // property will always be in use, while the ParentNode will always be null. + // Since all other changes affect nodes, ParentNode will conversely be in use, and ParentStyle will be null. + if (revision.getRevisionType() == RevisionType.STYLE_DEFINITION_CHANGE) { + System.out.println(MessageFormat.format("\tRevision type \"{0}\", ", revision.getRevisionType()) + + MessageFormat.format("author: {0}, style: [{1}]", revision.getAuthor(), revision.getParentStyle().getName())); + } else { + System.out.println(MessageFormat.format("\tRevision type \"{0}\", ", revision.getRevisionType()) + + MessageFormat.format("author: {0}, contents: [{1}]", revision.getAuthor(), revision.getParentNode().getText().trim())); + } + } + + // Reject all revisions via the collection, reverting the document to its original form. + revisions.rejectAll(); + + Assert.assertEquals(0, revisions.getCount()); + //ExEnd + } + + @Test + public void getInfoAboutRevisionsInRevisionGroups() throws Exception { + //ExStart + //ExFor:RevisionGroup + //ExFor:RevisionGroup.Author + //ExFor:RevisionGroup.RevisionType + //ExFor:RevisionGroup.Text + //ExFor:RevisionGroupCollection + //ExFor:RevisionGroupCollection.Count + //ExSummary:Shows how to print info about a group of revisions in a document. + Document doc = new Document(getMyDir() + "Revisions.docx"); + + Assert.assertEquals(7, doc.getRevisions().getGroups().getCount()); + + for (RevisionGroup group : doc.getRevisions().getGroups()) { + System.out.println(MessageFormat.format("Revision author: {0}; Revision type: {1} \n\tRevision text: {2}", group.getAuthor(), group.getRevisionType(), group.getText())); + } + //ExEnd + } + + @Test + public void getSpecificRevisionGroup() throws Exception { + //ExStart + //ExFor:RevisionGroupCollection + //ExFor:RevisionGroupCollection.Item(Int32) + //ExSummary:Shows how to get a group of revisions in a document. + Document doc = new Document(getMyDir() + "Revisions.docx"); + + RevisionGroup revisionGroup = doc.getRevisions().getGroups().get(0); + //ExEnd + + Assert.assertEquals(RevisionType.DELETION, revisionGroup.getRevisionType()); + Assert.assertEquals("Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. ", + revisionGroup.getText()); + } + + @Test + public void showRevisionBalloons() throws Exception { + //ExStart + //ExFor:RevisionOptions.ShowInBalloons + //ExSummary:Shows how to display revisions in balloons. + Document doc = new Document(getMyDir() + "Revisions.docx"); + + // By default, text that is a revision has a different color to differentiate it from the other non-revision text. + // Set a revision option to show more details about each revision in a balloon on the page's right margin. + doc.getLayoutOptions().getRevisionOptions().setShowInBalloons(ShowInBalloons.FORMAT_AND_DELETE); + doc.save(getArtifactsDir() + "Revision.ShowRevisionBalloons.pdf"); + //ExEnd + } + + @Test + public void revisionOptions() throws Exception { + //ExStart + //ExFor:ShowInBalloons + //ExFor:RevisionOptions.ShowInBalloons + //ExFor:RevisionOptions.CommentColor + //ExFor:RevisionOptions.DeletedTextColor + //ExFor:RevisionOptions.DeletedTextEffect + //ExFor:RevisionOptions.InsertedTextEffect + //ExFor:RevisionOptions.MovedFromTextColor + //ExFor:RevisionOptions.MovedFromTextEffect + //ExFor:RevisionOptions.MovedToTextColor + //ExFor:RevisionOptions.MovedToTextEffect + //ExFor:RevisionOptions.RevisedPropertiesColor + //ExFor:RevisionOptions.RevisedPropertiesEffect + //ExFor:RevisionOptions.RevisionBarsColor + //ExFor:RevisionOptions.RevisionBarsWidth + //ExFor:RevisionOptions.ShowOriginalRevision + //ExFor:RevisionOptions.ShowRevisionMarks + //ExFor:RevisionTextEffect + //ExSummary:Shows how to modify the appearance of revisions. + Document doc = new Document(getMyDir() + "Revisions.docx"); + + // Get the RevisionOptions object that controls the appearance of revisions. + RevisionOptions revisionOptions = doc.getLayoutOptions().getRevisionOptions(); + + // Render insertion revisions in green and italic. + revisionOptions.setInsertedTextColor(RevisionColor.GREEN); + revisionOptions.setInsertedTextEffect(RevisionTextEffect.ITALIC); + + // Render deletion revisions in red and bold. + revisionOptions.setDeletedTextColor(RevisionColor.RED); + revisionOptions.setDeletedTextEffect(RevisionTextEffect.BOLD); + + // The same text will appear twice in a movement revision: + // once at the departure point and once at the arrival destination. + // Render the text at the moved-from revision yellow with a double strike through + // and double-underlined blue at the moved-to revision. + revisionOptions.setMovedFromTextColor(RevisionColor.YELLOW); + revisionOptions.setMovedFromTextEffect(RevisionTextEffect.DOUBLE_STRIKE_THROUGH); + revisionOptions.setMovedToTextColor(RevisionColor.CLASSIC_BLUE); + revisionOptions.setMovedFromTextEffect(RevisionTextEffect.DOUBLE_UNDERLINE); + + // Render format revisions in dark red and bold. + revisionOptions.setRevisedPropertiesColor(RevisionColor.DARK_RED); + revisionOptions.setRevisedPropertiesEffect(RevisionTextEffect.BOLD); + + // Place a thick dark blue bar on the left side of the page next to lines affected by revisions. + revisionOptions.setRevisionBarsColor(RevisionColor.DARK_BLUE); + revisionOptions.setRevisionBarsWidth(15.0f); + + // Show revision marks and original text. + revisionOptions.setShowOriginalRevision(true); + revisionOptions.setShowRevisionMarks(true); + + // Get movement, deletion, formatting revisions, and comments to show up in green balloons + // on the right side of the page. + revisionOptions.setShowInBalloons(ShowInBalloons.FORMAT); + revisionOptions.setCommentColor(RevisionColor.BRIGHT_GREEN); + + // These features are only applicable to formats such as .pdf or .jpg. + doc.save(getArtifactsDir() + "Revision.RevisionOptions.pdf"); + //ExEnd + } + + //ExStart:RevisionSpecifiedCriteria + //GistId:66dd22f0854357e394a013b536e2181b + //ExFor:RevisionCollection.Accept(IRevisionCriteria) + //ExFor:RevisionCollection.Reject(IRevisionCriteria) + //ExFor:IRevisionCriteria + //ExFor:IRevisionCriteria.IsMatch(Revision) + //ExSummary:Shows how to accept or reject revision based on criteria. + @Test //ExSkip + public void revisionSpecifiedCriteria() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.write("This does not count as a revision. "); + + // To register our edits as revisions, we need to declare an author, and then start tracking them. + doc.startTrackRevisions("John Doe", new Date()); + builder.write("This is insertion revision #1. "); + doc.stopTrackRevisions(); + + doc.startTrackRevisions("Jane Doe", new Date()); + builder.write("This is insertion revision #2. "); + // Remove a run "This does not count as a revision.". + doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0).remove(); + doc.stopTrackRevisions(); + + Assert.assertEquals(3, doc.getRevisions().getCount()); + // We have two revisions from different authors, so we need to accept only one. + doc.getRevisions().accept(new RevisionCriteria("John Doe", RevisionType.INSERTION)); + Assert.assertEquals(2, doc.getRevisions().getCount()); + // Reject revision with different author name and revision type. + doc.getRevisions().reject(new RevisionCriteria("Jane Doe", RevisionType.DELETION)); + Assert.assertEquals(1, doc.getRevisions().getCount()); + + doc.save(getArtifactsDir() + "Revision.RevisionSpecifiedCriteria.docx"); + } + + ///

          + /// Control when certain revision should be accepted/rejected. + /// + public static class RevisionCriteria implements IRevisionCriteria + { + private String AuthorName; + private int _RevisionType; + + public RevisionCriteria(String authorName, int revisionType) + { + AuthorName = authorName; + _RevisionType = revisionType; + } + + public boolean isMatch(Revision revision) + { + return AuthorName.equals(revision.getAuthor()) && revision.getRevisionType() == _RevisionType; + } + } + //ExEnd:RevisionSpecifiedCriteria + + @Test + public void trackRevisions() throws Exception + { + //ExStart + //ExFor:Document.StartTrackRevisions(String) + //ExFor:Document.StartTrackRevisions(String, DateTime) + //ExFor:Document.StopTrackRevisions + //ExSummary:Shows how to track revisions while editing a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Editing a document usually does not count as a revision until we begin tracking them. + builder.write("Hello world! "); + + Assert.assertEquals(0, doc.getRevisions().getCount()); + Assert.assertFalse(doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0).isInsertRevision()); + + doc.startTrackRevisions("John Doe"); + + builder.write("Hello again! "); + + Assert.assertEquals(1, doc.getRevisions().getCount()); + Assert.assertTrue(doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(1).isInsertRevision()); + Assert.assertEquals("John Doe", doc.getRevisions().get(0).getAuthor()); + + // Stop tracking revisions to not count any future edits as revisions. + doc.stopTrackRevisions(); + builder.write("Hello again! "); + + Assert.assertEquals(1, doc.getRevisions().getCount()); + Assert.assertFalse(doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(2).isInsertRevision()); + + // Creating revisions gives them a date and time of the operation. + // We can disable this by passing DateTime.MinValue when we start tracking revisions. + doc.startTrackRevisions("John Doe", new Date()); + builder.write("Hello again! "); + + Assert.assertEquals(2, doc.getRevisions().getCount()); + Assert.assertEquals("John Doe", doc.getRevisions().get(1).getAuthor()); + Assert.assertEquals(new Date(), doc.getRevisions().get(1).getDateTime()); + + // We can accept/reject these revisions programmatically + // by calling methods such as Document.AcceptAllRevisions, or each revision's Accept method. + // In Microsoft Word, we can process them manually via "Review" -> "Changes". + doc.save(getArtifactsDir() + "Document.StartTrackRevisions.docx"); + //ExEnd + } + + @Test + public void acceptAllRevisions() throws Exception + { + //ExStart + //ExFor:Document.AcceptAllRevisions + //ExSummary:Shows how to accept all tracking changes in the document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Edit the document while tracking changes to create a few revisions. + doc.startTrackRevisions("John Doe"); + builder.write("Hello world! "); + builder.write("Hello again! "); + builder.write("This is another revision."); + doc.stopTrackRevisions(); + + Assert.assertEquals(3, doc.getRevisions().getCount()); + + // We can iterate through every revision and accept/reject it as a part of our document. + // If we know we wish to accept every revision, we can do it more straightforwardly so by calling this method. + doc.acceptAllRevisions(); + + Assert.assertEquals(0, doc.getRevisions().getCount()); + Assert.assertEquals("Hello world! Hello again! This is another revision.", doc.getText().trim()); + //ExEnd + } + + @Test + public void getRevisedPropertiesOfList() throws Exception + { + //ExStart + //ExFor:RevisionsView + //ExFor:Document.RevisionsView + //ExSummary:Shows how to switch between the revised and the original view of a document. + Document doc = new Document(getMyDir() + "Revisions at list levels.docx"); + doc.updateListLabels(); + + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + Assert.assertEquals("1.", paragraphs.get(0).getListLabel().getLabelString()); + Assert.assertEquals("a.", paragraphs.get(1).getListLabel().getLabelString()); + Assert.assertEquals("", paragraphs.get(2).getListLabel().getLabelString()); + + // View the document object as if all the revisions are accepted. Currently supports list labels. + doc.setRevisionsView(RevisionsView.FINAL); + + Assert.assertEquals("", paragraphs.get(0).getListLabel().getLabelString()); + Assert.assertEquals("1.", paragraphs.get(1).getListLabel().getLabelString()); + Assert.assertEquals("a.", paragraphs.get(2).getListLabel().getLabelString()); + //ExEnd + + doc.setRevisionsView(RevisionsView.ORIGINAL); + doc.acceptAllRevisions(); + + Assert.assertEquals("a.", paragraphs.get(0).getListLabel().getLabelString()); + Assert.assertEquals("", paragraphs.get(1).getListLabel().getLabelString()); + Assert.assertEquals("b.", paragraphs.get(2).getListLabel().getLabelString()); + } + + @Test + public void compare() throws Exception + { + //ExStart + //ExFor:Document.Compare(Document, String, DateTime) + //ExFor:RevisionCollection.AcceptAll + //ExSummary:Shows how to compare documents. + Document docOriginal = new Document(); + DocumentBuilder builder = new DocumentBuilder(docOriginal); + builder.writeln("This is the original document."); + + Document docEdited = new Document(); + builder = new DocumentBuilder(docEdited); + builder.writeln("This is the edited document."); + + // Comparing documents with revisions will throw an exception. + if (docOriginal.getRevisions().getCount() == 0 && docEdited.getRevisions().getCount() == 0) + docOriginal.compare(docEdited, "authorName", new Date()); + + // After the comparison, the original document will gain a new revision + // for every element that is different in the edited document. + Assert.assertEquals(2, docOriginal.getRevisions().getCount()); //ExSkip + for (Revision r : docOriginal.getRevisions()) + { + System.out.println("Revision type: {r.RevisionType}, on a node of type \"{r.ParentNode.NodeType}\""); + System.out.println("\tChanged text: \"{r.ParentNode.GetText()}\""); + } + + // Accepting these revisions will transform the original document into the edited document. + docOriginal.getRevisions().acceptAll(); + + Assert.assertEquals(docOriginal.getText(), docEdited.getText()); + //ExEnd + + docOriginal = DocumentHelper.saveOpen(docOriginal); + Assert.assertEquals(0, docOriginal.getRevisions().getCount()); + } + + @Test + public void compareDocumentWithRevisions() throws Exception + { + Document doc1 = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc1); + builder.writeln("Hello world! This text is not a revision."); + + Document docWithRevision = new Document(); + builder = new DocumentBuilder(docWithRevision); + + docWithRevision.startTrackRevisions("John Doe"); + builder.writeln("This is a revision."); + + Assert.assertThrows(IllegalStateException.class, () -> docWithRevision.compare(doc1, "John Doe", new Date())); + } + + @Test + public void compareOptions() throws Exception + { + //ExStart + //ExFor:CompareOptions + //ExFor:CompareOptions.CompareMoves + //ExFor:CompareOptions.IgnoreFormatting + //ExFor:CompareOptions.IgnoreCaseChanges + //ExFor:CompareOptions.IgnoreComments + //ExFor:CompareOptions.IgnoreTables + //ExFor:CompareOptions.IgnoreFields + //ExFor:CompareOptions.IgnoreFootnotes + //ExFor:CompareOptions.IgnoreTextboxes + //ExFor:CompareOptions.IgnoreHeadersAndFooters + //ExFor:CompareOptions.Target + //ExFor:ComparisonTargetType + //ExFor:Document.Compare(Document, String, DateTime, CompareOptions) + //ExSummary:Shows how to filter specific types of document elements when making a comparison. + // Create the original document and populate it with various kinds of elements. + Document docOriginal = new Document(); + DocumentBuilder builder = new DocumentBuilder(docOriginal); + + // Paragraph text referenced with an endnote: + builder.writeln("Hello world! This is the first paragraph."); + builder.insertFootnote(FootnoteType.ENDNOTE, "Original endnote text."); + + // Table: + builder.startTable(); + builder.insertCell(); + builder.write("Original cell 1 text"); + builder.insertCell(); + builder.write("Original cell 2 text"); + builder.endTable(); + + // Textbox: + Shape textBox = builder.insertShape(ShapeType.TEXT_BOX, 150.0, 20.0); + builder.moveTo(textBox.getFirstParagraph()); + builder.write("Original textbox contents"); + + // DATE field: + builder.moveTo(docOriginal.getFirstSection().getBody().appendParagraph("")); + builder.insertField(" DATE "); + + // Comment: + Comment newComment = new Comment(docOriginal, "John Doe", "J.D.", new Date()); + newComment.setText("Original comment."); + builder.getCurrentParagraph().appendChild(newComment); + + // Header: + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.writeln("Original header contents."); + + // Create a clone of our document and perform a quick edit on each of the cloned document's elements. + Document docEdited = (Document)docOriginal.deepClone(true); + Paragraph firstParagraph = docEdited.getFirstSection().getBody().getFirstParagraph(); + + firstParagraph.getRuns().get(0).setText("hello world! this is the first paragraph, after editing."); + firstParagraph.getParagraphFormat().setStyle(docEdited.getStyles().getByStyleIdentifier(StyleIdentifier.HEADING_1)); + ((Footnote)docEdited.getChild(NodeType.FOOTNOTE, 0, true)).getFirstParagraph().getRuns().get(1).setText("Edited endnote text."); + ((Table)docEdited.getChild(NodeType.TABLE, 0, true)).getFirstRow().getCells().get(1).getFirstParagraph().getRuns().get(0).setText("Edited Cell 2 contents"); + ((Shape)docEdited.getChild(NodeType.SHAPE, 0, true)).getFirstParagraph().getRuns().get(0).setText("Edited textbox contents"); + ((FieldDate)docEdited.getRange().getFields().get(0)).setUseLunarCalendar(true); + ((Comment)docEdited.getChild(NodeType.COMMENT, 0, true)).getFirstParagraph().getRuns().get(0).setText("Edited comment."); + docEdited.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.HEADER_PRIMARY).getFirstParagraph().getRuns().get(0).setText("Edited header contents."); + + // Comparing documents creates a revision for every edit in the edited document. + // A CompareOptions object has a series of flags that can suppress revisions + // on each respective type of element, effectively ignoring their change. + CompareOptions compareOptions = new CompareOptions(); + compareOptions.setCompareMoves(false); + compareOptions.setIgnoreFormatting(false); + compareOptions.setIgnoreCaseChanges(false); + compareOptions.setIgnoreComments(false); + compareOptions.setIgnoreTables(false); + compareOptions.setIgnoreFields(false); + compareOptions.setIgnoreFootnotes(false); + compareOptions.setIgnoreTextboxes(false); + compareOptions.setIgnoreHeadersAndFooters(false); + compareOptions.setTarget(ComparisonTargetType.NEW); + + docOriginal.compare(docEdited, "John Doe", new Date(), compareOptions); + docOriginal.save(getArtifactsDir() + "Revision.CompareOptions.docx"); + //ExEnd + + docOriginal = new Document(getArtifactsDir() + "Revision.CompareOptions.docx"); + + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "OriginalEdited endnote text.", (Footnote)docOriginal.getChild(NodeType.FOOTNOTE, 0, true)); + } + + @Test (dataProvider = "ignoreDmlUniqueIdDataProvider") + public void ignoreDmlUniqueId(boolean isIgnoreDmlUniqueId) throws Exception + { + //ExStart + //ExFor:CompareOptions.AdvancedOptions + //ExFor:AdvancedCompareOptions.IgnoreDmlUniqueId + //ExFor:CompareOptions.IgnoreDmlUniqueId + //ExSummary:Shows how to compare documents ignoring DML unique ID. + Document docA = new Document(getMyDir() + "DML unique ID original.docx"); + Document docB = new Document(getMyDir() + "DML unique ID compare.docx"); + + // By default, Aspose.Words do not ignore DML's unique ID, and the revisions count was 2. + // If we are ignoring DML's unique ID, and revisions count were 0. + CompareOptions compareOptions = new CompareOptions(); + compareOptions.getAdvancedOptions().setIgnoreDmlUniqueId(isIgnoreDmlUniqueId); + + docA.compare(docB, "Aspose.Words", new Date(), compareOptions); + + Assert.assertEquals(isIgnoreDmlUniqueId ? 0 : 2, docA.getRevisions().getCount()); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "ignoreDmlUniqueIdDataProvider") + public static Object[][] ignoreDmlUniqueIdDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void layoutOptionsRevisions() throws Exception + { + //ExStart + //ExFor:Document.LayoutOptions + //ExFor:LayoutOptions + //ExFor:LayoutOptions.RevisionOptions + //ExFor:RevisionColor + //ExFor:RevisionOptions + //ExFor:RevisionOptions.InsertedTextColor + //ExFor:RevisionOptions.ShowRevisionBars + //ExFor:RevisionOptions.RevisionBarsPosition + //ExSummary:Shows how to alter the appearance of revisions in a rendered output document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a revision, then change the color of all revisions to green. + builder.writeln("This is not a revision."); + doc.startTrackRevisions("John Doe", new Date()); + Assert.assertEquals(RevisionColor.BY_AUTHOR, doc.getLayoutOptions().getRevisionOptions().getInsertedTextColor()); //ExSkip + Assert.assertTrue(doc.getLayoutOptions().getRevisionOptions().getShowRevisionBars()); //ExSkip + builder.writeln("This is a revision."); + doc.stopTrackRevisions(); + builder.writeln("This is not a revision."); + + // Remove the bar that appears to the left of every revised line. + doc.getLayoutOptions().getRevisionOptions().setInsertedTextColor(RevisionColor.BRIGHT_GREEN); + doc.getLayoutOptions().getRevisionOptions().setShowRevisionBars(false); + doc.getLayoutOptions().getRevisionOptions().setRevisionBarsPosition(HorizontalAlignment.RIGHT); + + doc.save(getArtifactsDir() + "Revision.LayoutOptionsRevisions.pdf"); + //ExEnd + } + + @Test (dataProvider = "granularityCompareOptionDataProvider") + public void granularityCompareOption(/*Granularity*/int granularity) throws Exception + { + //ExStart + //ExFor:CompareOptions.Granularity + //ExFor:Granularity + //ExSummary:Shows to specify a granularity while comparing documents. + Document docA = new Document(); + DocumentBuilder builderA = new DocumentBuilder(docA); + builderA.writeln("Alpha Lorem ipsum dolor sit amet, consectetur adipiscing elit"); + + Document docB = new Document(); + DocumentBuilder builderB = new DocumentBuilder(docB); + builderB.writeln("Lorems ipsum dolor sit amet consectetur - \"adipiscing\" elit"); + + // Specify whether changes are tracking + // by character ('Granularity.CharLevel'), or by word ('Granularity.WordLevel'). + CompareOptions compareOptions = new CompareOptions(); + compareOptions.setGranularity(granularity); + + docA.compare(docB, "author", new Date(), compareOptions); + + // The first document's collection of revision groups contains all the differences between documents. + RevisionGroupCollection groups = docA.getRevisions().getGroups(); + Assert.assertEquals(5, groups.getCount()); + //ExEnd + + if (granularity == Granularity.CHAR_LEVEL) + { + Assert.assertEquals(RevisionType.DELETION, groups.get(0).getRevisionType()); + Assert.assertEquals("Alpha ", groups.get(0).getText()); + + Assert.assertEquals(RevisionType.DELETION, groups.get(1).getRevisionType()); + Assert.assertEquals(",", groups.get(1).getText()); + + Assert.assertEquals(RevisionType.INSERTION, groups.get(2).getRevisionType()); + Assert.assertEquals("s", groups.get(2).getText()); + + Assert.assertEquals(RevisionType.INSERTION, groups.get(3).getRevisionType()); + Assert.assertEquals("- \"", groups.get(3).getText()); + + Assert.assertEquals(RevisionType.INSERTION, groups.get(4).getRevisionType()); + Assert.assertEquals("\"", groups.get(4).getText()); + } + else + { + Assert.assertEquals(RevisionType.DELETION, groups.get(0).getRevisionType()); + Assert.assertEquals("Alpha Lorem", groups.get(0).getText()); + + Assert.assertEquals(RevisionType.DELETION, groups.get(1).getRevisionType()); + Assert.assertEquals(",", groups.get(1).getText()); + + Assert.assertEquals(RevisionType.INSERTION, groups.get(2).getRevisionType()); + Assert.assertEquals("Lorems", groups.get(2).getText()); + + Assert.assertEquals(RevisionType.INSERTION, groups.get(3).getRevisionType()); + Assert.assertEquals("- \"", groups.get(3).getText()); + + Assert.assertEquals(RevisionType.INSERTION, groups.get(4).getRevisionType()); + Assert.assertEquals("\"", groups.get(4).getText()); + } + } + + @DataProvider(name = "granularityCompareOptionDataProvider") + public static Object[][] granularityCompareOptionDataProvider() { + return new Object[][] + { + {Granularity.CHAR_LEVEL}, + {Granularity.WORD_LEVEL}, + }; + } + + @Test + public void ignoreStoreItemId() throws Exception + { + //ExStart:IgnoreStoreItemId + //GistId:a76df4b18bee76d169e55cdf6af8129c + //ExFor:AdvancedCompareOptions + //ExFor:AdvancedCompareOptions.IgnoreStoreItemId + //ExSummary:Shows how to compare SDT with same content but different store item id. + Document docA = new Document(getMyDir() + "Document with SDT 1.docx"); + Document docB = new Document(getMyDir() + "Document with SDT 2.docx"); + + // Configure options to compare SDT with same content but different store item id. + CompareOptions compareOptions = new CompareOptions(); + compareOptions.getAdvancedOptions().setIgnoreStoreItemId(false); + + docA.compare(docB, "user", new Date(), compareOptions); + Assert.assertEquals(8, docA.getRevisions().getCount()); + + compareOptions.getAdvancedOptions().setIgnoreStoreItemId(true); + + docA.getRevisions().rejectAll(); + docA.compare(docB, "user", new Date(), compareOptions); + Assert.assertEquals(0, docA.getRevisions().getCount()); + //ExEnd:IgnoreStoreItemId + } + + @Test + public void revisionCellColor() throws Exception + { + //ExStart:RevisionCellColor + //GistId:72d57eeddb7fb342fd51b26e5fcf9642 + //ExFor:RevisionOptions.InsertCellColor + //ExFor:RevisionOptions.DeleteCellColor + //ExSummary:Shows how to work with insert/delete cell revision color. + Document doc = new Document(getMyDir() + "Cell revisions.docx"); + + doc.getLayoutOptions().getRevisionOptions().setInsertCellColor(RevisionColor.BLUE); + doc.getLayoutOptions().getRevisionOptions().setDeleteCellColor(RevisionColor.DARK_RED); + + doc.save(getArtifactsDir() + "Revision.RevisionCellColor.pdf"); + //ExEnd:RevisionCellColor + } +} + diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExRtfLoadOptions.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExRtfLoadOptions.java new file mode 100644 index 00000000..f8978c91 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExRtfLoadOptions.java @@ -0,0 +1,54 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.Document; +import com.aspose.words.RtfLoadOptions; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +@Test +public class ExRtfLoadOptions extends ApiExampleBase { + @Test(dataProvider = "recognizeUtf8TextDataProvider") + public void recognizeUtf8Text(boolean recognizeUtf8Text) throws Exception { + //ExStart + //ExFor:RtfLoadOptions + //ExFor:RtfLoadOptions.#ctor + //ExFor:RtfLoadOptions.RecognizeUtf8Text + //ExSummary:Shows how to detect UTF-8 characters while loading an RTF document. + // Create an "RtfLoadOptions" object to modify how we load an RTF document. + RtfLoadOptions loadOptions = new RtfLoadOptions(); + + // Set the "RecognizeUtf8Text" property to "false" to assume that the document uses the ISO 8859-1 charset + // and loads every character in the document. + // Set the "RecognizeUtf8Text" property to "true" to parse any variable-length characters that may occur in the text. + loadOptions.setRecognizeUtf8Text(recognizeUtf8Text); + + Document doc = new Document(getMyDir() + "UTF-8 characters.rtf", loadOptions); + + Assert.assertEquals( + recognizeUtf8Text + ? "“John Doe´s list of currency symbols”™\r" + + "€, ¢, £, ¥, ¤" + : "“John Doe´s list of currency symbolsâ€\u009dâ„¢\r" + + "€, ¢, £, Â¥, ¤", + doc.getFirstSection().getBody().getText().trim()); + //ExEnd + } + + @DataProvider(name = "recognizeUtf8TextDataProvider") + public static Object[][] recognizeUtf8TextDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExRtfSaveOptions.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExRtfSaveOptions.java new file mode 100644 index 00000000..73f433bd --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExRtfSaveOptions.java @@ -0,0 +1,115 @@ +package Examples; + +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +@Test +public class ExRtfSaveOptions extends ApiExampleBase { + @Test(dataProvider = "exportImagesDataProvider") + public void exportImages(boolean exportImagesForOldReaders) throws Exception { + //ExStart + //ExFor:RtfSaveOptions + //ExFor:RtfSaveOptions.ExportCompactSize + //ExFor:RtfSaveOptions.ExportImagesForOldReaders + //ExFor:RtfSaveOptions.SaveFormat + //ExSummary:Shows how to save a document to .rtf with custom options. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // Create an "RtfSaveOptions" object to pass to the document's "Save" method to modify how we save it to an RTF. + RtfSaveOptions options = new RtfSaveOptions(); + + Assert.assertEquals(SaveFormat.RTF, options.getSaveFormat()); + + // Set the "ExportCompactSize" property to "true" to + // reduce the saved document's size at the cost of right-to-left text compatibility. + options.setExportCompactSize(true); + + // Set the "ExportImagesFotOldReaders" property to "true" to use extra keywords to ensure that our document is + // compatible with pre-Microsoft Word 97 readers and WordPad. + // Set the "ExportImagesFotOldReaders" property to "false" to reduce the size of the document, + // but prevent old readers from being able to read any non-metafile or BMP images that the document may contain. + options.setExportImagesForOldReaders(exportImagesForOldReaders); + + doc.save(getArtifactsDir() + "RtfSaveOptions.ExportImages.rtf", options); + //ExEnd + + if (exportImagesForOldReaders) { + TestUtil.fileContainsString("nonshppict", getArtifactsDir() + "RtfSaveOptions.ExportImages.rtf"); + TestUtil.fileContainsString("shprslt", getArtifactsDir() + "RtfSaveOptions.ExportImages.rtf"); + } else { + Assert.assertThrows(AssertionError.class, () -> TestUtil.fileContainsString("nonshppict", getArtifactsDir() + "RtfSaveOptions.ExportImages.rtf")); + Assert.assertThrows(AssertionError.class, () -> TestUtil.fileContainsString("shprslt", getArtifactsDir() + "RtfSaveOptions.ExportImages.rtf")); + } + } + + @DataProvider(name = "exportImagesDataProvider") + public static Object[][] exportImagesDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "saveImagesAsWmfDataProvider") + public void saveImagesAsWmf(boolean saveImagesAsWmf) throws Exception { + //ExStart + //ExFor:RtfSaveOptions.SaveImagesAsWmf + //ExSummary:Shows how to convert all images in a document to the Windows Metafile format as we save the document as an RTF. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Jpeg image:"); + Shape imageShape = builder.insertImage(getImageDir() + "Logo.jpg"); + + Assert.assertEquals(ImageType.JPEG, imageShape.getImageData().getImageType()); + + builder.insertParagraph(); + builder.writeln("Png image:"); + imageShape = builder.insertImage(getImageDir() + "Transparent background logo.png"); + + Assert.assertEquals(ImageType.PNG, imageShape.getImageData().getImageType()); + + // Create an "RtfSaveOptions" object to pass to the document's "Save" method to modify how we save it to an RTF. + RtfSaveOptions rtfSaveOptions = new RtfSaveOptions(); + + // Set the "SaveImagesAsWmf" property to "true" to convert all images in the document to WMF as we save it to RTF. + // Doing so will help readers such as WordPad to read our document. + // Set the "SaveImagesAsWmf" property to "false" to preserve the original format of all images in the document + // as we save it to RTF. This will preserve the quality of the images at the cost of compatibility with older RTF readers. + rtfSaveOptions.setSaveImagesAsWmf(saveImagesAsWmf); + + doc.save(getArtifactsDir() + "RtfSaveOptions.SaveImagesAsWmf.rtf", rtfSaveOptions); + + doc = new Document(getArtifactsDir() + "RtfSaveOptions.SaveImagesAsWmf.rtf"); + + NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); + + if (saveImagesAsWmf) { + Assert.assertEquals(ImageType.WMF, ((Shape) shapes.get(0)).getImageData().getImageType()); + Assert.assertEquals(ImageType.WMF, ((Shape) shapes.get(1)).getImageData().getImageType()); + } else { + Assert.assertEquals(ImageType.JPEG, ((Shape) shapes.get(0)).getImageData().getImageType()); + Assert.assertEquals(ImageType.PNG, ((Shape) shapes.get(1)).getImageData().getImageType()); + } + //ExEnd + } + + @DataProvider(name = "saveImagesAsWmfDataProvider") + public static Object[][] saveImagesAsWmfDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExSavingCallback.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExSavingCallback.java new file mode 100644 index 00000000..6dfafe00 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExSavingCallback.java @@ -0,0 +1,257 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.apache.commons.io.FilenameUtils; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.io.FileOutputStream; +import java.text.MessageFormat; + +public class ExSavingCallback extends ApiExampleBase { + //ExStart + //ExFor:IPageSavingCallback + //ExFor:IPageSavingCallback.PageSaving(PageSavingArgs) + //ExFor:PageSavingArgs + //ExFor:PageSavingArgs.PageFileName + //ExFor:PageSavingArgs.KeepPageStreamOpen + //ExFor:PageSavingArgs.PageIndex + //ExFor:PageSavingArgs.PageStream + //ExFor:FixedPageSaveOptions.PageSavingCallback + //ExSummary:Shows how to use a callback to save a document to HTML page by page. + @Test //ExSkip + public void pageFileNames() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Page 1."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 2."); + builder.insertImage(getImageDir() + "Logo.jpg"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 3."); + + // Create an "HtmlFixedSaveOptions" object, which we can pass to the document's "Save" method + // to modify how we convert the document to HTML. + HtmlFixedSaveOptions htmlFixedSaveOptions = new HtmlFixedSaveOptions(); + + // We will save each page in this document to a separate HTML file in the local file system. + // Set a callback that allows us to name each output HTML document. + htmlFixedSaveOptions.setPageSavingCallback(new CustomFileNamePageSavingCallback()); + + doc.save(getArtifactsDir() + "SavingCallback.PageFileNames.html", htmlFixedSaveOptions); + + String[] filePaths = DocumentHelper.directoryGetFiles(getArtifactsDir(), "SavingCallback.PageFileNames.Page_*").toArray(new String[0]); + + Assert.assertEquals(3, filePaths.length); + } + + /// + /// Saves all pages to a file and directory specified within. + /// + private static class CustomFileNamePageSavingCallback implements IPageSavingCallback { + public void pageSaving(PageSavingArgs args) throws Exception { + String outFileName = MessageFormat.format("{0}SavingCallback.PageFileNames.Page_{1}.html", getArtifactsDir(), args.getPageIndex()); + + // Below are two ways of specifying where Aspose.Words will save each page of the document. + // 1 - Set a filename for the output page file: + args.setPageFileName(outFileName); + + // 2 - Create a custom stream for the output page file: + try (FileOutputStream outputStream = new FileOutputStream(outFileName)) { + args.setPageStream(outputStream); + } + + Assert.assertFalse(args.getKeepPageStreamOpen()); + } + } + //ExEnd + + //ExStart + //ExFor:DocumentPartSavingArgs + //ExFor:DocumentPartSavingArgs.Document + //ExFor:DocumentPartSavingArgs.DocumentPartFileName + //ExFor:DocumentPartSavingArgs.DocumentPartStream + //ExFor:DocumentPartSavingArgs.KeepDocumentPartStreamOpen + //ExFor:IDocumentPartSavingCallback + //ExFor:IDocumentPartSavingCallback.DocumentPartSaving(DocumentPartSavingArgs) + //ExFor:IImageSavingCallback + //ExFor:IImageSavingCallback.ImageSaving + //ExFor:ImageSavingArgs + //ExFor:ImageSavingArgs.ImageFileName + //ExFor:HtmlSaveOptions + //ExFor:HtmlSaveOptions.DocumentPartSavingCallback + //ExFor:HtmlSaveOptions.ImageSavingCallback + //ExSummary:Shows how to split a document into parts and save them. + @Test //ExSkip + public void documentPartsFileNames() throws Exception { + Document doc = new Document(getMyDir() + "Rendering.docx"); + String outFileName = "SavingCallback.DocumentPartsFileNames.html"; + + // Create an "HtmlFixedSaveOptions" object, which we can pass to the document's "Save" method + // to modify how we convert the document to HTML. + HtmlSaveOptions options = new HtmlSaveOptions(); + + // If we save the document normally, there will be one output HTML + // document with all the source document's contents. + // Set the "DocumentSplitCriteria" property to "DocumentSplitCriteria.SectionBreak" to + // save our document to multiple HTML files: one for each section. + options.setDocumentSplitCriteria(DocumentSplitCriteria.SECTION_BREAK); + + // Assign a custom callback to the "DocumentPartSavingCallback" property to alter the document part saving logic. + options.setDocumentPartSavingCallback(new SavedDocumentPartRename(outFileName, options.getDocumentSplitCriteria())); + + // If we convert a document that contains images into html, we will end up with one html file which links to several images. + // Each image will be in the form of a file in the local file system. + // There is also a callback that can customize the name and file system location of each image. + options.setImageSavingCallback(new SavedImageRename(outFileName)); + + doc.save(getArtifactsDir() + outFileName, options); + } + + /// + /// Sets custom filenames for output documents that the saving operation splits a document into. + /// + private static class SavedDocumentPartRename implements IDocumentPartSavingCallback { + public SavedDocumentPartRename(String outFileName, int documentSplitCriteria) { + mOutFileName = outFileName; + mDocumentSplitCriteria = documentSplitCriteria; + } + + public void documentPartSaving(DocumentPartSavingArgs args) throws Exception { + // We can access the entire source document via the "Document" property. + Assert.assertTrue(args.getDocument().getOriginalFileName().endsWith("Rendering.docx")); + + String partType = ""; + + switch (mDocumentSplitCriteria) { + case DocumentSplitCriteria.PAGE_BREAK: + partType = "Page"; + break; + case DocumentSplitCriteria.COLUMN_BREAK: + partType = "Column"; + break; + case DocumentSplitCriteria.SECTION_BREAK: + partType = "Section"; + break; + case DocumentSplitCriteria.HEADING_PARAGRAPH: + partType = "Paragraph from heading"; + break; + } + + String partFileName = MessageFormat.format("{0} part {1}, of type {2}.{3}", mOutFileName, ++mCount, partType, FilenameUtils.getExtension(args.getDocumentPartFileName())); + + // Below are two ways of specifying where Aspose.Words will save each part of the document. + // 1 - Set a filename for the output part file: + args.setDocumentPartFileName(partFileName); + + // 2 - Create a custom stream for the output part file: + try (FileOutputStream outputStream = new FileOutputStream(getArtifactsDir() + partFileName)) { + args.setDocumentPartStream(outputStream); + } + + Assert.assertNotNull(args.getDocumentPartStream()); + Assert.assertFalse(args.getKeepDocumentPartStreamOpen()); + } + + private int mCount; + private final String mOutFileName; + private final int mDocumentSplitCriteria; + } + + /// + /// Sets custom filenames for image files that an HTML conversion creates. + /// + public static class SavedImageRename implements IImageSavingCallback { + public SavedImageRename(String outFileName) { + mOutFileName = outFileName; + } + + public void imageSaving(ImageSavingArgs args) throws Exception { + String imageFileName = MessageFormat.format("{0} shape {1}, of type {2}.{3}", mOutFileName, ++mCount, args.getCurrentShape().getShapeType(), FilenameUtils.getExtension(args.getImageFileName())); + + // Below are two ways of specifying where Aspose.Words will save each part of the document. + // 1 - Set a filename for the output image file: + args.setImageFileName(imageFileName); + + // 2 - Create a custom stream for the output image file: + args.setImageStream(new FileOutputStream(getArtifactsDir() + imageFileName)); + + Assert.assertNotNull(args.getImageStream()); + Assert.assertTrue(args.isImageAvailable()); + Assert.assertFalse(args.getKeepImageStreamOpen()); + } + + private int mCount; + private final String mOutFileName; + } + //ExEnd + + //ExStart + //ExFor:CssSavingArgs + //ExFor:CssSavingArgs.CssStream + //ExFor:CssSavingArgs.Document + //ExFor:CssSavingArgs.IsExportNeeded + //ExFor:CssSavingArgs.KeepCssStreamOpen + //ExFor:CssStyleSheetType + //ExFor:HtmlSaveOptions.CssSavingCallback + //ExFor:HtmlSaveOptions.CssStyleSheetFileName + //ExFor:HtmlSaveOptions.CssStyleSheetType + //ExFor:ICssSavingCallback + //ExFor:ICssSavingCallback.CssSaving(CssSavingArgs) + //ExSummary:Shows how to work with CSS stylesheets that an HTML conversion creates. + @Test //ExSkip + public void externalCssFilenames() throws Exception { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // Create an "HtmlFixedSaveOptions" object, which we can pass to the document's "Save" method + // to modify how we convert the document to HTML. + HtmlSaveOptions options = new HtmlSaveOptions(); + + // Set the "CssStylesheetType" property to "CssStyleSheetType.External" to + // accompany a saved HTML document with an external CSS stylesheet file. + options.setCssStyleSheetType(CssStyleSheetType.EXTERNAL); + + // Below are two ways of specifying directories and filenames for output CSS stylesheets. + // 1 - Use the "CssStyleSheetFileName" property to assign a filename to our stylesheet: + options.setCssStyleSheetFileName(getArtifactsDir() + "SavingCallback.ExternalCssFilenames.css"); + + // 2 - Use a custom callback to name our stylesheet: + options.setCssSavingCallback(new CustomCssSavingCallback(getArtifactsDir() + "SavingCallback.ExternalCssFilenames.css", true, false)); + + doc.save(getArtifactsDir() + "SavingCallback.ExternalCssFilenames.html", options); + } + + /// + /// Sets a custom filename, along with other parameters for an external CSS stylesheet. + /// + private static class CustomCssSavingCallback implements ICssSavingCallback { + public CustomCssSavingCallback(String cssDocFilename, boolean isExportNeeded, boolean keepCssStreamOpen) { + mCssTextFileName = cssDocFilename; + mIsExportNeeded = isExportNeeded; + mKeepCssStreamOpen = keepCssStreamOpen; + } + + public void cssSaving(CssSavingArgs args) throws Exception { + // We can access the entire source document via the "Document" property. + Assert.assertTrue(args.getDocument().getOriginalFileName().endsWith("Rendering.docx")); + + args.setCssStream(new FileOutputStream(mCssTextFileName)); + args.isExportNeeded(mIsExportNeeded); + args.setKeepCssStreamOpen(mKeepCssStreamOpen); + } + + private final String mCssTextFileName; + private final boolean mIsExportNeeded; + private final boolean mKeepCssStreamOpen; + } + //ExEnd +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExSection.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExSection.java new file mode 100644 index 00000000..968d6847 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExSection.java @@ -0,0 +1,575 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.awt.*; + +public class ExSection extends ApiExampleBase { + @Test + public void protect() throws Exception { + //ExStart + //ExFor:Document.Protect(ProtectionType) + //ExFor:ProtectionType + //ExFor:Section.ProtectedForForms + //ExSummary:Shows how to turn off protection for a section. + Document doc = new Document(); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Section 1. Hello world!"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + + builder.writeln("Section 2. Hello again!"); + builder.write("Please enter text here: "); + builder.insertTextInput("TextInput1", TextFormFieldType.REGULAR, "", "Placeholder text", 0); + + // Apply write protection to every section in the document. + doc.protect(ProtectionType.ALLOW_ONLY_FORM_FIELDS); + + // Turn off write protection for the first section. + doc.getSections().get(0).setProtectedForForms(false); + + // In this output document, we will be able to edit the first section freely, + // and we will only be able to edit the contents of the form field in the second section. + doc.save(getArtifactsDir() + "Section.Protect.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Section.Protect.docx"); + + Assert.assertFalse(doc.getSections().get(0).getProtectedForForms()); + Assert.assertTrue(doc.getSections().get(1).getProtectedForForms()); + } + + @Test + public void addRemove() throws Exception { + //ExStart + //ExFor:Document.Sections + //ExFor:Section.Clone + //ExFor:SectionCollection + //ExFor:NodeCollection.RemoveAt(Int32) + //ExSummary:Shows how to add and remove sections in a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Section 1"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.write("Section 2"); + + Assert.assertEquals("Section 1\fSection 2", doc.getText().trim()); + + // Delete the first section from the document. + doc.getSections().removeAt(0); + + Assert.assertEquals("Section 2", doc.getText().trim()); + + // Append a copy of what is now the first section to the end of the document. + int lastSectionIdx = doc.getSections().getCount() - 1; + Section newSection = doc.getSections().get(lastSectionIdx).deepClone(); + doc.getSections().add(newSection); + + Assert.assertEquals("Section 2\fSection 2", doc.getText().trim()); + //ExEnd + } + + @Test + public void firstAndLast() throws Exception { + //ExStart + //ExFor:Document.FirstSection + //ExFor:Document.LastSection + //ExSummary:Shows how to create a new section with a document builder. + Document doc = new Document(); + + // A blank document contains one section by default, + // which contains child nodes that we can edit. + Assert.assertEquals(1, doc.getSections().getCount()); + + // Use a document builder to add text to the first section. + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + // Create a second section by inserting a section break. + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + + Assert.assertEquals(2, doc.getSections().getCount()); + + // Each section has its own page setup settings. + // We can split the text in the second section into two columns. + // This will not affect the text in the first section. + doc.getLastSection().getPageSetup().getTextColumns().setCount(2); + builder.writeln("Column 1."); + builder.insertBreak(BreakType.COLUMN_BREAK); + builder.writeln("Column 2."); + + Assert.assertEquals(1, doc.getFirstSection().getPageSetup().getTextColumns().getCount()); + Assert.assertEquals(2, doc.getLastSection().getPageSetup().getTextColumns().getCount()); + + doc.save(getArtifactsDir() + "Section.Create.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Section.Create.docx"); + + Assert.assertEquals(1, doc.getFirstSection().getPageSetup().getTextColumns().getCount()); + Assert.assertEquals(2, doc.getLastSection().getPageSetup().getTextColumns().getCount()); + } + + @Test + public void createManually() throws Exception { + //ExStart + //ExFor:Node.GetText + //ExFor:CompositeNode.RemoveAllChildren + //ExFor:CompositeNode.AppendChild``1(``0) + //ExFor:Section + //ExFor:Section.#ctor + //ExFor:Section.PageSetup + //ExFor:PageSetup.SectionStart + //ExFor:PageSetup.PaperSize + //ExFor:SectionStart + //ExFor:PaperSize + //ExFor:Body + //ExFor:Body.#ctor + //ExFor:Paragraph + //ExFor:Paragraph.#ctor + //ExFor:Paragraph.ParagraphFormat + //ExFor:ParagraphFormat + //ExFor:ParagraphFormat.StyleName + //ExFor:ParagraphFormat.Alignment + //ExFor:ParagraphAlignment + //ExFor:Run + //ExFor:Run.#ctor(DocumentBase) + //ExFor:Run.Text + //ExFor:Inline.Font + //ExSummary:Shows how to construct an Aspose.Words document by hand. + Document doc = new Document(); + + // A blank document contains one section, one body and one paragraph. + // Call the "RemoveAllChildren" method to remove all those nodes, + // and end up with a document node with no children. + doc.removeAllChildren(); + + // This document now has no composite child nodes that we can add content to. + // If we wish to edit it, we will need to repopulate its node collection. + // First, create a new section, and then append it as a child to the root document node. + Section section = new Section(doc); + doc.appendChild(section); + + // Set some page setup properties for the section. + section.getPageSetup().setSectionStart(SectionStart.NEW_PAGE); + section.getPageSetup().setPaperSize(PaperSize.LETTER); + + // A section needs a body, which will contain and display all its contents + // on the page between the section's header and footer. + Body body = new Body(doc); + section.appendChild(body); + + // Create a paragraph, set some formatting properties, and then append it as a child to the body. + Paragraph para = new Paragraph(doc); + + para.getParagraphFormat().setStyleName("Heading 1"); + para.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + + body.appendChild(para); + + // Finally, add some content to do the document. Create a run, + // set its appearance and contents, and then append it as a child to the paragraph. + Run run = new Run(doc); + run.setText("Hello World!"); + run.getFont().setColor(Color.RED); + para.appendChild(run); + + Assert.assertEquals("Hello World!", doc.getText().trim()); + + doc.save(getArtifactsDir() + "Section.CreateManually.docx"); + //ExEnd + } + + @Test + public void ensureMinimum() throws Exception { + //ExStart + //ExFor:NodeCollection.Add + //ExFor:Section.EnsureMinimum + //ExFor:SectionCollection.Item(Int32) + //ExSummary:Shows how to prepare a new section node for editing. + Document doc = new Document(); + + // A blank document comes with a section, which has a body, which in turn has a paragraph. + // We can add contents to this document by adding elements such as text runs, shapes, or tables to that paragraph. + Assert.assertEquals(NodeType.SECTION, doc.getChild(NodeType.ANY, 0, true).getNodeType()); + Assert.assertEquals(NodeType.BODY, doc.getSections().get(0).getChild(NodeType.ANY, 0, true).getNodeType()); + Assert.assertEquals(NodeType.PARAGRAPH, doc.getSections().get(0).getBody().getChild(NodeType.ANY, 0, true).getNodeType()); + + // If we add a new section like this, it will not have a body, or any other child nodes. + doc.getSections().add(new Section(doc)); + + Assert.assertEquals(0, doc.getSections().get(1).getChildNodes(NodeType.ANY, true).getCount()); + + // Run the "EnsureMinimum" method to add a body and a paragraph to this section to begin editing it. + doc.getLastSection().ensureMinimum(); + + Assert.assertEquals(NodeType.BODY, doc.getSections().get(1).getChild(NodeType.ANY, 0, true).getNodeType()); + Assert.assertEquals(NodeType.PARAGRAPH, doc.getSections().get(1).getBody().getChild(NodeType.ANY, 0, true).getNodeType()); + + doc.getSections().get(0).getBody().getFirstParagraph().appendChild(new Run(doc, "Hello world!")); + + Assert.assertEquals("Hello world!", doc.getText().trim()); + //ExEnd + } + + @Test + public void bodyEnsureMinimum() throws Exception { + //ExStart + //ExFor:Section.Body + //ExFor:Body.EnsureMinimum + //ExSummary:Clears main text from all sections from the document leaving the sections themselves. + Document doc = new Document(); + + // A blank document contains one section, one body and one paragraph. + // Call the "RemoveAllChildren" method to remove all those nodes, + // and end up with a document node with no children. + doc.removeAllChildren(); + + // This document now has no composite child nodes that we can add content to. + // If we wish to edit it, we will need to repopulate its node collection. + // First, create a new section, and then append it as a child to the root document node. + Section section = new Section(doc); + doc.appendChild(section); + + // A section needs a body, which will contain and display all its contents + // on the page between the section's header and footer. + Body body = new Body(doc); + section.appendChild(body); + + // This body has no children, so we cannot add runs to it yet. + Assert.assertEquals(0, doc.getFirstSection().getBody().getChildNodes(NodeType.ANY, true).getCount()); + + // Call the "EnsureMinimum" to make sure that this body contains at least one empty paragraph. + body.ensureMinimum(); + + // Now, we can add runs to the body, and get the document to display them. + body.getFirstParagraph().appendChild(new Run(doc, "Hello world!")); + + Assert.assertEquals("Hello world!", doc.getText().trim()); + //ExEnd + } + + @Test + public void bodyChildNodes() throws Exception { + //ExStart + //ExFor:Body.NodeType + //ExFor:HeaderFooter.NodeType + //ExFor:Document.FirstSection + //ExSummary:Shows how to iterate through the children of a composite node. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Section 1"); + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.write("Primary header"); + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + builder.write("Primary footer"); + + Section section = doc.getFirstSection(); + + // A Section is a composite node and can contain child nodes, + // but only if those child nodes are of a "Body" or "HeaderFooter" node type. + for (Node node : section) { + switch (node.getNodeType()) { + case NodeType.BODY: { + Body body = (Body) node; + + System.out.println("Body:"); + System.out.println("\t\"{body.GetText().Trim()}\""); + break; + } + case NodeType.HEADER_FOOTER: { + HeaderFooter headerFooter = (HeaderFooter) node; + + System.out.println("HeaderFooter type: {headerFooter.HeaderFooterType}:"); + System.out.println("\t\"{headerFooter.GetText().Trim()}\""); + break; + } + default: { + throw new Exception("Unexpected node type in a section."); + } + } + } + //ExEnd + } + + @Test + public void clear() throws Exception { + //ExStart + //ExFor:NodeCollection.Clear + //ExSummary:Shows how to remove all sections from a document. + Document doc = new Document(getMyDir() + "Document.docx"); + + // This document has one section with a few child nodes containing and displaying all the document's contents. + Assert.assertEquals(doc.getSections().getCount(), 1); + Assert.assertEquals(doc.getSections().get(0).getChildNodes(NodeType.ANY, true).getCount(), 17); + Assert.assertEquals("Hello World!\r\rHello Word!\r\r\rHello World!", doc.getText().trim()); + + // Clear the collection of sections, which will remove all of the document's children. + doc.getSections().clear(); + + Assert.assertEquals(0, doc.getChildNodes(NodeType.ANY, true).getCount()); + Assert.assertEquals("", doc.getText().trim()); + //ExEnd + } + + @Test + public void prependAppendContent() throws Exception { + //ExStart + //ExFor:Section.AppendContent + //ExFor:Section.PrependContent + //ExSummary:Shows how to append the contents of a section to another section. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Section 1"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.write("Section 2"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.write("Section 3"); + + Section section = doc.getSections().get(2); + + Assert.assertEquals("Section 3" + ControlChar.SECTION_BREAK, section.getText()); + + // Insert the contents of the first section to the beginning of the third section. + Section sectionToPrepend = doc.getSections().get(0); + section.prependContent(sectionToPrepend); + + // Insert the contents of the second section to the end of the third section. + Section sectionToAppend = doc.getSections().get(1); + section.appendContent(sectionToAppend); + + // The "PrependContent" and "AppendContent" methods did not create any new sections. + Assert.assertEquals(3, doc.getSections().getCount()); + Assert.assertEquals("Section 1" + ControlChar.PARAGRAPH_BREAK + + "Section 3" + ControlChar.PARAGRAPH_BREAK + + "Section 2" + ControlChar.SECTION_BREAK, section.getText()); + //ExEnd + } + + @Test + public void clearContent() throws Exception { + //ExStart + //ExFor:Section.ClearContent + //ExSummary:Shows how to clear the contents of a section. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Hello world!"); + + Assert.assertEquals("Hello world!", doc.getText().trim()); + Assert.assertEquals(1, doc.getFirstSection().getBody().getParagraphs().getCount()); + + // Running the "ClearContent" method will remove all the section contents + // but leave a blank paragraph to add content again. + doc.getFirstSection().clearContent(); + + Assert.assertEquals("", doc.getText().trim()); + Assert.assertEquals(1, doc.getFirstSection().getBody().getParagraphs().getCount()); + //ExEnd + } + + @Test + public void clearHeadersFooters() throws Exception { + //ExStart + //ExFor:Section.ClearHeadersFooters + //ExSummary:Shows how to clear the contents of all headers and footers in a section. + Document doc = new Document(); + + Assert.assertEquals(0, doc.getFirstSection().getHeadersFooters().getCount()); + + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.writeln("This is the primary header."); + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + builder.writeln("This is the primary footer."); + + Assert.assertEquals(2, doc.getFirstSection().getHeadersFooters().getCount()); + + Assert.assertEquals("This is the primary header.", doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.HEADER_PRIMARY).getText().trim()); + Assert.assertEquals("This is the primary footer.", doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY).getText().trim()); + + // Empty all the headers and footers in this section of all their contents. + // The headers and footers themselves will still be present but will have nothing to display. + doc.getFirstSection().clearHeadersFooters(); + + Assert.assertEquals(2, doc.getFirstSection().getHeadersFooters().getCount()); + + Assert.assertEquals("", doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.HEADER_PRIMARY).getText().trim()); + Assert.assertEquals("", doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY).getText().trim()); + //ExEnd + } + + @Test + public void deleteHeaderFooterShapes() throws Exception { + //ExStart + //ExFor:Section.DeleteHeaderFooterShapes + //ExSummary:Shows how to remove all shapes from all headers footers in a section. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a primary header with a shape. + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.insertShape(ShapeType.RECTANGLE, 100.0, 100.0); + + // Create a primary footer with an image. + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + builder.insertImage(getImageDir() + "Logo Icon.ico"); + + Assert.assertEquals(1, doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.HEADER_PRIMARY).getChildNodes(NodeType.SHAPE, true).getCount()); + Assert.assertEquals(1, doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY).getChildNodes(NodeType.SHAPE, true).getCount()); + + // Remove all shapes from the headers and footers in the first section. + doc.getFirstSection().deleteHeaderFooterShapes(); + + Assert.assertEquals(0, doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.HEADER_PRIMARY).getChildNodes(NodeType.SHAPE, true).getCount()); + Assert.assertEquals(0, doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY).getChildNodes(NodeType.SHAPE, true).getCount()); + //ExEnd + } + + @Test + public void sectionsCloneSection() throws Exception { + Document doc = new Document(getMyDir() + "Document.docx"); + Section cloneSection = doc.getSections().get(0).deepClone(); + } + + @Test + public void sectionsImportSection() throws Exception { + Document srcDoc = new Document(getMyDir() + "Document.docx"); + Document dstDoc = new Document(); + + Section sourceSection = srcDoc.getSections().get(0); + Section newSection = (Section) dstDoc.importNode(sourceSection, true); + dstDoc.getSections().add(newSection); + } + + @Test + public void migrateFrom2XImportSection() throws Exception { + Document srcDoc = new Document(); + Document dstDoc = new Document(); + + Section sourceSection = srcDoc.getSections().get(0); + Section newSection = (Section) dstDoc.importNode(sourceSection, true); + dstDoc.getSections().add(newSection); + } + + @Test + public void modifyPageSetupInAllSections() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Section 1"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.write("Section 2"); + + // It is important to understand that a document can contain many sections, + // and each section has its page setup. In this case, we want to modify them all. + for (Section section : doc.getSections()) + section.getPageSetup().setPaperSize(PaperSize.LETTER); + + doc.save(getArtifactsDir() + "Section.ModifyPageSetupInAllSections.doc"); + } + + @Test + public void cultureInfoPageSetupDefaults() throws Exception { + CurrentThreadSettings.setLocale("en-us"); + + Document docEn = new Document(); + + // Assert that page defaults comply with current culture info. + Section sectionEn = docEn.getSections().get(0); + Assert.assertEquals(sectionEn.getPageSetup().getLeftMargin(), 72.0); // 2.54 cm + Assert.assertEquals(sectionEn.getPageSetup().getRightMargin(), 72.0); // 2.54 cm + Assert.assertEquals(sectionEn.getPageSetup().getTopMargin(), 72.0); // 2.54 cm + Assert.assertEquals(sectionEn.getPageSetup().getBottomMargin(), 72.0); // 2.54 cm + Assert.assertEquals(sectionEn.getPageSetup().getHeaderDistance(), 36.0); // 1.27 cm + Assert.assertEquals(sectionEn.getPageSetup().getFooterDistance(), 36.0); // 1.27 cm + Assert.assertEquals(sectionEn.getPageSetup().getTextColumns().getSpacing(), 36.0); // 1.27 cm + + // Change the culture and assert that the page defaults are changed. + CurrentThreadSettings.setLocale("de-de"); + + Document docDe = new Document(); + + Section sectionDe = docDe.getSections().get(0); + Assert.assertEquals(sectionDe.getPageSetup().getLeftMargin(), 70.85); // 2.5 cm + Assert.assertEquals(sectionDe.getPageSetup().getRightMargin(), 70.85); // 2.5 cm + Assert.assertEquals(sectionDe.getPageSetup().getTopMargin(), 70.85); // 2.5 cm + Assert.assertEquals(sectionDe.getPageSetup().getBottomMargin(), 56.7); // 2 cm + Assert.assertEquals(sectionDe.getPageSetup().getHeaderDistance(), 35.4); // 1.25 cm + Assert.assertEquals(sectionDe.getPageSetup().getFooterDistance(), 35.4); // 1.25 cm + Assert.assertEquals(sectionDe.getPageSetup().getTextColumns().getSpacing(), 35.4); // 1.25 cm + + // Change page defaults. + sectionDe.getPageSetup().setLeftMargin(90.0); // 3.17 cm + sectionDe.getPageSetup().setRightMargin(90.0); // 3.17 cm + sectionDe.getPageSetup().setTopMargin(72.0); // 2.54 cm + sectionDe.getPageSetup().setBottomMargin(72.0); // 2.54 cm + sectionDe.getPageSetup().setHeaderDistance(35.4); // 1.25 cm + sectionDe.getPageSetup().setFooterDistance(35.4); // 1.25 cm + sectionDe.getPageSetup().getTextColumns().setSpacing(35.4); // 1.25 cm + + docDe = DocumentHelper.saveOpen(docDe); + + Section sectionDeAfter = docDe.getSections().get(0); + Assert.assertEquals(sectionDeAfter.getPageSetup().getLeftMargin(), 90.0); // 3.17 cm + Assert.assertEquals(sectionDeAfter.getPageSetup().getRightMargin(), 90.0); // 3.17 cm + Assert.assertEquals(sectionDeAfter.getPageSetup().getTopMargin(), 72.0); // 2.54 cm + Assert.assertEquals(sectionDeAfter.getPageSetup().getBottomMargin(), 72.0); // 2.54 cm + Assert.assertEquals(sectionDeAfter.getPageSetup().getHeaderDistance(), 35.4); // 1.25 cm + Assert.assertEquals(sectionDeAfter.getPageSetup().getFooterDistance(), 35.4); // 1.25 cm + Assert.assertEquals(sectionDeAfter.getPageSetup().getTextColumns().getSpacing(), 35.4); // 1.25 cm + } + + @Test + public void preserveWatermarks() throws Exception + { + //ExStart:PreserveWatermarks + //GistId:0ede368e82d1e97d02e615a76923846b + //ExFor:Section.ClearHeadersFooters(bool) + //ExSummary:Shows how to clear the contents of header and footer with or without a watermark. + Document doc = new Document(getMyDir() + "Header and footer types.docx"); + + // Add a plain text watermark. + doc.getWatermark().setText("Aspose Watermark"); + + // Make sure the headers and footers have content. + HeaderFooterCollection headersFooters = doc.getFirstSection().getHeadersFooters(); + Assert.assertEquals("First header", headersFooters.getByHeaderFooterType(HeaderFooterType.HEADER_FIRST).getText().trim()); + Assert.assertEquals("Second header", headersFooters.getByHeaderFooterType(HeaderFooterType.HEADER_EVEN).getText().trim()); + Assert.assertEquals("Third header", headersFooters.getByHeaderFooterType(HeaderFooterType.HEADER_PRIMARY).getText().trim()); + Assert.assertEquals("First footer", headersFooters.getByHeaderFooterType(HeaderFooterType.FOOTER_FIRST).getText().trim()); + Assert.assertEquals("Second footer", headersFooters.getByHeaderFooterType(HeaderFooterType.FOOTER_EVEN).getText().trim()); + Assert.assertEquals("Third footer", headersFooters.getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY).getText().trim()); + + // Removes all header and footer content except watermarks. + doc.getFirstSection().clearHeadersFooters(true); + + headersFooters = doc.getFirstSection().getHeadersFooters(); + Assert.assertEquals("", headersFooters.getByHeaderFooterType(HeaderFooterType.HEADER_FIRST).getText().trim()); + Assert.assertEquals("", headersFooters.getByHeaderFooterType(HeaderFooterType.HEADER_EVEN).getText().trim()); + Assert.assertEquals("", headersFooters.getByHeaderFooterType(HeaderFooterType.HEADER_PRIMARY).getText().trim()); + Assert.assertEquals("", headersFooters.getByHeaderFooterType(HeaderFooterType.FOOTER_FIRST).getText().trim()); + Assert.assertEquals("", headersFooters.getByHeaderFooterType(HeaderFooterType.FOOTER_EVEN).getText().trim()); + Assert.assertEquals("", headersFooters.getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY).getText().trim()); + Assert.assertEquals(WatermarkType.TEXT, doc.getWatermark().getType()); + + // Removes all header and footer content including watermarks. + doc.getFirstSection().clearHeadersFooters(false); + Assert.assertEquals(WatermarkType.NONE, doc.getWatermark().getType()); + //ExEnd:PreserveWatermarks + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExShape.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExShape.java new file mode 100644 index 00000000..ac4953fa --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExShape.java @@ -0,0 +1,3527 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.Shape; +import com.aspose.words.Stroke; +import com.aspose.words.*; +import org.apache.commons.collections4.IterableUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +@Test +public class ExShape extends ApiExampleBase { + @Test + public void altText() throws Exception { + //ExStart + //ExFor:ShapeBase.AlternativeText + //ExFor:ShapeBase.Name + //ExSummary:Shows how to use a shape's alternative text. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + Shape shape = builder.insertShape(ShapeType.CUBE, 150.0, 150.0); + shape.setName("MyCube"); + + shape.setAlternativeText("Alt text for MyCube."); + + // We can access the alternative text of a shape by right-clicking it, and then via "Format AutoShape" -> "Alt Text". + doc.save(getArtifactsDir() + "Shape.AltText.docx"); + + // Save the document to HTML, and then delete the linked image that belongs to our shape. + // The browser that is reading our HTML will display the alt text in place of the missing image. + doc.save(getArtifactsDir() + "Shape.AltText.html"); + Assert.assertTrue(new File(getArtifactsDir() + "Shape.AltText.001.png").exists()); //ExSkip + new File(getArtifactsDir() + "Shape.AltText.001.png").delete(); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.AltText.docx"); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.CUBE, "MyCube", 150.0d, 150.0d, 0.0, 0.0, shape); + Assert.assertEquals("Alt text for MyCube.", shape.getAlternativeText()); + Assert.assertEquals("Times New Roman", shape.getFont().getName()); + + doc = new Document(getArtifactsDir() + "Shape.AltText.html"); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.IMAGE, "", 151.5d, 151.5d, 0.0, 0.0, shape); + Assert.assertEquals("Alt text for MyCube.", shape.getAlternativeText()); + + TestUtil.fileContainsString( + "\"Alt", + getArtifactsDir() + "Shape.AltText.html"); + } + + @Test(dataProvider = "fontDataProvider") + public void font(boolean hideShape) throws Exception { + //ExStart + //ExFor:ShapeBase.Font + //ExFor:ShapeBase.ParentParagraph + //ExSummary:Shows how to insert a text box, and set the font of its contents. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + + Shape shape = builder.insertShape(ShapeType.TEXT_BOX, 300.0, 50.0); + builder.moveTo(shape.getLastParagraph()); + builder.write("This text is inside the text box."); + + // Set the "Hidden" property of the shape's "Font" object to "true" to hide the text box from sight + // and collapse the space that it would normally occupy. + // Set the "Hidden" property of the shape's "Font" object to "false" to leave the text box visible. + shape.getFont().setHidden(hideShape); + + // If the shape is visible, we will modify its appearance via the font object. + if (!hideShape) { + shape.getFont().setHighlightColor(Color.LIGHT_GRAY); + shape.getFont().setColor(Color.RED); + shape.getFont().setUnderline(Underline.DASH); + } + + // Move the builder out of the text box back into the main document. + builder.moveTo(shape.getParentParagraph()); + + builder.writeln("\nThis text is outside the text box."); + + doc.save(getArtifactsDir() + "Shape.Font.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.Font.docx"); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(hideShape, shape.getFont().getHidden()); + + if (hideShape) { + Assert.assertEquals(0, shape.getFont().getHighlightColor().getRGB()); + Assert.assertEquals(0, shape.getFont().getColor().getRGB()); + Assert.assertEquals(Underline.NONE, shape.getFont().getUnderline()); + } else { + Assert.assertEquals(Color.LIGHT_GRAY.getRGB(), shape.getFont().getHighlightColor().getRGB()); + Assert.assertEquals(Color.RED.getRGB(), shape.getFont().getColor().getRGB()); + Assert.assertEquals(Underline.DASH, shape.getFont().getUnderline()); + } + + TestUtil.verifyShape(ShapeType.TEXT_BOX, "TextBox 100002", 300.0d, 50.0d, 0.0, 0.0, shape); + Assert.assertEquals("This text is inside the text box.", shape.getText().trim()); + Assert.assertEquals("Hello world!\rThis text is inside the text box.\r\rThis text is outside the text box.", doc.getText().trim()); + } + + @DataProvider(name = "fontDataProvider") + public static Object[][] fontDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void rotate() throws Exception { + //ExStart + //ExFor:ShapeBase.CanHaveImage + //ExFor:ShapeBase.Rotation + //ExSummary:Shows how to insert and rotate an image. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a shape with an image. + Shape shape = builder.insertImage(getImageDir() + "Logo.jpg"); + Assert.assertTrue(shape.canHaveImage()); + Assert.assertTrue(shape.hasImage()); + + // Rotate the image 45 degrees clockwise. + shape.setRotation(45.0); + + doc.save(getArtifactsDir() + "Shape.Rotate.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.Rotate.docx"); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.IMAGE, "", 300.0d, 300.0d, 0.0, 0.0, shape); + Assert.assertTrue(shape.canHaveImage()); + Assert.assertTrue(shape.hasImage()); + Assert.assertEquals(45.0d, shape.getRotation()); + } + + @Test + public void coordinates() throws Exception { + //ExStart + //ExFor:ShapeBase.DistanceBottom + //ExFor:ShapeBase.DistanceLeft + //ExFor:ShapeBase.DistanceRight + //ExFor:ShapeBase.DistanceTop + //ExSummary:Shows how to set the wrapping distance for a text that surrounds a shape. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a rectangle and, get the text to wrap tightly around its bounds. + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 150.0, 150.0); + shape.setWrapType(WrapType.TIGHT); + + // Set the minimum distance between the shape and surrounding text to 40pt from all sides. + shape.setDistanceTop(40.0); + shape.setDistanceBottom(40.0); + shape.setDistanceLeft(40.0); + shape.setDistanceRight(40.0); + + // Move the shape closer to the center of the page, and then rotate the shape 60 degrees clockwise. + shape.setTop(75.0); + shape.setLeft(150.0); + shape.setRotation(60.0); + + // Add text that will wrap around the shape. + builder.getFont().setSize(24.0d); + builder.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " + + "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."); + + doc.save(getArtifactsDir() + "Shape.Coordinates.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.Coordinates.docx"); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.RECTANGLE, "Rectangle 100002", 150.0d, 150.0d, 75.0d, 150.0d, shape); + Assert.assertEquals(40.0d, shape.getDistanceBottom()); + Assert.assertEquals(40.0d, shape.getDistanceLeft()); + Assert.assertEquals(40.0d, shape.getDistanceRight()); + Assert.assertEquals(40.0d, shape.getDistanceTop()); + Assert.assertEquals(60.0d, shape.getRotation()); + } + + @Test + public void groupShape() throws Exception { + //ExStart + //ExFor:ShapeBase.Bounds + //ExFor:ShapeBase.CoordOrigin + //ExFor:ShapeBase.CoordSize + //ExSummary:Shows how to create and populate a group shape. + Document doc = new Document(); + + // Create a group shape. A group shape can display a collection of child shape nodes. + // In Microsoft Word, clicking within the group shape's boundary or on one of the group shape's child shapes will + // select all the other child shapes within this group and allow us to scale and move all the shapes at once. + GroupShape group = new GroupShape(doc); + + Assert.assertEquals(WrapType.NONE, group.getWrapType()); + + // Create a 400pt x 400pt group shape and place it at the document's floating shape coordinate origin. + group.setBounds(new Rectangle2D.Float(0f, 0f, 400f, 400f)); + + // Set the group's internal coordinate plane size to 500 x 500pt. + // The top left corner of the group will have an x and y coordinate of (0, 0), + // and the bottom right corner will have an x and y coordinate of (500, 500). + group.setCoordSize(new Dimension(500, 500)); + + // Set the coordinates of the top left corner of the group to (-250, -250). + // The group's center will now have an x and y coordinate value of (0, 0), + // and the bottom right corner will be at (250, 250). + group.setCoordOrigin(new Point(-250, -250)); + + Shape rectangleShape = new Shape(doc, ShapeType.RECTANGLE); + rectangleShape.setWidth(group.getCoordSize().width); + rectangleShape.setHeight(group.getCoordSize().height); + rectangleShape.setLeft(group.getCoordOrigin().x); + rectangleShape.setTop(group.getCoordOrigin().y); + + // Create a rectangle that will display the boundary of this group shape and add it to the group. + group.appendChild(rectangleShape); + + // Once a shape is a part of a group shape, we can access it as a child node and then modify it. + ((Shape) group.getChild(NodeType.SHAPE, 0, true)).getStroke().setDashStyle(DashStyle.DASH); + + Shape starShape = new Shape(doc, ShapeType.STAR); + starShape.setWidth(20.0); + starShape.setHeight(20.0); + starShape.setLeft(-10); + starShape.setTop(-10); + starShape.setFillColor(Color.RED); + + // Create a small red star and insert it into the group. + // Line up the shape with the group's coordinate origin, which we have moved to the center. + group.appendChild(starShape); + + rectangleShape = new Shape(doc, ShapeType.RECTANGLE); + rectangleShape.setWidth(250.0); + rectangleShape.setHeight(250.0); + rectangleShape.setLeft(-250); + rectangleShape.setTop(-250); + rectangleShape.setFillColor(Color.BLUE); + + // Insert a rectangle, and then insert a slightly smaller rectangle in the same place with an image. + // Newer shapes that we add to the group overlap older shapes. The light blue rectangle will partially overlap the red star, + // and then the shape with the image will overlap the light blue rectangle, using it as a frame. + // We cannot use the "ZOrder" properties of shapes to manipulate their arrangement within a group shape. + group.appendChild(rectangleShape); + + Shape imageShape = new Shape(doc, ShapeType.IMAGE); + imageShape.setWidth(200.0); + imageShape.setHeight(200.0); + imageShape.setLeft(-225); + imageShape.setTop(-225); + + group.appendChild(imageShape); + + ((Shape) group.getChild(NodeType.SHAPE, 3, true)).getImageData().setImage(getImageDir() + "Logo.jpg"); + + Shape textboxShape = new Shape(doc, ShapeType.TEXT_BOX); + textboxShape.setWidth(200.0); + textboxShape.setHeight(50.0); + textboxShape.setLeft(group.getCoordSize().width + new Point(group.getCoordOrigin()).x - 200); + textboxShape.setTop(group.getCoordSize().height + new Point(group.getCoordOrigin()).y); + + // Insert a text box into the group shape. Set the "Left" property so that the text box's right edge + // touches the right boundary of the group shape. Set the "Top" property so that the text box sits outside + // the boundary of the group shape, with its top size lined up along the group shape's bottom margin. + group.appendChild(textboxShape); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertNode(group); + builder.moveTo(((Shape) group.getChild(NodeType.SHAPE, 4, true)).appendChild(new Paragraph(doc))); + builder.write("Hello world!"); + + doc.save(getArtifactsDir() + "Shape.GroupShape.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.GroupShape.docx"); + group = (GroupShape) doc.getChild(NodeType.GROUP_SHAPE, 0, true); + + Assert.assertEquals(new Rectangle2D.Float(0f, 0f, 400f, 400f), group.getBounds()); + Assert.assertEquals(new Dimension(500, 500), group.getCoordSize()); + Assert.assertEquals(new Point(-250, -250), group.getCoordOrigin()); + + TestUtil.verifyShape(ShapeType.RECTANGLE, "", 500.0d, 500.0d, -250.0d, -250.0d, (Shape) group.getChild(NodeType.SHAPE, 0, true)); + TestUtil.verifyShape(ShapeType.STAR, "", 20.0d, 20.0d, -10.0d, -10.0d, (Shape) group.getChild(NodeType.SHAPE, 1, true)); + TestUtil.verifyShape(ShapeType.RECTANGLE, "", 250.0d, 250.0d, -250.0d, -250.0d, (Shape) group.getChild(NodeType.SHAPE, 2, true)); + TestUtil.verifyShape(ShapeType.IMAGE, "", 200.0d, 200.0d, -225.0d, -225.0d, (Shape) group.getChild(NodeType.SHAPE, 3, true)); + TestUtil.verifyShape(ShapeType.TEXT_BOX, "", 200.0d, 50.0d, 250.0d, 50.0d, (Shape) group.getChild(NodeType.SHAPE, 4, true)); + } + + @Test + public void isTopLevel() throws Exception { + //ExStart + //ExFor:ShapeBase.IsTopLevel + //ExSummary:Shows how to tell whether a shape is a part of a group shape. + Document doc = new Document(); + + Shape shape = new Shape(doc, ShapeType.RECTANGLE); + shape.setWidth(200.0); + shape.setHeight(200.0); + shape.setWrapType(WrapType.NONE); + + // A shape by default is not part of any group shape, and therefore has the "IsTopLevel" property set to "true". + Assert.assertTrue(shape.isTopLevel()); + + GroupShape group = new GroupShape(doc); + group.appendChild(shape); + + // Once we assimilate a shape into a group shape, the "IsTopLevel" property changes to "false". + Assert.assertFalse(shape.isTopLevel()); + //ExEnd + } + + @Test + public void localToParent() throws Exception { + //ExStart + //ExFor:ShapeBase.CoordOrigin + //ExFor:ShapeBase.CoordSize + //ExFor:ShapeBase.LocalToParent(PointF) + //ExSummary:Shows how to translate the x and y coordinate location on a shape's coordinate plane to a location on the parent shape's coordinate plane. + Document doc = new Document(); + + // Insert a group shape, and place it 100 points below and to the right of + // the document's x and Y coordinate origin point. + GroupShape group = new GroupShape(doc); + group.setBounds(new Rectangle2D.Float(100f, 100f, 500f, 500f)); + + // Use the "LocalToParent" method to determine that (0, 0) on the group's internal x and y coordinates + // lies on (100, 100) of its parent shape's coordinate system. The group shape's parent is the document itself. + Assert.assertEquals(new Point2D.Float(100f, 100f), group.localToParent(new Point2D.Float(0f, 0f))); + + // By default, a shape's internal coordinate plane has the top left corner at (0, 0), + // and the bottom right corner at (1000, 1000). Due to its size, our group shape covers an area of 500pt x 500pt + // in the document's plane. This means that a movement of 1pt on the document's coordinate plane will translate + // to a movement of 2pts on the group shape's coordinate plane. + Assert.assertEquals(new Point2D.Float(150f, 150f), group.localToParent(new Point2D.Float(100f, 100f))); + Assert.assertEquals(new Point2D.Float(200f, 200f), group.localToParent(new Point2D.Float(200f, 200f))); + Assert.assertEquals(new Point2D.Float(250f, 250f), group.localToParent(new Point2D.Float(300f, 300f))); + + // Move the group shape's x and y axis origin from the top left corner to the center. + // This will offset the group's internal coordinates relative to the document's coordinates even further. + group.setCoordOrigin(new Point(-250, -250)); + + Assert.assertEquals(new Point2D.Float(375f, 375f), group.localToParent(new Point2D.Float(300f, 300f))); + + // Changing the scale of the coordinate plane will also affect relative locations. + group.setCoordSize(new Dimension(500, 500)); + + Assert.assertEquals(new Point2D.Float(650f, 650f), group.localToParent(new Point2D.Float(300f, 300f))); + + // If we wish to add a shape to this group while defining its location based on a location in the document, + // we will need to first confirm a location in the group shape that will match the document's location. + Assert.assertEquals(new Point2D.Float(700f, 700f), group.localToParent(new Point2D.Float(350f, 350f))); + + Shape shape = new Shape(doc, ShapeType.RECTANGLE); + { + shape.setWidth(100.0); + shape.setHeight(100.0); + shape.setLeft(700.0); + shape.setTop(700.0); + } + + group.appendChild(shape); + doc.getFirstSection().getBody().getFirstParagraph().appendChild(group); + + doc.save(getArtifactsDir() + "Shape.LocalToParent.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.LocalToParent.docx"); + group = (GroupShape) doc.getChild(NodeType.GROUP_SHAPE, 0, true); + + Assert.assertEquals(new Rectangle2D.Float(100f, 100f, 500f, 500f), group.getBounds()); + Assert.assertEquals(new Dimension(500, 500), group.getCoordSize()); + Assert.assertEquals(new Point(-250, -250), group.getCoordOrigin()); + } + + @Test(dataProvider = "anchorLockedDataProvider") + public void anchorLocked(boolean anchorLocked) throws Exception { + //ExStart + //ExFor:ShapeBase.AnchorLocked + //ExSummary:Shows how to lock or unlock a shape's paragraph anchor. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + + builder.write("Our shape will have an anchor attached to this paragraph."); + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 200.0, 160.0); + shape.setWrapType(WrapType.NONE); + builder.insertBreak(BreakType.PARAGRAPH_BREAK); + + builder.writeln("Hello again!"); + + // Set the "AnchorLocked" property to "true" to prevent the shape's anchor + // from moving when moving the shape in Microsoft Word. + // Set the "AnchorLocked" property to "false" to allow any movement of the shape + // to also move its anchor to any other paragraph that the shape ends up close to. + shape.setAnchorLocked(anchorLocked); + + // If the shape does not have a visible anchor symbol to its left, + // we will need to enable visible anchors via "Options" -> "Display" -> "Object Anchors". + doc.save(getArtifactsDir() + "Shape.AnchorLocked.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.AnchorLocked.docx"); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(anchorLocked, shape.getAnchorLocked()); + } + + @DataProvider(name = "anchorLockedDataProvider") + public static Object[][] anchorLockedDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void deleteAllShapes() throws Exception { + //ExStart + //ExFor:Shape + //ExSummary:Shows how to delete all shapes from a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert two shapes along with a group shape with another shape inside it. + builder.insertShape(ShapeType.RECTANGLE, 400.0, 200.0); + builder.insertShape(ShapeType.STAR, 300.0, 300.0); + + GroupShape group = new GroupShape(doc); + group.setBounds(new Rectangle2D.Float(100f, 50f, 200f, 100f)); + group.setCoordOrigin(new Point(-1000, -500)); + + Shape subShape = new Shape(doc, ShapeType.CUBE); + subShape.setWidth(500.0); + subShape.setHeight(700.0); + subShape.setLeft(0.0); + subShape.setTop(0.0); + + group.appendChild(subShape); + builder.insertNode(group); + + Assert.assertEquals(doc.getChildNodes(NodeType.SHAPE, true).getCount(), 3); + Assert.assertEquals(doc.getChildNodes(NodeType.GROUP_SHAPE, true).getCount(), 1); + + // Remove all Shape nodes from the document. + NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); + shapes.clear(); + + // All shapes are gone, but the group shape is still in the document. + Assert.assertEquals(doc.getChildNodes(NodeType.GROUP_SHAPE, true).getCount(), 1); + Assert.assertEquals(doc.getChildNodes(NodeType.SHAPE, true).getCount(), 0); + + // Remove all group shapes separately. + NodeCollection groupShapes = doc.getChildNodes(NodeType.GROUP_SHAPE, true); + groupShapes.clear(); + + Assert.assertEquals(doc.getChildNodes(NodeType.GROUP_SHAPE, true).getCount(), 0); + Assert.assertEquals(doc.getChildNodes(NodeType.SHAPE, true).getCount(), 0); + //ExEnd + } + + @Test + public void isInline() throws Exception { + //ExStart + //ExFor:ShapeBase.IsInline + //ExSummary:Shows how to determine whether a shape is inline or floating. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are two wrapping types that shapes may have. + // 1 - Inline: + builder.write("Hello world! "); + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 100.0, 100.0); + shape.setFillColor(Color.BLUE); + builder.write(" Hello again."); + + // An inline shape sits inside a paragraph among other paragraph elements, such as runs of text. + // In Microsoft Word, we may click and drag the shape to any paragraph as if it is a character. + // If the shape is large, it will affect vertical paragraph spacing. + // We cannot move this shape to a place with no paragraph. + Assert.assertEquals(WrapType.INLINE, shape.getWrapType()); + Assert.assertTrue(shape.isInline()); + + // 2 - Floating: + shape = builder.insertShape(ShapeType.RECTANGLE, RelativeHorizontalPosition.LEFT_MARGIN, 200.0, + RelativeVerticalPosition.TOP_MARGIN, 200.0, 100.0, 100.0, WrapType.NONE); + shape.setFillColor(Color.ORANGE); + + // A floating shape belongs to the paragraph that we insert it into, + // which we can determine by an anchor symbol that appears when we click the shape. + // If the shape does not have a visible anchor symbol to its left, + // we will need to enable visible anchors via "Options" -> "Display" -> "Object Anchors". + // In Microsoft Word, we may left click and drag this shape freely to any location. + Assert.assertEquals(WrapType.NONE, shape.getWrapType()); + Assert.assertFalse(shape.isInline()); + + doc.save(getArtifactsDir() + "Shape.IsInline.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.IsInline.docx"); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.RECTANGLE, "Rectangle 100002", 100.0, 100.0, 0.0, 0.0, shape); + Assert.assertEquals(Color.BLUE.getRGB(), shape.getFillColor().getRGB()); + Assert.assertEquals(WrapType.INLINE, shape.getWrapType()); + Assert.assertTrue(shape.isInline()); + + shape = (Shape) doc.getChild(NodeType.SHAPE, 1, true); + + TestUtil.verifyShape(ShapeType.RECTANGLE, "Rectangle 100004", 100.0, 100.0, 200.0, 200.0, shape); + Assert.assertEquals(Color.ORANGE.getRGB(), shape.getFillColor().getRGB()); + Assert.assertEquals(WrapType.NONE, shape.getWrapType()); + Assert.assertFalse(shape.isInline()); + } + + @Test + public void bounds() throws Exception { + //ExStart + //ExFor:ShapeBase.Bounds + //ExFor:ShapeBase.BoundsInPoints + //ExSummary:Shows how to verify shape containing block boundaries. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertShape(ShapeType.LINE, RelativeHorizontalPosition.LEFT_MARGIN, 50.0, + RelativeVerticalPosition.TOP_MARGIN, 50.0, 100.0, 100.0, WrapType.NONE); + shape.setStrokeColor(Color.ORANGE); + + // Even though the line itself takes up little space on the document page, + // it occupies a rectangular containing block, the size of which we can determine using the "Bounds" properties. + Assert.assertEquals(new Rectangle2D.Float(50f, 50f, 100f, 100f), shape.getBounds()); + Assert.assertEquals(new Rectangle2D.Float(50f, 50f, 100f, 100f), shape.getBoundsInPoints()); + + // Create a group shape, and then set the size of its containing block using the "Bounds" property. + GroupShape group = new GroupShape(doc); + group.setBounds(new Rectangle2D.Float(0f, 100f, 250f, 250f)); + + Assert.assertEquals(new Rectangle2D.Float(0f, 100f, 250f, 250f), group.getBoundsInPoints()); + + // Create a rectangle, verify the size of its bounding block, and then add it to the group shape. + shape = new Shape(doc, ShapeType.RECTANGLE); + { + shape.setWidth(100.0); + shape.setHeight(100.0); + shape.setLeft(700.0); + shape.setTop(700.0); + } + + Assert.assertEquals(new Rectangle2D.Float(700f, 700f, 100f, 100f), shape.getBoundsInPoints()); + + group.appendChild(shape); + + // The group shape's coordinate plane has its origin on the top left-hand side corner of its containing block, + // and the x and y coordinates of (1000, 1000) on the bottom right-hand side corner. + // Our group shape is 250x250pt in size, so every 4pt on the group shape's coordinate plane + // translates to 1pt in the document body's coordinate plane. + // Every shape that we insert will also shrink in size by a factor of 4. + // The change in the shape's "BoundsInPoints" property will reflect this. + Assert.assertEquals(new Rectangle2D.Float(175f, 275f, 25f, 25f), shape.getBoundsInPoints()); + + doc.getFirstSection().getBody().getFirstParagraph().appendChild(group); + + // Insert a shape and place it outside of the bounds of the group shape's containing block. + shape = new Shape(doc, ShapeType.RECTANGLE); + { + shape.setWidth(100.0); + shape.setHeight(100.0); + shape.setLeft(1000.0); + shape.setTop(1000.0); + } + + group.appendChild(shape); + + // The group shape's footprint in the document body has increased, but the containing block remains the same. + Assert.assertEquals(new Rectangle2D.Float(0f, 100f, 250f, 250f), group.getBoundsInPoints()); + Assert.assertEquals(new Rectangle2D.Float(250f, 350f, 25f, 25f), shape.getBoundsInPoints()); + + doc.save(getArtifactsDir() + "Shape.Bounds.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.Bounds.docx"); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.LINE, "Line 100002", 100.0, 100.0, 50.0, 50.0, shape); + Assert.assertEquals(Color.ORANGE.getRGB(), shape.getStrokeColor().getRGB()); + Assert.assertEquals(new Rectangle2D.Float(50f, 50f, 100f, 100f), shape.getBoundsInPoints()); + + group = (GroupShape) doc.getChild(NodeType.GROUP_SHAPE, 0, true); + + Assert.assertEquals(new Rectangle2D.Float(0f, 100f, 250f, 250f), group.getBounds()); + Assert.assertEquals(new Rectangle2D.Float(0f, 100f, 250f, 250f), group.getBoundsInPoints()); + Assert.assertEquals(new Dimension(1000, 1000), group.getCoordSize()); + Assert.assertEquals(new Point(0, 0), group.getCoordOrigin()); + + shape = (Shape) doc.getChild(NodeType.SHAPE, 1, true); + + TestUtil.verifyShape(ShapeType.RECTANGLE, "", 100.0, 100.0, 700.0, 700.0, shape); + Assert.assertEquals(new Rectangle2D.Float(175f, 275f, 25f, 25f), shape.getBoundsInPoints()); + + shape = (Shape) doc.getChild(NodeType.SHAPE, 2, true); + + TestUtil.verifyShape(ShapeType.RECTANGLE, "", 100.0, 100.0, 1000.0, 1000.0, shape); + Assert.assertEquals(new Rectangle2D.Float(250f, 350f, 25f, 25f), shape.getBoundsInPoints()); + } + + @Test + public void flipShapeOrientation() throws Exception { + //ExStart + //ExFor:ShapeBase.FlipOrientation + //ExFor:FlipOrientation + //ExSummary:Shows how to flip a shape on an axis. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert an image shape and leave its orientation in its default state. + Shape shape = builder.insertShape(ShapeType.RECTANGLE, RelativeHorizontalPosition.LEFT_MARGIN, 100.0, + RelativeVerticalPosition.TOP_MARGIN, 100.0, 100.0, 100.0, WrapType.NONE); + shape.getImageData().setImage(getImageDir() + "Logo.jpg"); + + Assert.assertEquals(FlipOrientation.NONE, shape.getFlipOrientation()); + + shape = builder.insertShape(ShapeType.RECTANGLE, RelativeHorizontalPosition.LEFT_MARGIN, 250.0, + RelativeVerticalPosition.TOP_MARGIN, 100.0, 100.0, 100.0, WrapType.NONE); + shape.getImageData().setImage(getImageDir() + "Logo.jpg"); + + // Set the "FlipOrientation" property to "FlipOrientation.Horizontal" to flip the second shape on the y-axis, + // making it into a horizontal mirror image of the first shape. + shape.setFlipOrientation(FlipOrientation.HORIZONTAL); + + shape = builder.insertShape(ShapeType.RECTANGLE, RelativeHorizontalPosition.LEFT_MARGIN, 100.0, + RelativeVerticalPosition.TOP_MARGIN, 250.0, 100.0, 100.0, WrapType.NONE); + shape.getImageData().setImage(getImageDir() + "Logo.jpg"); + + // Set the "FlipOrientation" property to "FlipOrientation.Horizontal" to flip the third shape on the x-axis, + // making it into a vertical mirror image of the first shape. + shape.setFlipOrientation(FlipOrientation.VERTICAL); + + shape = builder.insertShape(ShapeType.RECTANGLE, RelativeHorizontalPosition.LEFT_MARGIN, 250.0, + RelativeVerticalPosition.TOP_MARGIN, 250.0, 100.0, 100.0, WrapType.NONE); + shape.getImageData().setImage(getImageDir() + "Logo.jpg"); + + // Set the "FlipOrientation" property to "FlipOrientation.Horizontal" to flip the fourth shape on both the x and y axes, + // making it into a horizontal and vertical mirror image of the first shape. + shape.setFlipOrientation(FlipOrientation.BOTH); + + doc.save(getArtifactsDir() + "Shape.FlipShapeOrientation.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.FlipShapeOrientation.docx"); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.RECTANGLE, "Rectangle 100002", 100.0, 100.0, 100.0, 100.0, shape); + Assert.assertEquals(FlipOrientation.NONE, shape.getFlipOrientation()); + + shape = (Shape) doc.getChild(NodeType.SHAPE, 1, true); + + TestUtil.verifyShape(ShapeType.RECTANGLE, "Rectangle 100004", 100.0, 100.0, 100.0, 250.0, shape); + Assert.assertEquals(FlipOrientation.HORIZONTAL, shape.getFlipOrientation()); + + shape = (Shape) doc.getChild(NodeType.SHAPE, 2, true); + + TestUtil.verifyShape(ShapeType.RECTANGLE, "Rectangle 100006", 100.0, 100.0, 250.0, 100.0, shape); + Assert.assertEquals(FlipOrientation.VERTICAL, shape.getFlipOrientation()); + + shape = (Shape) doc.getChild(NodeType.SHAPE, 3, true); + + TestUtil.verifyShape(ShapeType.RECTANGLE, "Rectangle 100008", 100.0, 100.0, 250.0, 250.0, shape); + Assert.assertEquals(FlipOrientation.BOTH, shape.getFlipOrientation()); + } + + @Test + public void fill() throws Exception { + //ExStart + //ExFor:ShapeBase.Fill + //ExFor:Shape.FillColor + //ExFor:Shape.StrokeColor + //ExFor:Fill + //ExFor:Fill.Opacity + //ExSummary:Shows how to fill a shape with a solid color. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Write some text, and then cover it with a floating shape. + builder.getFont().setSize(32.0); + builder.writeln("Hello world!"); + + Shape shape = builder.insertShape(ShapeType.CLOUD_CALLOUT, RelativeHorizontalPosition.LEFT_MARGIN, 25.0, + RelativeVerticalPosition.TOP_MARGIN, 25.0, 250.0, 150.0, WrapType.NONE); + + // Use the "StrokeColor" property to set the color of the outline of the shape. + shape.setStrokeColor(Color.BLACK); + + // Use the "FillColor" property to set the color of the inside area of the shape. + shape.setFillColor(Color.BLUE); + + // The "Opacity" property determines how transparent the color is on a 0-1 scale, + // with 1 being fully opaque, and 0 being invisible. + // The shape fill by default is fully opaque, so we cannot see the text that this shape is on top of. + Assert.assertEquals(1.0d, shape.getFill().getOpacity()); + + // Set the shape fill color's opacity to a lower value so that we can see the text underneath it. + shape.getFill().setOpacity(0.3); + + doc.save(getArtifactsDir() + "Shape.Fill.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.Fill.docx"); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.CLOUD_CALLOUT, "CloudCallout 100002", 250.0d, 150.0d, 25.0d, 25.0d, shape); + Color colorWithOpacity = new Color(Color.BLUE.getRed(), Color.BLUE.getGreen(), Color.BLUE.getBlue(), (int)(255.0 * shape.getFill().getOpacity())); + Assert.assertEquals(colorWithOpacity.getRGB(), shape.getFillColor().getRGB()); + Assert.assertEquals(Color.BLACK.getRGB(), shape.getStrokeColor().getRGB()); + Assert.assertEquals(0.3d, shape.getFill().getOpacity(), 0.01d); + } + + @Test + public void textureFill() throws Exception + { + //ExStart + //ExFor:Fill.PresetTexture + //ExFor:Fill.TextureAlignment + //ExFor:TextureAlignment + //ExSummary:Shows how to fill and tiling the texture inside the shape. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 80.0, 80.0); + + // Apply texture alignment to the shape fill. + shape.getFill().presetTextured(PresetTexture.CANVAS); + shape.getFill().setTextureAlignment(TextureAlignment.TOP_RIGHT); + + // Use the compliance option to define the shape using DML if you want to get "TextureAlignment" + // property after the document saves. + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setCompliance(OoxmlCompliance.ISO_29500_2008_STRICT); } + + doc.save(getArtifactsDir() + "Shape.TextureFill.docx", saveOptions); + + doc = new Document(getArtifactsDir() + "Shape.TextureFill.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(TextureAlignment.TOP_RIGHT, shape.getFill().getTextureAlignment()); + Assert.assertEquals(PresetTexture.CANVAS, shape.getFill().getPresetTexture()); + //ExEnd + } + + @Test + public void gradientFill() throws Exception + { + //ExStart + //ExFor:Fill.OneColorGradient(Color, GradientStyle, GradientVariant, Double) + //ExFor:Fill.OneColorGradient(GradientStyle, GradientVariant, Double) + //ExFor:Fill.TwoColorGradient(Color, Color, GradientStyle, GradientVariant) + //ExFor:Fill.TwoColorGradient(GradientStyle, GradientVariant) + //ExFor:Fill.BackColor + //ExFor:Fill.GradientStyle + //ExFor:Fill.GradientVariant + //ExFor:Fill.GradientAngle + //ExFor:GradientStyle + //ExFor:GradientVariant + //ExSummary:Shows how to fill a shape with a gradients. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 80.0, 80.0); + // Apply One-color gradient fill to the shape with ForeColor of gradient fill. + shape.getFill().oneColorGradient(Color.RED, GradientStyle.HORIZONTAL, GradientVariant.VARIANT_2, 0.1); + + Assert.assertEquals(Color.RED.getRGB(), shape.getFill().getForeColor().getRGB()); + Assert.assertEquals(GradientStyle.HORIZONTAL, shape.getFill().getGradientStyle()); + Assert.assertEquals(GradientVariant.VARIANT_2, shape.getFill().getGradientVariant()); + Assert.assertEquals(270, shape.getFill().getGradientAngle()); + + shape = builder.insertShape(ShapeType.RECTANGLE, 80.0, 80.0); + // Apply Two-color gradient fill to the shape. + shape.getFill().twoColorGradient(GradientStyle.FROM_CORNER, GradientVariant.VARIANT_4); + // Change BackColor of gradient fill. + shape.getFill().setBackColor(Color.YELLOW); + // Note that changes "GradientAngle" for "GradientStyle.FromCorner/GradientStyle.FromCenter" + // gradient fill don't get any effect, it will work only for linear gradient. + shape.getFill().setGradientAngle(15.0); + + Assert.assertEquals(Color.YELLOW.getRGB(), shape.getFill().getBackColor().getRGB()); + Assert.assertEquals(GradientStyle.FROM_CORNER, shape.getFill().getGradientStyle()); + Assert.assertEquals(GradientVariant.VARIANT_4, shape.getFill().getGradientVariant()); + Assert.assertEquals(0, shape.getFill().getGradientAngle()); + + // Use the compliance option to define the shape using DML if you want to get "GradientStyle", + // "GradientVariant" and "GradientAngle" properties after the document saves. + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setCompliance(OoxmlCompliance.ISO_29500_2008_STRICT); } + + doc.save(getArtifactsDir() + "Shape.GradientFill.docx", saveOptions); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.GradientFill.docx"); + Shape firstShape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(Color.RED.getRGB(), firstShape.getFill().getForeColor().getRGB()); + Assert.assertEquals(GradientStyle.HORIZONTAL, firstShape.getFill().getGradientStyle()); + Assert.assertEquals(GradientVariant.VARIANT_2, firstShape.getFill().getGradientVariant()); + Assert.assertEquals(270, firstShape.getFill().getGradientAngle()); + + Shape secondShape = (Shape)doc.getChild(NodeType.SHAPE, 1, true); + + Assert.assertEquals(Color.YELLOW.getRGB(), secondShape.getFill().getBackColor().getRGB()); + Assert.assertEquals(GradientStyle.FROM_CORNER, secondShape.getFill().getGradientStyle()); + Assert.assertEquals(GradientVariant.VARIANT_4, secondShape.getFill().getGradientVariant()); + Assert.assertEquals(0, secondShape.getFill().getGradientAngle()); + } + + @Test + public void gradientStops() throws Exception + { + //ExStart + //ExFor:Fill.GradientStops + //ExFor:GradientStopCollection + //ExFor:GradientStopCollection.Insert(Int32, GradientStop) + //ExFor:GradientStopCollection.Add(GradientStop) + //ExFor:GradientStopCollection.RemoveAt(Int32) + //ExFor:GradientStopCollection.Remove(GradientStop) + //ExFor:GradientStopCollection.Item(Int32) + //ExFor:GradientStopCollection.Count + //ExFor:GradientStop + //ExFor:GradientStop.#ctor(Color, Double) + //ExFor:GradientStop.#ctor(Color, Double, Double) + //ExFor:GradientStop.BaseColor + //ExFor:GradientStop.Color + //ExFor:GradientStop.Position + //ExFor:GradientStop.Transparency + //ExFor:GradientStop.Remove + //ExSummary:Shows how to add gradient stops to the gradient fill. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 80.0, 80.0); + shape.getFill().twoColorGradient(Color.green, Color.RED, GradientStyle.HORIZONTAL, GradientVariant.VARIANT_2); + + // Get gradient stops collection. + GradientStopCollection gradientStops = shape.getFill().getGradientStops(); + + // Change first gradient stop. + gradientStops.get(0).setColor(Color.yellow); + gradientStops.get(0).setPosition(0.1); + gradientStops.get(0).setTransparency(0.25); + + // Add new gradient stop to the end of collection. + GradientStop gradientStop = new GradientStop(Color.blue, 0.5); + gradientStops.add(gradientStop); + + // Remove gradient stop at index 1. + gradientStops.removeAt(1); + // And insert new gradient stop at the same index 1. + gradientStops.insert(1, new GradientStop(Color.pink, 0.75, 0.3)); + + // Remove last gradient stop in the collection. + gradientStop = gradientStops.get(2); + gradientStops.remove(gradientStop); + + Assert.assertEquals(2, gradientStops.getCount()); + + Assert.assertEquals(new Color((255), (255), (0)), gradientStops.get(0).getBaseColor()); + Assert.assertEquals(Color.yellow.getRGB(), gradientStops.get(0).getColor().getRGB()); + Assert.assertEquals(0.1d, gradientStops.get(0).getPosition(), 0.01d); + Assert.assertEquals(0.25d, gradientStops.get(0).getTransparency(), 0.01d); + + Assert.assertEquals(Color.pink.getRGB(), gradientStops.get(1).getColor().getRGB()); + Assert.assertEquals(0.75d, gradientStops.get(1).getPosition(), 0.01d); + Assert.assertEquals(0.3d, gradientStops.get(1).getTransparency(), 0.01d); + + // Use the compliance option to define the shape using DML + // if you want to get "GradientStops" property after the document saves. + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setCompliance(OoxmlCompliance.ISO_29500_2008_STRICT); } + + doc.save(getArtifactsDir() + "Shape.GradientStops.docx", saveOptions); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.GradientStops.docx"); + + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + gradientStops = shape.getFill().getGradientStops(); + + Assert.assertEquals(2, gradientStops.getCount()); + + Assert.assertEquals(Color.yellow.getRGB(), gradientStops.get(0).getColor().getRGB()); + Assert.assertEquals(0.1d, gradientStops.get(0).getPosition(), 0.01d); + Assert.assertEquals(0.25d, gradientStops.get(0).getTransparency(), 0.01d); + + Assert.assertEquals(Color.pink.getRGB(), gradientStops.get(1).getColor().getRGB()); + Assert.assertEquals(0.75d, gradientStops.get(1).getPosition(), 0.01d); + Assert.assertEquals(0.3d, gradientStops.get(1).getTransparency(), 0.01d); + } + + @Test + public void fillPattern() throws Exception + { + //ExStart + //ExFor:PatternType + //ExFor:Fill.Pattern + //ExFor:Fill.Patterned(PatternType) + //ExFor:Fill.Patterned(PatternType, Color, Color) + //ExSummary:Shows how to set pattern for a shape. + Document doc = new Document(getMyDir() + "Shape stroke pattern border.docx"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + Fill fill = shape.getFill(); + + System.out.println(MessageFormat.format("Pattern value is: {0}",fill.getPattern())); + + // There are several ways specified fill to a pattern. + // 1 - Apply pattern to the shape fill: + fill.patterned(PatternType.DIAGONAL_BRICK); + + // 2 - Apply pattern with foreground and background colors to the shape fill: + fill.patterned(PatternType.DIAGONAL_BRICK, Color.yellow, Color.blue); + + doc.save(getArtifactsDir() + "Shape.FillPattern.docx"); + //ExEnd + } + + @Test + public void fillThemeColor() throws Exception + { + //ExStart + //ExFor:Fill.ForeThemeColor + //ExFor:Fill.BackThemeColor + //ExFor:Fill.BackTintAndShade + //ExSummary:Shows how to set theme color for foreground/background shape color. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertShape(ShapeType.ROUND_RECTANGLE, 80.0, 80.0); + + Fill fill = shape.getFill(); + fill.setForeThemeColor(ThemeColor.DARK_1); + fill.setBackThemeColor(ThemeColor.BACKGROUND_2); + + // Note: do not use "BackThemeColor" and "BackTintAndShade" for font fill. + if (fill.getBackTintAndShade() == 0) + fill.setBackTintAndShade(0.2); + + doc.save(getArtifactsDir() + "Shape.FillThemeColor.docx"); + //ExEnd + } + + @Test + public void fillTintAndShade() throws Exception + { + //ExStart + //ExFor:Fill.ForeTintAndShade + //ExSummary:Shows how to manage lightening and darkening foreground font color. + Document doc = new Document(getMyDir() + "Big document.docx"); + + Fill textFill = doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0).getFont().getFill(); + textFill.setForeThemeColor(ThemeColor.ACCENT_1); + if (textFill.getForeTintAndShade() == 0) + textFill.setForeTintAndShade(0.5); + + doc.save(getArtifactsDir() + "Shape.FillTintAndShade.docx"); + //ExEnd + } + + @Test + public void title() throws Exception { + //ExStart + //ExFor:ShapeBase.Title + //ExSummary:Shows how to set the title of a shape. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a shape, give it a title, and then add it to the document. + Shape shape = new Shape(doc, ShapeType.CUBE); + shape.setWidth(200.0); + shape.setHeight(200.0); + shape.setTitle("My cube"); + + builder.insertNode(shape); + + // When we save a document with a shape that has a title, + // Aspose.Words will store that title in the shape's Alt Text. + doc.save(getArtifactsDir() + "Shape.Title.docx"); + + doc = new Document(getArtifactsDir() + "Shape.Title.docx"); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals("", shape.getTitle()); + Assert.assertEquals("Title: My cube", shape.getAlternativeText()); + //ExEnd + + TestUtil.verifyShape(ShapeType.CUBE, "", 200.0d, 200.0d, 0.0d, 0.0d, shape); + } + + @Test + public void replaceTextboxesWithImages() throws Exception { + //ExStart + //ExFor:WrapSide + //ExFor:ShapeBase.WrapSide + //ExFor:NodeCollection + //ExFor:CompositeNode.InsertAfter``1(``0,Node) + //ExFor:NodeCollection.ToArray + //ExSummary:Shows how to replace all textbox shapes with image shapes. + Document doc = new Document(getMyDir() + "Textboxes in drawing canvas.docx"); + + List shapeList = Arrays.stream(doc.getChildNodes(NodeType.SHAPE, true).toArray()) + .filter(Shape.class::isInstance) + .map(Shape.class::cast) + .collect(Collectors.toList()); + + Assert.assertEquals(3, IterableUtils.countMatches(shapeList, s -> s.getShapeType() == ShapeType.TEXT_BOX)); + Assert.assertEquals(1, IterableUtils.countMatches(shapeList, s -> s.getShapeType() == ShapeType.IMAGE)); + + for (Shape shape : shapeList) { + if (((shape.getShapeType()) == (ShapeType.TEXT_BOX))) { + Shape replacementShape = new Shape(doc, ShapeType.IMAGE); + replacementShape.getImageData().setImage(getImageDir() + "Logo.jpg"); + replacementShape.setLeft(shape.getLeft()); + replacementShape.setTop(shape.getTop()); + replacementShape.setWidth(shape.getWidth()); + replacementShape.setHeight(shape.getHeight()); + replacementShape.setRelativeHorizontalPosition(shape.getRelativeHorizontalPosition()); + replacementShape.setRelativeVerticalPosition(shape.getRelativeVerticalPosition()); + replacementShape.setHorizontalAlignment(shape.getHorizontalAlignment()); + replacementShape.setVerticalAlignment(shape.getVerticalAlignment()); + replacementShape.setWrapType(shape.getWrapType()); + replacementShape.setWrapSide(shape.getWrapSide()); + + shape.getParentNode().insertAfter(replacementShape, shape); + shape.remove(); + } + } + + shapeList = Arrays.stream(doc.getChildNodes(NodeType.SHAPE, true).toArray()) + .filter(Shape.class::isInstance) + .map(Shape.class::cast) + .collect(Collectors.toList()); + + Assert.assertEquals(0, IterableUtils.countMatches(shapeList, s -> s.getShapeType() == ShapeType.TEXT_BOX)); + Assert.assertEquals(4, IterableUtils.countMatches(shapeList, s -> s.getShapeType() == ShapeType.IMAGE)); + + doc.save(getArtifactsDir() + "Shape.ReplaceTextboxesWithImages.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.ReplaceTextboxesWithImages.docx"); + Shape outShape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(WrapSide.BOTH, outShape.getWrapSide()); + } + + @Test + public void createTextBox() throws Exception { + //ExStart + //ExFor:Shape.#ctor(DocumentBase, ShapeType) + //ExFor:Story.FirstParagraph + //ExFor:Shape.FirstParagraph + //ExFor:ShapeBase.WrapType + //ExSummary:Shows how to create and format a text box. + Document doc = new Document(); + + // Create a floating text box. + Shape textBox = new Shape(doc, ShapeType.TEXT_BOX); + textBox.setWrapType(WrapType.NONE); + textBox.setHeight(50.0); + textBox.setWidth(200.0); + + // Set the horizontal, and vertical alignment of the text inside the shape. + textBox.setHorizontalAlignment(HorizontalAlignment.CENTER); + textBox.setVerticalAlignment(VerticalAlignment.TOP); + + // Add a paragraph to the text box and add a run of text that the text box will display. + textBox.appendChild(new Paragraph(doc)); + Paragraph para = textBox.getFirstParagraph(); + para.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + Run run = new Run(doc); + run.setText("Hello world!"); + para.appendChild(run); + + doc.getFirstSection().getBody().getFirstParagraph().appendChild(textBox); + + doc.save(getArtifactsDir() + "Shape.CreateTextBox.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.CreateTextBox.docx"); + textBox = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.TEXT_BOX, "", 200.0d, 50.0d, 0.0d, 0.0d, textBox); + Assert.assertEquals(WrapType.NONE, textBox.getWrapType()); + Assert.assertEquals(HorizontalAlignment.CENTER, textBox.getHorizontalAlignment()); + Assert.assertEquals(VerticalAlignment.TOP, textBox.getVerticalAlignment()); + Assert.assertEquals("Hello world!", textBox.getText().trim()); + } + + @Test + public void zOrder() throws Exception { + //ExStart + //ExFor:ShapeBase.ZOrder + //ExSummary:Shows how to manipulate the order of shapes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert three different colored rectangles that partially overlap each other. + // When we insert a shape that overlaps another shape, Aspose.Words places the newer shape on top of the old one. + // The light green rectangle will overlap the light blue rectangle and partially obscure it, + // and the light blue rectangle will obscure the orange rectangle. + Shape shape = builder.insertShape(ShapeType.RECTANGLE, RelativeHorizontalPosition.LEFT_MARGIN, 100.0, + RelativeVerticalPosition.TOP_MARGIN, 100.0, 200.0, 200.0, WrapType.NONE); + shape.setFillColor(Color.ORANGE); + + shape = builder.insertShape(ShapeType.RECTANGLE, RelativeHorizontalPosition.LEFT_MARGIN, 150.0, + RelativeVerticalPosition.TOP_MARGIN, 150.0, 200.0, 200.0, WrapType.NONE); + shape.setFillColor(Color.BLUE); + + shape = builder.insertShape(ShapeType.RECTANGLE, RelativeHorizontalPosition.LEFT_MARGIN, 200.0, + RelativeVerticalPosition.TOP_MARGIN, 200.0, 200.0, 200.0, WrapType.NONE); + shape.setFillColor(Color.GREEN); + + List shapeList = Arrays.stream(doc.getChildNodes(NodeType.SHAPE, true).toArray()) + .filter(Shape.class::isInstance) + .map(Shape.class::cast) + .collect(Collectors.toList()); + + // The "ZOrder" property of a shape determines its stacking priority among other overlapping shapes. + // If two overlapping shapes have different "ZOrder" values, + // Microsoft Word will place the shape with a higher value over the shape with the lower value. + // Set the "ZOrder" values of our shapes to place the first orange rectangle over the second light blue one + // and the second light blue rectangle over the third light green rectangle. + // This will reverse their original stacking order. + shapeList.get(0).setZOrder(3); + shapeList.get(1).setZOrder(2); + shapeList.get(2).setZOrder(1); + + doc.save(getArtifactsDir() + "Shape.ZOrder.docx"); + //ExEnd + } + + @Test + public void getActiveXControlProperties() throws Exception { + //ExStart + //ExFor:OleControl + //ExFor:OleControl.IsForms2OleControl + //ExFor:OleControl.Name + //ExFor:OleFormat.OleControl + //ExFor:Forms2OleControl + //ExFor:Forms2OleControl.Caption + //ExFor:Forms2OleControl.Value + //ExFor:Forms2OleControl.Enabled + //ExFor:Forms2OleControl.Type + //ExFor:Forms2OleControl.ChildNodes + //ExFor:Forms2OleControl.GroupName + //ExSummary:Shows how to verify the properties of an ActiveX control. + Document doc = new Document(getMyDir() + "ActiveX controls.docx"); + + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + OleControl oleControl = shape.getOleFormat().getOleControl(); + + Assert.assertEquals(oleControl.getName(), "CheckBox1"); + + if (oleControl.isForms2OleControl()) { + Forms2OleControl checkBox = (Forms2OleControl) oleControl; + Assert.assertEquals(checkBox.getCaption(), "First"); + Assert.assertEquals(checkBox.getValue(), "0"); + Assert.assertEquals(checkBox.getEnabled(), true); + Assert.assertEquals(checkBox.getType(), Forms2OleControlType.CHECK_BOX); + Assert.assertEquals(checkBox.getChildNodes(), null); + } + //ExEnd + + doc.save(getArtifactsDir() + "Shape.GetActiveXControlProperties.docx"); + doc = new Document(getArtifactsDir() + "Shape.GetActiveXControlProperties.docx"); + + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + Forms2OleControl forms2OleControl = (Forms2OleControl)shape.getOleFormat().getOleControl(); + + Assert.assertEquals("", forms2OleControl.getGroupName()); + } + + @Test + public void getOleObjectRawData() throws Exception { + //ExStart + //ExFor:OleFormat.GetRawData + //ExSummary:Shows how to access the raw data of an embedded OLE object. + Document doc = new Document(getMyDir() + "OLE objects.docx"); + + for (Node shape : (Iterable) doc.getChildNodes(NodeType.SHAPE, true)) { + OleFormat oleFormat = ((Shape) shape).getOleFormat(); + if (oleFormat != null) { + System.out.println("This is {(oleFormat.IsLink ? "); //ExSkip + byte[] oleRawData = oleFormat.getRawData(); + + Assert.assertEquals(24576, oleRawData.length); + } + } + //ExEnd + } + + @Test + public void linkedChartSourceFullName() throws Exception + { + //ExStart + //ExFor:Chart.SourceFullName + //ExSummary:Shows how to get/set the full name of the external xls/xlsx document if the chart is linked. + Document doc = new Document(getMyDir() + "Shape with linked chart.docx"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + String sourceFullName = shape.getChart().getSourceFullName(); + Assert.assertTrue(sourceFullName.contains("Examples\\Data\\Spreadsheet.xlsx")); + //ExEnd + } + + @Test + public void oleControl() throws Exception { + //ExStart + //ExFor:OleFormat + //ExFor:OleFormat.AutoUpdate + //ExFor:OleFormat.IsLocked + //ExFor:OleFormat.ProgId + //ExFor:OleFormat.Save(Stream) + //ExFor:OleFormat.Save(String) + //ExFor:OleFormat.SuggestedExtension + //ExSummary:Shows how to extract embedded OLE objects into files. + Document doc = new Document(getMyDir() + "OLE spreadsheet.docm"); + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + // The OLE object in the first shape is a Microsoft Excel spreadsheet. + OleFormat oleFormat = shape.getOleFormat(); + + Assert.assertEquals("Excel.Sheet.12", oleFormat.getProgId()); + + // Our object is neither auto updating nor locked from updates. + Assert.assertFalse(oleFormat.getAutoUpdate()); + Assert.assertEquals(oleFormat.isLocked(), false); + + // If we plan on saving the OLE object to a file in the local file system, + // we can use the "SuggestedExtension" property to determine which file extension to apply to the file. + Assert.assertEquals(".xlsx", oleFormat.getSuggestedExtension()); + + // Below are two ways of saving an OLE object to a file in the local file system. + // 1 - Save it via a stream: + OutputStream fs = new FileOutputStream(getArtifactsDir() + "OLE spreadsheet extracted via stream" + oleFormat.getSuggestedExtension()); + try { + oleFormat.save(fs); + } finally { + if (fs != null) fs.close(); + } + + // 2 - Save it directly to a filename: + oleFormat.save(getArtifactsDir() + "OLE spreadsheet saved directly" + oleFormat.getSuggestedExtension()); + //ExEnd + + Assert.assertTrue(new File(getArtifactsDir() + "OLE spreadsheet extracted via stream.xlsx").length() < 8500); + Assert.assertTrue(new File(getArtifactsDir() + "OLE spreadsheet saved directly.xlsx").length() < 8500); + } + + @Test + public void oleLinks() throws Exception { + //ExStart + //ExFor:OleFormat.IconCaption + //ExFor:OleFormat.GetOleEntry(String) + //ExFor:OleFormat.IsLink + //ExFor:OleFormat.OleIcon + //ExFor:OleFormat.SourceFullName + //ExFor:OleFormat.SourceItem + //ExSummary:Shows how to insert linked and unlinked OLE objects. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Embed a Microsoft Visio drawing into the document as an OLE object. + builder.insertOleObject(getImageDir() + "Microsoft Visio drawing.vsd", "Package", false, false, new FileInputStream(getImageDir() + "Transparent background logo.png")); + + // Insert a link to the file in the local file system and display it as an icon. + builder.insertOleObject(getImageDir() + "Microsoft Visio drawing.vsd", "Package", true, true, new FileInputStream(getImageDir() + "Transparent background logo.png")); + + // Inserting OLE objects creates shapes that store these objects. + List shapeList = Arrays.stream(doc.getChildNodes(NodeType.SHAPE, true).toArray()) + .filter(Shape.class::isInstance) + .map(Shape.class::cast) + .collect(Collectors.toList()); + + Assert.assertEquals(2, shapeList.size()); + Assert.assertEquals(2, IterableUtils.countMatches(shapeList, s -> s.getShapeType() == ShapeType.OLE_OBJECT)); + + // If a shape contains an OLE object, it will have a valid "OleFormat" property, + // which we can use to verify some aspects of the shape. + OleFormat oleFormat = shapeList.get(0).getOleFormat(); + + Assert.assertEquals(false, oleFormat.isLink()); + Assert.assertEquals(false, oleFormat.getOleIcon()); + + oleFormat = shapeList.get(1).getOleFormat(); + + Assert.assertEquals(true, oleFormat.isLink()); + Assert.assertEquals(true, oleFormat.getOleIcon()); + + Assert.assertTrue(oleFormat.getSourceFullName().endsWith("Images" + File.separator + "Microsoft Visio drawing.vsd")); + Assert.assertEquals("", oleFormat.getSourceItem()); + + Assert.assertEquals("Microsoft Visio drawing.vsd", oleFormat.getIconCaption()); + + doc.save(getArtifactsDir() + "Shape.OleLinks.docx"); + + // If the object contains OLE data, we can access it using a stream. + byte[] oleEntryBytes = oleFormat.getOleEntry("\u0001CompObj"); + Assert.assertEquals(76, oleEntryBytes.length); + //ExEnd + } + + @Test + public void oleControlCollection() throws Exception { + //ExStart + //ExFor:OleFormat.Clsid + //ExFor:Forms2OleControlCollection + //ExFor:Forms2OleControlCollection.Count + //ExFor:Forms2OleControlCollection.Item(Int32) + //ExSummary:Shows how to access an OLE control embedded in a document and its child controls. + Document doc = new Document(getMyDir() + "OLE ActiveX controls.docm"); + + // Shapes store and display OLE objects in the document's body. + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals("6e182020-f460-11ce-9bcd-00aa00608e01", shape.getOleFormat().getClsid().toString()); + + Forms2OleControl oleControl = (Forms2OleControl) shape.getOleFormat().getOleControl(); + + // Some OLE controls may contain child controls, such as the one in this document with three options buttons. + Forms2OleControlCollection oleControlCollection = oleControl.getChildNodes(); + + Assert.assertEquals(3, oleControlCollection.getCount()); + + Assert.assertEquals("C#", oleControlCollection.get(0).getCaption()); + Assert.assertEquals("1", oleControlCollection.get(0).getValue()); + + Assert.assertEquals("Visual Basic", oleControlCollection.get(1).getCaption()); + Assert.assertEquals("0", oleControlCollection.get(1).getValue()); + + Assert.assertEquals("Delphi", oleControlCollection.get(2).getCaption()); + Assert.assertEquals("0", oleControlCollection.get(2).getValue()); + //ExEnd + } + + @Test + public void suggestedFileName() throws Exception { + //ExStart + //ExFor:OleFormat.SuggestedFileName + //ExSummary:Shows how to get an OLE object's suggested file name. + Document doc = new Document(getMyDir() + "OLE shape.rtf"); + + Shape oleShape = (Shape) doc.getFirstSection().getBody().getChild(NodeType.SHAPE, 0, true); + + // OLE objects can provide a suggested filename and extension, + // which we can use when saving the object's contents into a file in the local file system. + String suggestedFileName = oleShape.getOleFormat().getSuggestedFileName(); + + Assert.assertEquals("CSV.csv", suggestedFileName); + + OutputStream fileStream = new FileOutputStream(getArtifactsDir() + suggestedFileName); + try { + oleShape.getOleFormat().save(fileStream); + } finally { + if (fileStream != null) fileStream.close(); + } + //ExEnd + } + + @Test + public void objectDidNotHaveSuggestedFileName() throws Exception { + Document doc = new Document(getMyDir() + "ActiveX controls.docx"); + + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + Assert.assertEquals(shape.getOleFormat().getSuggestedFileName(), ""); + } + + @Test + public void renderOfficeMath() throws Exception { + //ExStart + //ExFor:ImageSaveOptions.Scale + //ExFor:OfficeMath.GetMathRenderer + //ExFor:NodeRendererBase.Save(String, ImageSaveOptions) + //ExSummary:Shows how to render an Office Math object into an image file in the local file system. + Document doc = new Document(getMyDir() + "Office math.docx"); + + OfficeMath math = (OfficeMath) doc.getChild(NodeType.OFFICE_MATH, 0, true); + + // Create an "ImageSaveOptions" object to pass to the node renderer's "Save" method to modify + // how it renders the OfficeMath node into an image. + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.PNG); + + // Set the "Scale" property to 5 to render the object to five times its original size. + saveOptions.setScale(5f); + + math.getMathRenderer().save(getArtifactsDir() + "Shape.RenderOfficeMath.png", saveOptions); + //ExEnd + + TestUtil.verifyImage(813, 86, getArtifactsDir() + "Shape.RenderOfficeMath.png"); + } + + @Test + public void officeMathDisplayException() throws Exception { + Document doc = new Document(getMyDir() + "Office math.docx"); + + OfficeMath officeMath = (OfficeMath) doc.getChild(NodeType.OFFICE_MATH, 0, true); + officeMath.setDisplayType(OfficeMathDisplayType.DISPLAY); + + Assert.assertThrows(IllegalArgumentException.class, () -> officeMath.setJustification(OfficeMathJustification.INLINE)); + } + + @Test + public void officeMathDefaultValue() throws Exception { + Document doc = new Document(getMyDir() + "Office math.docx"); + + OfficeMath officeMath = (OfficeMath) doc.getChild(NodeType.OFFICE_MATH, 0, true); + + Assert.assertEquals(officeMath.getDisplayType(), OfficeMathDisplayType.DISPLAY); + Assert.assertEquals(officeMath.getJustification(), OfficeMathJustification.CENTER); + } + + @Test + public void officeMath() throws Exception { + //ExStart + //ExFor:OfficeMath + //ExFor:OfficeMath.DisplayType + //ExFor:OfficeMath.Justification + //ExFor:OfficeMath.NodeType + //ExFor:OfficeMath.ParentParagraph + //ExFor:OfficeMathDisplayType + //ExFor:OfficeMathJustification + //ExSummary:Shows how to set office math display formatting. + Document doc = new Document(getMyDir() + "Office math.docx"); + + OfficeMath officeMath = (OfficeMath) doc.getChild(NodeType.OFFICE_MATH, 0, true); + + // OfficeMath nodes that are children of other OfficeMath nodes are always inline. + // The node we are working with is the base node to change its location and display type. + Assert.assertEquals(MathObjectType.O_MATH_PARA, officeMath.getMathObjectType()); + Assert.assertEquals(NodeType.OFFICE_MATH, officeMath.getNodeType()); + Assert.assertEquals(officeMath.getParentNode(), officeMath.getParentParagraph()); + + // Change the location and display type of the OfficeMath node. + officeMath.setDisplayType(OfficeMathDisplayType.DISPLAY); + officeMath.setJustification(OfficeMathJustification.LEFT); + + doc.save(getArtifactsDir() + "Shape.OfficeMath.docx"); + //ExEnd + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "Shape.OfficeMath.docx", getGoldsDir() + "Shape.OfficeMath Gold.docx")); + } + + @Test + public void cannotBeSetDisplayWithInlineJustification() throws Exception { + Document doc = new Document(getMyDir() + "Office math.docx"); + + OfficeMath officeMath = (OfficeMath) doc.getChild(NodeType.OFFICE_MATH, 0, true); + officeMath.setDisplayType(OfficeMathDisplayType.DISPLAY); + + Assert.assertThrows(IllegalArgumentException.class, () -> officeMath.setJustification(OfficeMathJustification.INLINE)); + } + + @Test + public void cannotBeSetInlineDisplayWithJustification() throws Exception { + Document doc = new Document(getMyDir() + "Office math.docx"); + + OfficeMath officeMath = (OfficeMath) doc.getChild(NodeType.OFFICE_MATH, 0, true); + officeMath.setDisplayType(OfficeMathDisplayType.INLINE); + + Assert.assertThrows(IllegalArgumentException.class, () -> officeMath.setJustification(OfficeMathJustification.CENTER)); + } + + @Test + public void officeMathDisplayNestedObjects() throws Exception { + Document doc = new Document(getMyDir() + "Office math.docx"); + + OfficeMath officeMath = (OfficeMath) doc.getChild(NodeType.OFFICE_MATH, 0, true); + + Assert.assertEquals(officeMath.getDisplayType(), OfficeMathDisplayType.DISPLAY); + Assert.assertEquals(officeMath.getJustification(), OfficeMathJustification.CENTER); + } + + @Test(dataProvider = "workWithMathObjectTypeDataProvider") + public void workWithMathObjectType(final int index, final int objectType) throws Exception { + Document doc = new Document(getMyDir() + "Office math.docx"); + + OfficeMath officeMath = (OfficeMath) doc.getChild(NodeType.OFFICE_MATH, index, true); + Assert.assertEquals(officeMath.getMathObjectType(), objectType); + } + + @DataProvider(name = "workWithMathObjectTypeDataProvider") + public static Object[][] workWithMathObjectTypeDataProvider() { + return new Object[][] + { + {0, MathObjectType.O_MATH_PARA}, + {1, MathObjectType.O_MATH}, + {2, MathObjectType.SUPERCRIPT}, + {3, MathObjectType.ARGUMENT}, + {4, MathObjectType.SUPERSCRIPT_PART} + }; + } + + @Test(dataProvider = "aspectRatioDataProvider") + public void aspectRatio(boolean lockAspectRatio) throws Exception { + //ExStart + //ExFor:ShapeBase.AspectRatioLocked + //ExSummary:Shows how to lock/unlock a shape's aspect ratio. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a shape. If we open this document in Microsoft Word, we can left click the shape to reveal + // eight sizing handles around its perimeter, which we can click and drag to change its size. + Shape shape = builder.insertImage(getImageDir() + "Logo.jpg"); + + // Set the "AspectRatioLocked" property to "true" to preserve the shape's aspect ratio + // when using any of the four diagonal sizing handles, which change both the image's height and width. + // Using any orthogonal sizing handles that either change the height or width will still change the aspect ratio. + // Set the "AspectRatioLocked" property to "false" to allow us to + // freely change the image's aspect ratio with all sizing handles. + shape.setAspectRatioLocked(lockAspectRatio); + + doc.save(getArtifactsDir() + "Shape.AspectRatio.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.AspectRatio.docx"); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(lockAspectRatio, shape.getAspectRatioLocked()); + } + + @DataProvider(name = "aspectRatioDataProvider") + public static Object[][] aspectRatioDataProvider() { + return new Object[][] + { + {true}, + {false} + }; + } + + @Test + public void markupLanguageByDefault() throws Exception { + //ExStart + //ExFor:ShapeBase.MarkupLanguage + //ExFor:ShapeBase.SizeInPoints + //ExSummary:Shows how to verify a shape's size and markup language. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertImage(getImageDir() + "Transparent background logo.png"); + + Assert.assertEquals(ShapeMarkupLanguage.DML, shape.getMarkupLanguage()); + Assert.assertEquals(new Point2D.Float(300f, 300f), shape.getSizeInPoints()); + //ExEnd + } + + @Test(dataProvider = "markupLunguageForDifferentMsWordVersionsDataProvider") + public void markupLunguageForDifferentMsWordVersions(final int msWordVersion, final byte shapeMarkupLanguage) throws Exception { + Document doc = new Document(); + doc.getCompatibilityOptions().optimizeFor(msWordVersion); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertImage(getImageDir() + "Transparent background logo.png"); + + for (Shape shape : (Iterable) doc.getChildNodes(NodeType.SHAPE, true)) { + Assert.assertEquals(shape.getMarkupLanguage(), shapeMarkupLanguage); + } + } + + @DataProvider(name = "markupLunguageForDifferentMsWordVersionsDataProvider") + public static Object[][] markupLunguageForDifferentMsWordVersionsDataProvider() { + return new Object[][] + { + {MsWordVersion.WORD_2000, ShapeMarkupLanguage.VML}, + {MsWordVersion.WORD_2002, ShapeMarkupLanguage.VML}, + {MsWordVersion.WORD_2003, ShapeMarkupLanguage.VML}, + {MsWordVersion.WORD_2007, ShapeMarkupLanguage.VML}, + {MsWordVersion.WORD_2010, ShapeMarkupLanguage.DML}, + {MsWordVersion.WORD_2013, ShapeMarkupLanguage.DML}, + {MsWordVersion.WORD_2016, ShapeMarkupLanguage.DML} + }; + } + + @Test + public void stroke() throws Exception { + //ExStart + //ExFor:Stroke + //ExFor:Stroke.On + //ExFor:Stroke.Weight + //ExFor:Stroke.JoinStyle + //ExFor:Stroke.LineStyle + //ExFor:Stroke.Fill + //ExFor:ShapeLineStyle + //ExSummary:Shows how change stroke properties. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertShape(ShapeType.RECTANGLE, RelativeHorizontalPosition.LEFT_MARGIN, 100.0, + RelativeVerticalPosition.TOP_MARGIN, 100.0, 200.0, 200.0, WrapType.NONE); + + // Basic shapes, such as the rectangle, have two visible parts. + // 1 - The fill, which applies to the area within the outline of the shape: + shape.getFill().setForeColor(Color.WHITE); + + // 2 - The stroke, which marks the outline of the shape: + // Modify various properties of this shape's stroke. + Stroke stroke = shape.getStroke(); + stroke.setOn(true); + stroke.setWeight(5.0); + stroke.setColor(Color.RED); + stroke.setDashStyle(DashStyle.SHORT_DASH_DOT_DOT); + stroke.setJoinStyle(JoinStyle.MITER); + stroke.setEndCap(EndCap.SQUARE); + stroke.setLineStyle(ShapeLineStyle.TRIPLE); + stroke.getFill().twoColorGradient(Color.RED, Color.BLUE, GradientStyle.VERTICAL, GradientVariant.VARIANT_1); + + doc.save(getArtifactsDir() + "Shape.Stroke.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.Stroke.docx"); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + stroke = shape.getStroke(); + + Assert.assertEquals(true, stroke.getOn()); + Assert.assertEquals(5.0, stroke.getWeight()); + Assert.assertEquals(Color.RED.getRGB(), stroke.getColor().getRGB()); + Assert.assertEquals(DashStyle.SHORT_DASH_DOT_DOT, stroke.getDashStyle()); + Assert.assertEquals(JoinStyle.MITER, stroke.getJoinStyle()); + Assert.assertEquals(EndCap.SQUARE, stroke.getEndCap()); + Assert.assertEquals(ShapeLineStyle.TRIPLE, stroke.getLineStyle()); + } + + @Test(description = "WORDSNET-16067") + public void insertOleObjectAsHtmlFile() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertOleObject("http://www.aspose.com", "htmlfile", true, false, new FileInputStream(getImageDir() + "Transparent background logo.png")); + + doc.save(getArtifactsDir() + "Shape.InsertOleObjectAsHtmlFile.docx"); + } + + @Test(description = "WORDSNET-16085") + public void insertOlePackage() throws Exception { + //ExStart + //ExFor:OlePackage + //ExFor:OleFormat.OlePackage + //ExFor:OlePackage.FileName + //ExFor:OlePackage.DisplayName + //ExSummary:Shows how insert an OLE object into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // OLE objects allow us to open other files in the local file system using another installed application + // in our operating system by double-clicking on the shape that contains the OLE object in the document body. + // In this case, our external file will be a ZIP archive. + byte[] zipFileBytes = DocumentHelper.getBytesFromStream(new FileInputStream(getDatabaseDir() + "cat001.zip")); + + InputStream stream = new ByteArrayInputStream(zipFileBytes); + InputStream representingImage = new FileInputStream(getImageDir() + "Logo.jpg"); + try { + Shape shape = builder.insertOleObject(stream, "Package", true, representingImage); + + OlePackage setOlePackage = shape.getOleFormat().getOlePackage(); + setOlePackage.setFileName("Package file name.zip"); + setOlePackage.setDisplayName("Package display name.zip"); + + doc.save(getArtifactsDir() + "Shape.InsertOlePackage.docx"); + } finally { + if (stream != null) { + stream.close(); + } + } + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.InsertOlePackage.docx"); + Shape getShape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals("Package file name.zip", getShape.getOleFormat().getOlePackage().getFileName()); + Assert.assertEquals("Package display name.zip", getShape.getOleFormat().getOlePackage().getDisplayName()); + } + + @Test + public void getAccessToOlePackage() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape oleObject = builder.insertOleObject(getMyDir() + "Spreadsheet.xlsx", false, false, new FileInputStream(getImageDir() + "Logo.jpg")); + Shape oleObjectAsOlePackage = builder.insertOleObject(getMyDir() + "Spreadsheet.xlsx", "Excel.Sheet", false, false, new FileInputStream(getImageDir() + "Logo.jpg")); + + Assert.assertEquals(oleObject.getOleFormat().getOlePackage(), null); + Assert.assertEquals(oleObjectAsOlePackage.getOleFormat().getOlePackage().getClass(), OlePackage.class); + } + + @Test + public void resize() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 200.0, 300.0); + shape.setHeight(300.0); + shape.setWidth(500.0); + shape.setRotation(30.0); + + doc.save(getArtifactsDir() + "Shape.Resize.docx"); + } + + @Test + public void calendar() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startTable(); + builder.getRowFormat().setHeight(100.0); + builder.getRowFormat().setHeightRule(HeightRule.EXACTLY); + + for (int i = 0; i < 31; i++) { + if (i != 0 && i % 7 == 0) builder.endRow(); + builder.insertCell(); + builder.write("Cell contents"); + } + + builder.endTable(); + + NodeCollection runs = doc.getChildNodes(NodeType.RUN, true); + int num = 1; + + for (Run run : (Iterable) runs) { + Shape watermark = new Shape(doc, ShapeType.TEXT_PLAIN_TEXT); + { + watermark.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE); + watermark.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE); + watermark.setWidth(30.0); + watermark.setHeight(30.0); + watermark.setHorizontalAlignment(HorizontalAlignment.CENTER); + watermark.setVerticalAlignment(VerticalAlignment.CENTER); + watermark.setRotation(-40); + } + + watermark.getFill().setForeColor(new Color(220, 220, 220)); + watermark.setStrokeColor(new Color(220, 220, 220)); + + watermark.getTextPath().setText(MessageFormat.format("{0}", num)); + watermark.getTextPath().setFontFamily("Arial"); + + watermark.setName(MessageFormat.format("Watermark_{0}", num++)); + + watermark.setBehindText(true); + + builder.moveTo(run); + builder.insertNode(watermark); + } + + doc.save(getArtifactsDir() + "Shape.Calendar.docx"); + + doc = new Document(getArtifactsDir() + "Shape.Calendar.docx"); + List shapeList = Arrays.stream(doc.getChildNodes(NodeType.SHAPE, true).toArray()) + .filter(Shape.class::isInstance) + .map(Shape.class::cast) + .collect(Collectors.toList()); + + Assert.assertEquals(31, shapeList.size()); + + for (Shape shape : shapeList) + TestUtil.verifyShape(ShapeType.TEXT_PLAIN_TEXT, MessageFormat.format("Watermark_{0}", shapeList.indexOf(shape) + 1), + 30.0d, 30.0d, 0.0d, 0.0d, shape); + } + + @Test(dataProvider = "isLayoutInCellDataProvider") + public void isLayoutInCell(boolean isLayoutInCell) throws Exception { + //ExStart + //ExFor:ShapeBase.IsLayoutInCell + //ExSummary:Shows how to determine how to display a shape in a table cell. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + builder.insertCell(); + builder.endTable(); + + TableStyle tableStyle = (TableStyle) doc.getStyles().add(StyleType.TABLE, "MyTableStyle1"); + tableStyle.setBottomPadding(20.0); + tableStyle.setLeftPadding(10.0); + tableStyle.setRightPadding(10.0); + tableStyle.setTopPadding(20.0); + tableStyle.getBorders().setColor(Color.BLACK); + tableStyle.getBorders().setLineStyle(LineStyle.SINGLE); + + table.setStyle(tableStyle); + + builder.moveTo(table.getFirstRow().getFirstCell().getFirstParagraph()); + + Shape shape = builder.insertShape(ShapeType.RECTANGLE, RelativeHorizontalPosition.LEFT_MARGIN, 50.0, + RelativeVerticalPosition.TOP_MARGIN, 100.0, 100.0, 100.0, WrapType.NONE); + + // Set the "IsLayoutInCell" property to "true" to display the shape as an inline element inside the cell's paragraph. + // The coordinate origin that will determine the shape's location will be the top left corner of the shape's cell. + // If we re-size the cell, the shape will move to maintain the same position starting from the cell's top left. + // Set the "IsLayoutInCell" property to "false" to display the shape as an independent floating shape. + // The coordinate origin that will determine the shape's location will be the top left corner of the page, + // and the shape will not respond to any re-sizing of its cell. + shape.isLayoutInCell(isLayoutInCell); + + // We can only apply the "IsLayoutInCell" property to floating shapes. + shape.setWrapType(WrapType.NONE); + + doc.save(getArtifactsDir() + "Shape.LayoutInTableCell.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.LayoutInTableCell.docx"); + table = doc.getFirstSection().getBody().getTables().get(0); + shape = (Shape) table.getFirstRow().getFirstCell().getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(isLayoutInCell, shape.isLayoutInCell()); + } + + @DataProvider(name = "isLayoutInCellDataProvider") + public static Object[][] isLayoutInCellDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void shapeInsertion() throws Exception { + //ExStart + //ExFor:DocumentBuilder.InsertShape(ShapeType, RelativeHorizontalPosition, double, RelativeVerticalPosition, double, double, double, WrapType) + //ExFor:DocumentBuilder.InsertShape(ShapeType, double, double) + //ExFor:OoxmlCompliance + //ExFor:OoxmlSaveOptions.Compliance + //ExSummary:Shows how to insert DML shapes into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are two wrapping types that shapes may have. + // 1 - Floating: + builder.insertShape(ShapeType.TOP_CORNERS_ROUNDED, RelativeHorizontalPosition.PAGE, 100.0, + RelativeVerticalPosition.PAGE, 100.0, 50.0, 50.0, WrapType.NONE); + + // 2 - Inline: + builder.insertShape(ShapeType.DIAGONAL_CORNERS_ROUNDED, 50.0, 50.0); + + // If you need to create "non-primitive" shapes, such as SingleCornerSnipped, TopCornersSnipped, DiagonalCornersSnipped, + // TopCornersOneRoundedOneSnipped, SingleCornerRounded, TopCornersRounded, or DiagonalCornersRounded, + // then save the document with "Strict" or "Transitional" compliance, which allows saving shape as DML. + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(SaveFormat.DOCX); + saveOptions.setCompliance(OoxmlCompliance.ISO_29500_2008_TRANSITIONAL); + + doc.save(getArtifactsDir() + "Shape.ShapeInsertion.docx", saveOptions); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.ShapeInsertion.docx"); + List shapeList = Arrays.stream(doc.getChildNodes(NodeType.SHAPE, true).toArray()) + .filter(Shape.class::isInstance) + .map(Shape.class::cast) + .collect(Collectors.toList()); + + TestUtil.verifyShape(ShapeType.TOP_CORNERS_ROUNDED, "TopCornersRounded 100002", 50.0d, 50.0d, 100.0d, 100.0d, shapeList.get(0)); + TestUtil.verifyShape(ShapeType.DIAGONAL_CORNERS_ROUNDED, "DiagonalCornersRounded 100004", 50.0d, 50.0d, 0.0d, 0.0d, shapeList.get(1)); + } + + //ExStart + //ExFor:Shape.Accept(DocumentVisitor) + //ExFor:Shape.AcceptStart(DocumentVisitor) + //ExFor:Shape.AcceptEnd(DocumentVisitor) + //ExFor:Shape.Chart + //ExFor:Shape.ExtrusionEnabled + //ExFor:Shape.Filled + //ExFor:Shape.HasChart + //ExFor:Shape.OleFormat + //ExFor:Shape.ShadowEnabled + //ExFor:Shape.StoryType + //ExFor:Shape.StrokeColor + //ExFor:Shape.Stroked + //ExFor:Shape.StrokeWeight + //ExSummary:Shows how to iterate over all the shapes in a document. + @Test //ExSkip + public void visitShapes() throws Exception { + Document doc = new Document(getMyDir() + "Revision shape.docx"); + Assert.assertEquals(2, doc.getChildNodes(NodeType.SHAPE, true).getCount()); //ExSkip + + ShapeAppearancePrinter visitor = new ShapeAppearancePrinter(); + doc.accept(visitor); + + System.out.println(visitor.getText()); + } + + /// + /// Logs appearance-related information about visited shapes. + /// + private static class ShapeAppearancePrinter extends DocumentVisitor { + public ShapeAppearancePrinter() { + mShapesVisited = 0; + mTextIndentLevel = 0; + mStringBuilder = new StringBuilder(); + } + + /// + /// Appends a line to the StringBuilder with one prepended tab character for each indent level. + /// + private void appendLine(String text) { + for (int i = 0; i < mTextIndentLevel; i++) { + mStringBuilder.append('\t'); + } + + mStringBuilder.append(text + "\n"); + } + + /// + /// Return all the text that the StringBuilder has accumulated. + /// + public String getText() { + return MessageFormat.format("Shapes visited: {0}\n{1}", mShapesVisited, mStringBuilder); + } + + /// + /// Called when this visitor visits the start of a Shape node. + /// + public int visitShapeStart(Shape shape) { + appendLine(MessageFormat.format("Shape found: {0}", shape.getShapeType())); + + mTextIndentLevel++; + + if (shape.hasChart()) + appendLine(MessageFormat.format("Has chart: {0}", shape.getChart().getTitle().getText())); + + appendLine(MessageFormat.format("Extrusion enabled: {0}", shape.getExtrusionEnabled())); + appendLine(MessageFormat.format("Shadow enabled: {0}", shape.getShadowEnabled())); + appendLine(MessageFormat.format("StoryType: {0}", shape.getStoryType())); + + if (shape.getStroked()) { + Assert.assertEquals(shape.getStrokeColor(), shape.getStroke().getColor()); + appendLine(MessageFormat.format("Stroke colors: {0}, {1}", shape.getStroke().getColor(), shape.getStroke().getColor2())); + appendLine(MessageFormat.format("Stroke weight: {0}", shape.getStrokeWeight())); + } + + if (shape.getFilled()) + appendLine(MessageFormat.format("Filled: {0}", shape.getFillColor())); + + if (shape.getOleFormat() != null) + appendLine(MessageFormat.format("Ole found of type: {0}", shape.getOleFormat().getProgId())); + + if (shape.getSignatureLine() != null) + appendLine(MessageFormat.format("Found signature line for: {0}, {1}", shape.getSignatureLine().getSigner(), shape.getSignatureLine().getSignerTitle())); + + return VisitorAction.CONTINUE; + } + + /// + /// Called when this visitor visits the end of a Shape node. + /// + public int visitShapeEnd(Shape shape) { + mTextIndentLevel--; + mShapesVisited++; + appendLine(MessageFormat.format("End of {0}", shape.getShapeType())); + + return VisitorAction.CONTINUE; + } + + /// + /// Called when this visitor visits the start of a GroupShape node. + /// + public int visitGroupShapeStart(GroupShape groupShape) { + appendLine(MessageFormat.format("Shape group found: {0}", groupShape.getShapeType())); + mTextIndentLevel++; + + return VisitorAction.CONTINUE; + } + + /// + /// Called when this visitor visits the end of a GroupShape node. + /// + public int visitGroupShapeEnd(GroupShape groupShape) { + mTextIndentLevel--; + appendLine(MessageFormat.format("End of {0}", groupShape.getShapeType())); + + return VisitorAction.CONTINUE; + } + + private int mShapesVisited; + private int mTextIndentLevel; + private final StringBuilder mStringBuilder; + } + //ExEnd + + @Test + public void signatureLine() throws Exception { + //ExStart + //ExFor:Shape.SignatureLine + //ExFor:ShapeBase.IsSignatureLine + //ExFor:SignatureLine + //ExFor:SignatureLine.AllowComments + //ExFor:SignatureLine.DefaultInstructions + //ExFor:SignatureLine.Email + //ExFor:SignatureLine.Instructions + //ExFor:SignatureLine.ShowDate + //ExFor:SignatureLine.Signer + //ExFor:SignatureLine.SignerTitle + //ExSummary:Shows how to create a line for a signature and insert it into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + SignatureLineOptions options = new SignatureLineOptions(); + { + options.setAllowComments(true); + options.setDefaultInstructions(true); + options.setEmail("john.doe@management.com"); + options.setInstructions("Please sign here"); + options.setShowDate(true); + options.setSigner("John Doe"); + options.setSignerTitle("Senior Manager"); + } + + // Insert a shape that will contain a signature line, whose appearance we will + // customize using the "SignatureLineOptions" object we have created above. + // If we insert a shape whose coordinates originate at the bottom right hand corner of the page, + // we will need to supply negative x and y coordinates to bring the shape into view. + Shape shape = builder.insertSignatureLine(options, RelativeHorizontalPosition.RIGHT_MARGIN, -170.0, + RelativeVerticalPosition.BOTTOM_MARGIN, -60.0, WrapType.NONE); + + Assert.assertTrue(shape.isSignatureLine()); + + // Verify the properties of our signature line via its Shape object. + SignatureLine signatureLine = shape.getSignatureLine(); + + Assert.assertEquals(signatureLine.getEmail(), "john.doe@management.com"); + Assert.assertEquals(signatureLine.getSigner(), "John Doe"); + Assert.assertEquals(signatureLine.getSignerTitle(), "Senior Manager"); + Assert.assertEquals(signatureLine.getInstructions(), "Please sign here"); + Assert.assertTrue(signatureLine.getShowDate()); + Assert.assertTrue(signatureLine.getAllowComments()); + Assert.assertTrue(signatureLine.getDefaultInstructions()); + + doc.save(getArtifactsDir() + "Shape.SignatureLine.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.SignatureLine.docx"); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.IMAGE, "", 192.75d, 96.75d, -60.0d, -170.0d, shape); + Assert.assertTrue(shape.isSignatureLine()); + + signatureLine = shape.getSignatureLine(); + + Assert.assertEquals("john.doe@management.com", signatureLine.getEmail()); + Assert.assertEquals("John Doe", signatureLine.getSigner()); + Assert.assertEquals("Senior Manager", signatureLine.getSignerTitle()); + Assert.assertEquals("Please sign here", signatureLine.getInstructions()); + Assert.assertTrue(signatureLine.getShowDate()); + Assert.assertTrue(signatureLine.getAllowComments()); + Assert.assertTrue(signatureLine.getDefaultInstructions()); + Assert.assertFalse(signatureLine.isSigned()); + Assert.assertFalse(signatureLine.isValid()); + } + + @Test(dataProvider = "textBoxLayoutFlowDataProvider") + public void textBoxLayoutFlow(int layoutFlow) throws Exception { + //ExStart + //ExFor:Shape.TextBox + //ExFor:Shape.LastParagraph + //ExFor:TextBox + //ExFor:TextBox.LayoutFlow + //ExSummary:Shows how to set the orientation of text inside a text box. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape textBoxShape = builder.insertShape(ShapeType.TEXT_BOX, 150.0, 100.0); + TextBox textBox = textBoxShape.getTextBox(); + + // Move the document builder to inside the TextBox and add text. + builder.moveTo(textBoxShape.getLastParagraph()); + builder.writeln("Hello world!"); + builder.write("Hello again!"); + + // Set the "LayoutFlow" property to set an orientation for the text contents of this text box. + textBox.setLayoutFlow(layoutFlow); + + doc.save(getArtifactsDir() + "Shape.TextBoxLayoutFlow.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.TextBoxLayoutFlow.docx"); + textBoxShape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.TEXT_BOX, "TextBox 100002", 150.0d, 100.0d, 0.0d, 0.0d, textBoxShape); + + /*LayoutFlow*/ + int expectedLayoutFlow; + + switch (layoutFlow) { + case LayoutFlow.BOTTOM_TO_TOP: + case LayoutFlow.HORIZONTAL: + case LayoutFlow.TOP_TO_BOTTOM_IDEOGRAPHIC: + case LayoutFlow.VERTICAL: + expectedLayoutFlow = layoutFlow; + break; + case LayoutFlow.TOP_TO_BOTTOM: + expectedLayoutFlow = LayoutFlow.VERTICAL; + break; + default: + expectedLayoutFlow = LayoutFlow.HORIZONTAL; + break; + } + + TestUtil.verifyTextBox(expectedLayoutFlow, false, TextBoxWrapMode.SQUARE, 3.6d, 3.6d, 7.2d, 7.2d, textBoxShape.getTextBox()); + Assert.assertEquals("Hello world!\rHello again!", textBoxShape.getText().trim()); + } + + @DataProvider(name = "textBoxLayoutFlowDataProvider") + public static Object[][] textBoxLayoutFlowDataProvider() { + return new Object[][] + { + {LayoutFlow.VERTICAL}, + {LayoutFlow.HORIZONTAL}, + {LayoutFlow.HORIZONTAL_IDEOGRAPHIC}, + {LayoutFlow.BOTTOM_TO_TOP}, + {LayoutFlow.TOP_TO_BOTTOM}, + {LayoutFlow.TOP_TO_BOTTOM_IDEOGRAPHIC}, + }; + } + + @Test + public void textBoxFitShapeToText() throws Exception { + //ExStart + //ExFor:TextBox + //ExFor:TextBox.FitShapeToText + //ExSummary:Shows how to get a text box to resize itself to fit its contents tightly. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape textBoxShape = builder.insertShape(ShapeType.TEXT_BOX, 150.0, 100.0); + TextBox textBox = textBoxShape.getTextBox(); + + // Apply these values to both these members to get the parent shape to fit + // tightly around the text contents, ignoring the dimensions we have set. + textBox.setFitShapeToText(true); + textBox.setTextBoxWrapMode(TextBoxWrapMode.NONE); + + builder.moveTo(textBoxShape.getLastParagraph()); + builder.write("Text fit tightly inside textbox."); + + doc.save(getArtifactsDir() + "Shape.TextBoxFitShapeToText.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.TextBoxFitShapeToText.docx"); + textBoxShape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.TEXT_BOX, "TextBox 100002", 150.0d, 100.0d, 0.0d, 0.0d, textBoxShape); + TestUtil.verifyTextBox(LayoutFlow.HORIZONTAL, true, TextBoxWrapMode.NONE, 3.6d, 3.6d, 7.2d, 7.2d, textBoxShape.getTextBox()); + Assert.assertEquals("Text fit tightly inside textbox.", textBoxShape.getText().trim()); + } + + @Test + public void textBoxMargins() throws Exception { + //ExStart + //ExFor:TextBox + //ExFor:TextBox.InternalMarginBottom + //ExFor:TextBox.InternalMarginLeft + //ExFor:TextBox.InternalMarginRight + //ExFor:TextBox.InternalMarginTop + //ExSummary:Shows how to set internal margins for a text box. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert another textbox with specific margins. + Shape textBoxShape = builder.insertShape(ShapeType.TEXT_BOX, 100.0, 100.0); + TextBox textBox = textBoxShape.getTextBox(); + textBox.setInternalMarginTop(15.0); + textBox.setInternalMarginBottom(15.0); + textBox.setInternalMarginLeft(15.0); + textBox.setInternalMarginRight(15.0); + + builder.moveTo(textBoxShape.getLastParagraph()); + builder.write("Text placed according to textbox margins."); + + doc.save(getArtifactsDir() + "Shape.TextBoxMargins.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.TextBoxMargins.docx"); + textBoxShape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.TEXT_BOX, "TextBox 100002", 100.0d, 100.0d, 0.0d, 0.0d, textBoxShape); + TestUtil.verifyTextBox(LayoutFlow.HORIZONTAL, false, TextBoxWrapMode.SQUARE, 15.0d, 15.0d, 15.0d, 15.0d, textBoxShape.getTextBox()); + Assert.assertEquals("Text placed according to textbox margins.", textBoxShape.getText().trim()); + } + + @Test(dataProvider = "textBoxContentsWrapModeDataProvider") + public void textBoxContentsWrapMode(int textBoxWrapMode) throws Exception { + //ExStart + //ExFor:TextBox.TextBoxWrapMode + //ExFor:TextBoxWrapMode + //ExSummary:Shows how to set a wrapping mode for the contents of a text box. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape textBoxShape = builder.insertShape(ShapeType.TEXT_BOX, 300.0, 300.0); + TextBox textBox = textBoxShape.getTextBox(); + + // Set the "TextBoxWrapMode" property to "TextBoxWrapMode.None" to increase the text box's width + // to accommodate text, should it be large enough. + // Set the "TextBoxWrapMode" property to "TextBoxWrapMode.Square" to + // wrap all text inside the text box, preserving its dimensions. + textBox.setTextBoxWrapMode(textBoxWrapMode); + + builder.moveTo(textBoxShape.getLastParagraph()); + builder.getFont().setSize(32.0); + builder.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + + doc.save(getArtifactsDir() + "Shape.TextBoxContentsWrapMode.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.TextBoxContentsWrapMode.docx"); + textBoxShape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.TEXT_BOX, "TextBox 100002", 300.0d, 300.0d, 0.0d, 0.0d, textBoxShape); + TestUtil.verifyTextBox(LayoutFlow.HORIZONTAL, false, textBoxWrapMode, 3.6d, 3.6d, 7.2d, 7.2d, textBoxShape.getTextBox()); + Assert.assertEquals("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", textBoxShape.getText().trim()); + } + + @DataProvider(name = "textBoxContentsWrapModeDataProvider") + public static Object[][] textBoxContentsWrapModeDataProvider() { + return new Object[][] + { + {TextBoxWrapMode.NONE}, + {TextBoxWrapMode.SQUARE}, + }; + } + + @Test + public void textBoxShapeType() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Set compatibility options to correctly using of VerticalAnchor property. + doc.getCompatibilityOptions().optimizeFor(MsWordVersion.WORD_2016); + + Shape textBoxShape = builder.insertShape(ShapeType.TEXT_BOX, 100.0, 100.0); + // Not all formats are compatible with this one. + // For most of the incompatible formats, AW generated warnings on save, so use doc.WarningCallback to check it. + textBoxShape.getTextBox().setVerticalAnchor(TextBoxAnchor.BOTTOM); + + builder.moveTo(textBoxShape.getLastParagraph()); + builder.write("Text placed bottom"); + + doc.save(getArtifactsDir() + "Shape.TextBoxShapeType.docx"); + } + + @Test + public void createLinkBetweenTextBoxes() throws Exception { + //ExStart + //ExFor:TextBox.IsValidLinkTarget(TextBox) + //ExFor:TextBox.Next + //ExFor:TextBox.Previous + //ExFor:TextBox.BreakForwardLink + //ExSummary:Shows how to link text boxes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape textBoxShape1 = builder.insertShape(ShapeType.TEXT_BOX, 100.0, 100.0); + TextBox textBox1 = textBoxShape1.getTextBox(); + builder.writeln(); + + Shape textBoxShape2 = builder.insertShape(ShapeType.TEXT_BOX, 100.0, 100.0); + TextBox textBox2 = textBoxShape2.getTextBox(); + builder.writeln(); + + Shape textBoxShape3 = builder.insertShape(ShapeType.TEXT_BOX, 100.0, 100.0); + TextBox textBox3 = textBoxShape3.getTextBox(); + builder.writeln(); + + Shape textBoxShape4 = builder.insertShape(ShapeType.TEXT_BOX, 100.0, 100.0); + TextBox textBox4 = textBoxShape4.getTextBox(); + + // Create links between some of the text boxes. + if (textBox1.isValidLinkTarget(textBox2)) + textBox1.setNext(textBox2); + + if (textBox2.isValidLinkTarget(textBox3)) + textBox2.setNext(textBox3); + + // Only an empty text box may have a link. + Assert.assertTrue(textBox3.isValidLinkTarget(textBox4)); + + builder.moveTo(textBoxShape4.getLastParagraph()); + builder.write("Hello world!"); + + Assert.assertFalse(textBox3.isValidLinkTarget(textBox4)); + + if (textBox1.getNext() != null && textBox1.getPrevious() == null) + System.out.println("This TextBox is the head of the sequence"); + + if (textBox2.getNext() != null && textBox2.getPrevious() != null) + System.out.println("This TextBox is the middle of the sequence"); + + if (textBox3.getNext() == null && textBox3.getPrevious() != null) { + System.out.println("This TextBox is the tail of the sequence"); + + // Break the forward link between textBox2 and textBox3, and then verify that they are no longer linked. + textBox3.getPrevious().breakForwardLink(); + + Assert.assertTrue(textBox2.getNext() == null); + Assert.assertTrue(textBox3.getPrevious() == null); + } + + doc.save(getArtifactsDir() + "Shape.CreateLinkBetweenTextBoxes.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.CreateLinkBetweenTextBoxes.docx"); + List shapeList = Arrays.stream(doc.getChildNodes(NodeType.SHAPE, true).toArray()) + .filter(Shape.class::isInstance) + .map(Shape.class::cast) + .collect(Collectors.toList()); + + TestUtil.verifyShape(ShapeType.TEXT_BOX, "TextBox 100002", 100.0d, 100.0d, 0.0d, 0.0d, shapeList.get(0)); + TestUtil.verifyTextBox(LayoutFlow.HORIZONTAL, false, TextBoxWrapMode.SQUARE, 3.6d, 3.6d, 7.2d, 7.2d, shapeList.get(0).getTextBox()); + Assert.assertEquals("", shapeList.get(0).getText().trim()); + + TestUtil.verifyShape(ShapeType.TEXT_BOX, "TextBox 100004", 100.0d, 100.0d, 0.0d, 0.0d, shapeList.get(1)); + TestUtil.verifyTextBox(LayoutFlow.HORIZONTAL, false, TextBoxWrapMode.SQUARE, 3.6d, 3.6d, 7.2d, 7.2d, shapeList.get(1).getTextBox()); + Assert.assertEquals("", shapeList.get(1).getText().trim()); + + TestUtil.verifyShape(ShapeType.RECTANGLE, "TextBox 100006", 100.0d, 100.0d, 0.0d, 0.0d, shapeList.get(2)); + TestUtil.verifyTextBox(LayoutFlow.HORIZONTAL, false, TextBoxWrapMode.SQUARE, 3.6d, 3.6d, 7.2d, 7.2d, shapeList.get(2).getTextBox()); + Assert.assertEquals("", shapeList.get(2).getText().trim()); + + TestUtil.verifyShape(ShapeType.TEXT_BOX, "TextBox 100008", 100.0d, 100.0d, 0.0d, 0.0d, shapeList.get(3)); + TestUtil.verifyTextBox(LayoutFlow.HORIZONTAL, false, TextBoxWrapMode.SQUARE, 3.6d, 3.6d, 7.2d, 7.2d, shapeList.get(3).getTextBox()); + Assert.assertEquals("Hello world!", shapeList.get(3).getText().trim()); + } + + @Test(dataProvider = "verticalAnchorDataProvider") + public void verticalAnchor(int verticalAnchor) throws Exception { + //ExStart + //ExFor:CompatibilityOptions + //ExFor:CompatibilityOptions.OptimizeFor(MsWordVersion) + //ExFor:TextBoxAnchor + //ExFor:TextBox.VerticalAnchor + //ExSummary:Shows how to vertically align the text contents of a text box. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertShape(ShapeType.TEXT_BOX, 200.0, 200.0); + + // Set the "VerticalAnchor" property to "TextBoxAnchor.Top" to + // align the text in this text box with the top side of the shape. + // Set the "VerticalAnchor" property to "TextBoxAnchor.Middle" to + // align the text in this text box to the center of the shape. + // Set the "VerticalAnchor" property to "TextBoxAnchor.Bottom" to + // align the text in this text box to the bottom of the shape. + shape.getTextBox().setVerticalAnchor(verticalAnchor); + + builder.moveTo(shape.getFirstParagraph()); + builder.write("Hello world!"); + + // The vertical aligning of text inside text boxes is available from Microsoft Word 2007 onwards. + doc.getCompatibilityOptions().optimizeFor(MsWordVersion.WORD_2007); + doc.save(getArtifactsDir() + "Shape.VerticalAnchor.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.VerticalAnchor.docx"); + shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.TEXT_BOX, "TextBox 100002", 200.0d, 200.0d, 0.0d, 0.0d, shape); + TestUtil.verifyTextBox(LayoutFlow.HORIZONTAL, false, TextBoxWrapMode.SQUARE, 3.6d, 3.6d, 7.2d, 7.2d, shape.getTextBox()); + Assert.assertEquals(verticalAnchor, shape.getTextBox().getVerticalAnchor()); + Assert.assertEquals("Hello world!", shape.getText().trim()); + } + + @DataProvider(name = "verticalAnchorDataProvider") + public static Object[][] verticalAnchorDataProvider() { + return new Object[][] + { + {TextBoxAnchor.TOP}, + {TextBoxAnchor.MIDDLE}, + {TextBoxAnchor.BOTTOM}, + }; + } + + //ExStart + //ExFor:Shape.TextPath + //ExFor:ShapeBase.IsWordArt + //ExFor:TextPath + //ExFor:TextPath.Bold + //ExFor:TextPath.FitPath + //ExFor:TextPath.FitShape + //ExFor:TextPath.FontFamily + //ExFor:TextPath.Italic + //ExFor:TextPath.Kerning + //ExFor:TextPath.On + //ExFor:TextPath.ReverseRows + //ExFor:TextPath.RotateLetters + //ExFor:TextPath.SameLetterHeights + //ExFor:TextPath.Shadow + //ExFor:TextPath.SmallCaps + //ExFor:TextPath.Spacing + //ExFor:TextPath.StrikeThrough + //ExFor:TextPath.Text + //ExFor:TextPath.TextPathAlignment + //ExFor:TextPath.Trim + //ExFor:TextPath.Underline + //ExFor:TextPath.XScale + //ExFor:TextPath.Size + //ExFor:TextPathAlignment + //ExSummary:Shows how to work with WordArt. + @Test //ExSkip + public void insertTextPaths() throws Exception { + Document doc = new Document(); + + // Insert a WordArt object to display text in a shape that we can re-size and move by using the mouse in Microsoft Word. + // Provide a "ShapeType" as an argument to set a shape for the WordArt. + Shape shape = appendWordArt(doc, "Hello World! This text is bold, and italic.", + "Arial", 480.0, 24.0, Color.WHITE, Color.BLACK, ShapeType.TEXT_PLAIN_TEXT); + + // Apply the "Bold" and "Italic" formatting settings to the text using the respective properties. + shape.getTextPath().setBold(true); + shape.getTextPath().setItalic(true); + + // Below are various other text formatting-related properties. + Assert.assertFalse(shape.getTextPath().getUnderline()); + Assert.assertFalse(shape.getTextPath().getShadow()); + Assert.assertFalse(shape.getTextPath().getStrikeThrough()); + Assert.assertFalse(shape.getTextPath().getReverseRows()); + Assert.assertFalse(shape.getTextPath().getXScale()); + Assert.assertFalse(shape.getTextPath().getTrim()); + Assert.assertFalse(shape.getTextPath().getSmallCaps()); + + Assert.assertEquals(36.0, shape.getTextPath().getSize()); + Assert.assertEquals("Hello World! This text is bold, and italic.", shape.getTextPath().getText()); + Assert.assertEquals(ShapeType.TEXT_PLAIN_TEXT, shape.getShapeType()); + + // Use the "On" property to show/hide the text. + shape = appendWordArt(doc, "On set to \"true\"", "Calibri", 150.0, 24.0, Color.YELLOW, Color.RED, ShapeType.TEXT_PLAIN_TEXT); + shape.getTextPath().setOn(true); + + shape = appendWordArt(doc, "On set to \"false\"", "Calibri", 150.0, 24.0, Color.YELLOW, Color.pink, ShapeType.TEXT_PLAIN_TEXT); + shape.getTextPath().setOn(false); + + // Use the "Kerning" property to enable/disable kerning spacing between certain characters. + shape = appendWordArt(doc, "Kerning: VAV", "Times New Roman", 90.0, 24.0, Color.ORANGE, Color.RED, ShapeType.TEXT_PLAIN_TEXT); + shape.getTextPath().setKerning(true); + + shape = appendWordArt(doc, "No kerning: VAV", "Times New Roman", 100.0, 24.0, Color.ORANGE, Color.RED, ShapeType.TEXT_PLAIN_TEXT); + shape.getTextPath().setKerning(false); + + // Use the "Spacing" property to set the custom spacing between characters on a scale from 0.0 (none) to 1.0 (default). + shape = appendWordArt(doc, "Spacing set to 0.1", "Calibri", 120.0, 24.0, Color.BLUE, Color.BLUE, ShapeType.TEXT_CASCADE_DOWN); + shape.getTextPath().setSpacing(0.1); + + // Set the "RotateLetters" property to "true" to rotate each character 90 degrees counterclockwise. + shape = appendWordArt(doc, "RotateLetters", "Calibri", 200.0, 36.0, Color.YELLOW, Color.GREEN, ShapeType.TEXT_WAVE); + shape.getTextPath().setRotateLetters(true); + + // Set the "SameLetterHeights" property to "true" to get the x-height of each character to equal the cap height. + shape = appendWordArt(doc, "Same character height for lower and UPPER case", "Calibri", 300.0, 24.0, Color.BLUE, Color.BLUE, ShapeType.TEXT_SLANT_UP); + shape.getTextPath().setSameLetterHeights(true); + + // By default, the text's size will always scale to fit the containing shape's size, overriding the text size setting. + shape = appendWordArt(doc, "FitShape on", "Calibri", 160.0, 24.0, Color.BLUE, Color.BLUE, ShapeType.TEXT_PLAIN_TEXT); + Assert.assertTrue(shape.getTextPath().getFitShape()); + shape.getTextPath().setSize(24.0); + + // If we set the "FitShape: property to "false", the text will keep the size + // which the "Size" property specifies regardless of the size of the shape. + // Use the "TextPathAlignment" property also to align the text to a side of the shape. + shape = appendWordArt(doc, "FitShape off", "Calibri", 160.0, 24.0, Color.BLUE, Color.BLUE, ShapeType.TEXT_PLAIN_TEXT); + shape.getTextPath().setFitShape(false); + shape.getTextPath().setSize(24.0); + shape.getTextPath().setTextPathAlignment(TextPathAlignment.RIGHT); + + doc.save(getArtifactsDir() + "Shape.InsertTextPaths.docx"); + testInsertTextPaths(getArtifactsDir() + "Shape.InsertTextPaths.docx"); //ExSkip + } + + /// + /// Insert a new paragraph with a WordArt shape inside it. + /// + private static Shape appendWordArt(Document doc, String text, String textFontFamily, double shapeWidth, double shapeHeight, Color wordArtFill, Color line, /*ShapeType*/int wordArtShapeType) throws Exception { + // Create an inline Shape, which will serve as a container for our WordArt. + // The shape can only be a valid WordArt shape if we assign a WordArt-designated ShapeType to it. + // These types will have "WordArt object" in the description, + // and their enumerator constant names will all start with "Text". + Shape shape = new Shape(doc, wordArtShapeType); + { + shape.setWrapType(WrapType.INLINE); + shape.setWidth(shapeWidth); + shape.setHeight(shapeHeight); + shape.setFillColor(wordArtFill); + shape.setStrokeColor(line); + } + + shape.getTextPath().setText(text); + shape.getTextPath().setFontFamily(textFontFamily); + + Paragraph para = (Paragraph) doc.getFirstSection().getBody().appendChild(new Paragraph(doc)); + para.appendChild(shape); + return shape; + } + //ExEnd + + private void testInsertTextPaths(String filename) throws Exception { + Document doc = new Document(filename); + List shapeList = Arrays.stream(doc.getChildNodes(NodeType.SHAPE, true).toArray()) + .filter(Shape.class::isInstance) + .map(Shape.class::cast) + .collect(Collectors.toList()); + + TestUtil.verifyShape(ShapeType.TEXT_PLAIN_TEXT, "", 480.0, 24.0, 0.0d, 0.0d, shapeList.get(0)); + Assert.assertTrue(shapeList.get(0).getTextPath().getBold()); + Assert.assertTrue(shapeList.get(0).getTextPath().getItalic()); + + TestUtil.verifyShape(ShapeType.TEXT_PLAIN_TEXT, "", 150.0, 24.0, 0.0d, 0.0d, shapeList.get(1)); + Assert.assertTrue(shapeList.get(1).getTextPath().getOn()); + + TestUtil.verifyShape(ShapeType.TEXT_PLAIN_TEXT, "", 150.0, 24.0, 0.0d, 0.0d, shapeList.get(2)); + Assert.assertFalse(shapeList.get(2).getTextPath().getOn()); + + TestUtil.verifyShape(ShapeType.TEXT_PLAIN_TEXT, "", 90.0, 24.0, 0.0d, 0.0d, shapeList.get(3)); + Assert.assertTrue(shapeList.get(3).getTextPath().getKerning()); + + TestUtil.verifyShape(ShapeType.TEXT_PLAIN_TEXT, "", 100.0, 24.0, 0.0d, 0.0d, shapeList.get(4)); + Assert.assertFalse(shapeList.get(4).getTextPath().getKerning()); + + TestUtil.verifyShape(ShapeType.TEXT_CASCADE_DOWN, "", 120.0, 24.0, 0.0d, 0.0d, shapeList.get(5)); + Assert.assertEquals(0.1d, shapeList.get(5).getTextPath().getSpacing(), 0.01d); + + TestUtil.verifyShape(ShapeType.TEXT_WAVE, "", 200.0, 36.0, 0.0d, 0.0d, shapeList.get(6)); + Assert.assertTrue(shapeList.get(6).getTextPath().getRotateLetters()); + + TestUtil.verifyShape(ShapeType.TEXT_SLANT_UP, "", 300.0, 24.0, 0.0d, 0.0d, shapeList.get(7)); + Assert.assertTrue(shapeList.get(7).getTextPath().getSameLetterHeights()); + + TestUtil.verifyShape(ShapeType.TEXT_PLAIN_TEXT, "", 160.0, 24.0, 0.0d, 0.0d, shapeList.get(8)); + Assert.assertTrue(shapeList.get(8).getTextPath().getFitShape()); + Assert.assertEquals(24.0d, shapeList.get(8).getTextPath().getSize()); + + TestUtil.verifyShape(ShapeType.TEXT_PLAIN_TEXT, "", 160.0, 24.0, 0.0d, 0.0d, shapeList.get(9)); + Assert.assertFalse(shapeList.get(9).getTextPath().getFitShape()); + Assert.assertEquals(24.0d, shapeList.get(9).getTextPath().getSize()); + Assert.assertEquals(TextPathAlignment.RIGHT, shapeList.get(9).getTextPath().getTextPathAlignment()); + } + + @Test + public void shapeRevision() throws Exception { + //ExStart + //ExFor:ShapeBase.IsDeleteRevision + //ExFor:ShapeBase.IsInsertRevision + //ExSummary:Shows how to work with revision shapes. + Document doc = new Document(); + + Assert.assertFalse(doc.getTrackRevisions()); + + // Insert an inline shape without tracking revisions, which will make this shape not a revision of any kind. + Shape shape = new Shape(doc, ShapeType.CUBE); + shape.setWrapType(WrapType.INLINE); + shape.setWidth(100.0); + shape.setHeight(100.0); + doc.getFirstSection().getBody().getFirstParagraph().appendChild(shape); + + // Start tracking revisions and then insert another shape, which will be a revision. + doc.startTrackRevisions("John Doe"); + + shape = new Shape(doc, ShapeType.SUN); + shape.setWrapType(WrapType.INLINE); + shape.setWidth(100.0); + shape.setHeight(100.0); + doc.getFirstSection().getBody().getFirstParagraph().appendChild(shape); + + List shapeList = Arrays.stream(doc.getChildNodes(NodeType.SHAPE, true).toArray()) + .filter(Shape.class::isInstance) + .map(Shape.class::cast) + .collect(Collectors.toList()); + Assert.assertEquals(shapeList.size(), 2); + + Shape firstShape = shapeList.get(0); + firstShape.remove(); + + // Since we removed that shape while we were tracking changes, + // the shape persists in the document and counts as a delete revision. + // Accepting this revision will remove the shape permanently, and rejecting it will keep it in the document. + Assert.assertEquals(ShapeType.CUBE, shapeList.get(0).getShapeType()); + Assert.assertTrue(shapeList.get(0).isDeleteRevision()); + + // And we inserted another shape while tracking changes, so that shape will count as an insert revision. + // Accepting this revision will assimilate this shape into the document as a non-revision, + // and rejecting the revision will remove this shape permanently. + Assert.assertEquals(ShapeType.SUN, shapeList.get(1).getShapeType()); + Assert.assertTrue(shapeList.get(1).isInsertRevision()); + //ExEnd + } + + @Test + public void moveRevisions() throws Exception { + //ExStart + //ExFor:ShapeBase.IsMoveFromRevision + //ExFor:ShapeBase.IsMoveToRevision + //ExSummary:Shows how to identify move revision shapes. + // A move revision is when we move an element in the document body by cut-and-pasting it in Microsoft Word while + // tracking changes. If we involve an inline shape in such a text movement, that shape will also be a revision. + // Copying-and-pasting or moving floating shapes do not create move revisions. + Document doc = new Document(getMyDir() + "Revision shape.docx"); + + // Move revisions consist of pairs of "Move from", and "Move to" revisions. We moved in this document in one shape, + // but until we accept or reject the move revision, there will be two instances of that shape. + List shapeList = Arrays.stream(doc.getChildNodes(NodeType.SHAPE, true).toArray()) + .filter(Shape.class::isInstance) + .map(Shape.class::cast) + .collect(Collectors.toList()); + Assert.assertEquals(shapeList.size(), 2); + + Shape firstShape = shapeList.get(0); + + // This is the "Move to" revision, which is the shape at its arrival destination. + // If we accept the revision, this "Move to" revision shape will disappear, + // and the "Move from" revision shape will remain. + Assert.assertFalse(shapeList.get(0).isMoveFromRevision()); + Assert.assertTrue(shapeList.get(0).isMoveToRevision()); + + // This is the "Move from" revision, which is the shape at its original location. + // If we accept the revision, this "Move from" revision shape will disappear, + // and the "Move to" revision shape will remain. + Assert.assertTrue(shapeList.get(1).isMoveFromRevision()); + Assert.assertFalse(shapeList.get(1).isMoveToRevision()); + //ExEnd + } + + @Test + public void adjustWithEffects() throws Exception { + //ExStart + //ExFor:ShapeBase.AdjustWithEffects(RectangleF) + //ExFor:ShapeBase.BoundsWithEffects + //ExSummary:Shows how to check how a shape's bounds are affected by shape effects. + Document doc = new Document(getMyDir() + "Shape shadow effect.docx"); + List shapeList = Arrays.stream(doc.getChildNodes(NodeType.SHAPE, true).toArray()) + .filter(Shape.class::isInstance) + .map(Shape.class::cast) + .collect(Collectors.toList()); + Assert.assertEquals(shapeList.size(), 2); + + Shape firstShape = shapeList.get(0); + Shape secondShape = shapeList.get(1); + + // The two shapes are identical in terms of dimensions and shape type. + Assert.assertEquals(firstShape.getWidth(), secondShape.getWidth()); + Assert.assertEquals(firstShape.getHeight(), secondShape.getHeight()); + Assert.assertEquals(firstShape.getShapeType(), secondShape.getShapeType()); + + // The first shape has no effects, and the second one has a shadow and thick outline. + // These effects make the size of the second shape's silhouette bigger than that of the first. + // Even though the rectangle's size shows up when we click on these shapes in Microsoft Word, + // the visible outer bounds of the second shape are affected by the shadow and outline and thus are bigger. + // We can use the "AdjustWithEffects" method to see the true size of the shape. + Assert.assertEquals(0.0, firstShape.getStrokeWeight()); + Assert.assertEquals(20.0, secondShape.getStrokeWeight()); + Assert.assertFalse(firstShape.getShadowEnabled()); + Assert.assertTrue(secondShape.getShadowEnabled()); + + Shape shape = firstShape; + + // Run this method to get the size of the rectangle adjusted for all our shape effects. + Rectangle2D.Float rectangleFOut = shape.adjustWithEffects(new Rectangle2D.Float(200f, 200f, 1000f, 1000f)); + + // Since the shape has no border-changing effects, its boundary dimensions are unaffected. + Assert.assertEquals(200.0, rectangleFOut.getX()); + Assert.assertEquals(200.0, rectangleFOut.getY()); + Assert.assertEquals(1000.0, rectangleFOut.getWidth()); + Assert.assertEquals(1000.0, rectangleFOut.getHeight()); + + // Verify the final extent of the first shape, in points. + Assert.assertEquals(0.0, shape.getBoundsWithEffects().getX()); + Assert.assertEquals(0.0, shape.getBoundsWithEffects().getY()); + Assert.assertEquals(147.0, shape.getBoundsWithEffects().getWidth()); + Assert.assertEquals(147.0, shape.getBoundsWithEffects().getHeight()); + + shape = secondShape; + rectangleFOut = shape.adjustWithEffects(new Rectangle2D.Float(200f, 200f, 1000f, 1000f)); + + // The shape effects have moved the apparent top left corner of the shape slightly. + Assert.assertEquals(171.5, rectangleFOut.getX()); + Assert.assertEquals(167.0, rectangleFOut.getY()); + + // The effects have also affected the visible dimensions of the shape. + Assert.assertEquals(1045.0, rectangleFOut.getWidth()); + Assert.assertEquals(1133.5, rectangleFOut.getHeight()); + + // The effects have also affected the visible bounds of the shape. + Assert.assertEquals(-28.5, shape.getBoundsWithEffects().getX()); + Assert.assertEquals(-33.0, shape.getBoundsWithEffects().getY()); + Assert.assertEquals(192.0, shape.getBoundsWithEffects().getWidth()); + Assert.assertEquals(280.5, shape.getBoundsWithEffects().getHeight()); + //ExEnd + } + + @Test + public void renderAllShapes() throws Exception { + //ExStart + //ExFor:ShapeBase.GetShapeRenderer + //ExFor:NodeRendererBase.Save(Stream, ImageSaveOptions) + //ExSummary:Shows how to use a shape renderer to export shapes to files in the local file system. + Document doc = new Document(getMyDir() + "Various shapes.docx"); + NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); + + Assert.assertEquals(7, shapes.getCount()); + + // There are 7 shapes in the document, including one group shape with 2 child shapes. + // We will render every shape to an image file in the local file system + // while ignoring the group shapes since they have no appearance. + // This will produce 6 image files. + for (Shape shape : (Iterable) doc.getChildNodes(NodeType.SHAPE, true)) { + ShapeRenderer renderer = shape.getShapeRenderer(); + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.PNG); + renderer.save(getArtifactsDir() + MessageFormat.format("Shape.RenderAllShapes.{0}.png", shape.getName()), options); + } + //ExEnd + } + + @Test + public void documentHasSmartArtObject() throws Exception { + //ExStart + //ExFor:Shape.HasSmartArt + //ExSummary:Shows how to count the number of shapes in a document with SmartArt objects. + Document doc = new Document(getMyDir() + "SmartArt.docx"); + + int count = 0; + for (Shape shape : (Iterable) doc.getChildNodes(NodeType.SHAPE, true)) { + if (shape.hasSmartArt()) + count++; + } + + Assert.assertEquals(2, count); + //ExEnd + } + + @Test + public void officeMathRenderer() throws Exception { + //ExStart + //ExFor:NodeRendererBase + //ExFor:NodeRendererBase.BoundsInPoints + //ExFor:NodeRendererBase.GetBoundsInPixels(Single, Single) + //ExFor:NodeRendererBase.GetBoundsInPixels(Single, Single, Single) + //ExFor:NodeRendererBase.GetOpaqueBoundsInPixels(Single, Single) + //ExFor:NodeRendererBase.GetOpaqueBoundsInPixels(Single, Single, Single) + //ExFor:NodeRendererBase.GetSizeInPixels(Single, Single) + //ExFor:NodeRendererBase.GetSizeInPixels(Single, Single, Single) + //ExFor:NodeRendererBase.OpaqueBoundsInPoints + //ExFor:NodeRendererBase.SizeInPoints + //ExFor:OfficeMathRenderer + //ExFor:OfficeMathRenderer.#ctor(OfficeMath) + //ExSummary:Shows how to measure and scale shapes. + Document doc = new Document(getMyDir() + "Office math.docx"); + + OfficeMath officeMath = (OfficeMath) doc.getChild(NodeType.OFFICE_MATH, 0, true); + OfficeMathRenderer renderer = new OfficeMathRenderer(officeMath); + + Assert.assertEquals(122.0f, renderer.getBoundsInPoints().getWidth(), 0.25f); + Assert.assertEquals(12.9f, renderer.getBoundsInPoints().getHeight(), 0.1f); + + // Shapes with transparent parts may contain different values in the "OpaqueBoundsInPoints" properties. + Assert.assertEquals(122.0f, renderer.getOpaqueBoundsInPoints().getWidth(), 0.25f); + Assert.assertEquals(14.2f, renderer.getOpaqueBoundsInPoints().getHeight(), 0.1f); + + // Get the shape size in pixels, with linear scaling to a specific DPI. + Rectangle bounds = renderer.getBoundsInPixels(1.0f, 96.0f); + + Assert.assertEquals(163.0, bounds.getWidth()); + Assert.assertEquals(18.0, bounds.getHeight()); + + // Get the shape size in pixels, but with a different DPI for the horizontal and vertical dimensions. + bounds = renderer.getBoundsInPixels(1.0f, 96.0f, 150.0f); + Assert.assertEquals(163.0, bounds.getWidth()); + Assert.assertEquals(27.0, bounds.getHeight()); + + // The opaque bounds may vary here also. + bounds = renderer.getOpaqueBoundsInPixels(1.0f, 96.0f); + + Assert.assertEquals(163.0, bounds.getWidth()); + Assert.assertEquals(19.0, bounds.getHeight()); + + bounds = renderer.getOpaqueBoundsInPixels(1.0f, 96.0f, 150.0f); + + Assert.assertEquals(163.0, bounds.getWidth()); + Assert.assertEquals(29.0, bounds.getHeight()); + //ExEnd + } + + @Test + public void shapeTypes() throws Exception + { + //ExStart + //ExFor:ShapeType + //ExSummary:Shows how Aspose.Words identify shapes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertShape(ShapeType.HEPTAGON, RelativeHorizontalPosition.PAGE, 0.0, + RelativeVerticalPosition.PAGE, 0.0, 0.0, 0.0, WrapType.NONE); + + builder.insertShape(ShapeType.CLOUD, RelativeHorizontalPosition.RIGHT_MARGIN, 0.0, + RelativeVerticalPosition.PAGE, 0.0, 0.0, 0.0, WrapType.NONE); + + builder.insertShape(ShapeType.MATH_PLUS, RelativeHorizontalPosition.RIGHT_MARGIN, 0.0, + RelativeVerticalPosition.PAGE, 0.0, 0.0, 0.0, WrapType.NONE); + + // To correct identify shape types you need to work with shapes as DML. + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(SaveFormat.DOCX); + { + // "Strict" or "Transitional" compliance allows to save shape as DML. + saveOptions.setCompliance(OoxmlCompliance.ISO_29500_2008_TRANSITIONAL); + } + + doc.save(getArtifactsDir() + "Shape.ShapeTypes.docx", saveOptions); + doc = new Document(getArtifactsDir() + "Shape.ShapeTypes.docx"); + + List shapes = Arrays.stream(doc.getChildNodes(NodeType.SHAPE, true).toArray()) + .filter(Shape.class::isInstance) + .map(Shape.class::cast) + .collect(Collectors.toList()); + + for (Shape shape : shapes) + { + System.out.println(shape.getShapeType()); + } + //ExEnd + } + + @Test + public void isDecorative() throws Exception + { + //ExStart + //ExFor:ShapeBase.IsDecorative + //ExSummary:Shows how to set that the shape is decorative. + Document doc = new Document(getMyDir() + "Decorative shapes.docx"); + + Shape shape = (Shape) doc.getChildNodes(NodeType.SHAPE, true).get(0); + Assert.assertTrue(shape.isDecorative()); + + // If "AlternativeText" is not empty, the shape cannot be decorative. + // That's why our value has changed to 'false'. + shape.setAlternativeText("Alternative text."); + Assert.assertFalse(shape.isDecorative()); + + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.moveToDocumentEnd(); + // Create a new shape as decorative. + shape = builder.insertShape(ShapeType.RECTANGLE, 100.0, 100.0); + shape.isDecorative(true); + + doc.save(getArtifactsDir() + "Shape.IsDecorative.docx"); + //ExEnd + } + + @Test + public void fillImage() throws Exception + { + //ExStart + //ExFor:Fill.SetImage(String) + //ExFor:Fill.SetImage(Byte[]) + //ExFor:Fill.SetImage(Stream) + //ExSummary:Shows how to set shape fill type as image. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // There are several ways of setting image. + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 80.0, 80.0); + // 1 - Using a local system filename: + shape.getFill().setImage(getImageDir() + "Logo.jpg"); + doc.save(getArtifactsDir() + "Shape.FillImage.FileName.docx"); + + // 2 - Load a file into a byte array: + shape.getFill().setImage(Files.readAllBytes(Paths.get(getImageDir() + "Logo.jpg"))); + doc.save(getArtifactsDir() + "Shape.FillImage.ByteArray.docx"); + + // 3 - From a stream: + FileInputStream stream = new FileInputStream(getImageDir() + "Logo.jpg"); + try /*JAVA: was using*/ + { + shape.getFill().setImage(stream); + } + finally { if (stream != null) stream.close(); } + doc.save(getArtifactsDir() + "Shape.FillImage.Stream.docx"); + //ExEnd + } + + @Test + public void shadowFormat() throws Exception + { + //ExStart + //ExFor:ShadowFormat.Visible + //ExFor:ShadowFormat.Clear() + //ExFor:ShadowType + //ExSummary:Shows how to work with a shadow formatting for the shape. + Document doc = new Document(getMyDir() + "Shape stroke pattern border.docx"); + Shape shape = (Shape)doc.getChildNodes(NodeType.SHAPE, true).get(0); + + if (shape.getShadowFormat().getVisible() && shape.getShadowFormat().getType() == ShadowType.SHADOW_2) + shape.getShadowFormat().setType(ShadowType.SHADOW_7); + + if (shape.getShadowFormat().getType() == ShadowType.SHADOW_MIXED) + shape.getShadowFormat().clear(); + //ExEnd + } + + @Test + public void noTextRotation() throws Exception + { + //ExStart + //ExFor:TextBox.NoTextRotation + //ExSummary:Shows how to disable text rotation when the shape is rotate. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertShape(ShapeType.ELLIPSE, 20.0, 20.0); + shape.getTextBox().setNoTextRotation(true); + + doc.save(getArtifactsDir() + "Shape.NoTextRotation.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.NoTextRotation.docx"); + shape = (Shape)doc.getChildNodes(NodeType.SHAPE, true).get(0); + + Assert.assertEquals(true, shape.getTextBox().getNoTextRotation()); + } + + @Test + public void relativeSizeAndPosition() throws Exception + { + //ExStart + //ExFor:ShapeBase.RelativeHorizontalSize + //ExFor:ShapeBase.RelativeVerticalSize + //ExFor:ShapeBase.WidthRelative + //ExFor:ShapeBase.HeightRelative + //ExFor:ShapeBase.TopRelative + //ExFor:ShapeBase.LeftRelative + //ExFor:RelativeHorizontalSize + //ExFor:RelativeVerticalSize + //ExSummary:Shows how to set relative size and position. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Adding a simple shape with absolute size and position. + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 100.0, 40.0); + // Set WrapType to WrapType.None since Inline shapes are automatically converted to absolute units. + shape.setWrapType(WrapType.NONE); + + // Checking and setting the relative horizontal size. + if (shape.getRelativeHorizontalSize() == RelativeHorizontalSize.DEFAULT) + { + // Setting the horizontal size binding to Margin. + shape.setRelativeHorizontalSize(RelativeHorizontalSize.MARGIN); + // Setting the width to 50% of Margin width. + shape.setWidthRelative(50f); + } + + // Checking and setting the relative vertical size. + if (shape.getRelativeVerticalSize() == RelativeVerticalSize.DEFAULT) + { + // Setting the vertical size binding to Margin. + shape.setRelativeVerticalSize(RelativeVerticalSize.MARGIN); + // Setting the heigh to 30% of Margin height. + shape.setHeightRelative(30f); + } + + // Checking and setting the relative vertical position. + if (shape.getRelativeVerticalPosition() == RelativeVerticalPosition.PARAGRAPH) + { + // etting the position binding to TopMargin. + shape.setRelativeVerticalPosition(RelativeVerticalPosition.TOP_MARGIN); + // Setting relative Top to 30% of TopMargin position. + shape.setTopRelative(30f); + } + + // Checking and setting the relative horizontal position. + if (shape.getRelativeHorizontalPosition() == RelativeHorizontalPosition.DEFAULT) + { + // Setting the position binding to RightMargin. + shape.setRelativeHorizontalPosition(RelativeHorizontalPosition.RIGHT_MARGIN); + // The position relative value can be negative. + shape.setLeftRelative(-260); + } + + doc.save(getArtifactsDir() + "Shape.RelativeSizeAndPosition.docx"); + //ExEnd + } + + @Test + public void fillBaseColor() throws Exception + { + //ExStart:FillBaseColor + //GistId:6d898be16b796fcf7448ad3bfe18e51c + //ExFor:Fill.BaseForeColor + //ExFor:Stroke.BaseForeColor + //ExSummary:Shows how to get foreground color without modifiers. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(); + + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 100.0, 40.0); + shape.getFill().setForeColor(Color.RED); + shape.getFill().setForeTintAndShade(0.5); + shape.getStroke().getFill().setForeColor(Color.GREEN); + shape.getStroke().getFill().setTransparency(0.5); + + Assert.assertEquals(new Color((255), (188), (188), (255)).getRGB(), shape.getFill().getForeColor().getRGB()); + Assert.assertEquals(Color.RED.getRGB(), shape.getFill().getBaseForeColor().getRGB()); + + Assert.assertEquals(new Color((0), (255), (0), (128)).getRGB(), shape.getStroke().getForeColor().getRGB()); + Assert.assertEquals(Color.GREEN.getRGB(), shape.getStroke().getBaseForeColor().getRGB()); + + Assert.assertEquals(Color.GREEN.getRGB(), shape.getStroke().getFill().getForeColor().getRGB()); + Assert.assertEquals(Color.GREEN.getRGB(), shape.getStroke().getFill().getBaseForeColor().getRGB()); + //ExEnd:FillBaseColor + } + + @Test + public void fitImageToShape() throws Exception + { + //ExStart:FitImageToShape + //GistId:6d898be16b796fcf7448ad3bfe18e51c + //ExFor:ImageData.FitImageToShape + //ExSummary:Shows hot to fit the image data to Shape frame. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert an image shape and leave its orientation in its default state. + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 300.0, 450.0); + shape.getImageData().setImage(getImageDir() + "Barcode.png"); + shape.getImageData().fitImageToShape(); + + doc.save(getArtifactsDir() + "Shape.FitImageToShape.docx"); + //ExEnd:FitImageToShape + } + + @Test + public void strokeForeThemeColors() throws Exception + { + //ExStart:StrokeForeThemeColors + //GistId:b9e728d2381f759edd5b31d64c1c4d3f + //ExFor:Stroke.ForeThemeColor + //ExFor:Stroke.ForeTintAndShade + //ExSummary:Shows how to set fore theme color and tint and shade. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertShape(ShapeType.TEXT_BOX, 100.0, 40.0); + Stroke stroke = shape.getStroke(); + stroke.setForeThemeColor(ThemeColor.DARK_1); + stroke.setForeTintAndShade(0.5); + + doc.save(getArtifactsDir() + "Shape.StrokeForeThemeColors.docx"); + //ExEnd:StrokeForeThemeColors + + doc = new Document(getArtifactsDir() + "Shape.StrokeForeThemeColors.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(ThemeColor.DARK_1, shape.getStroke().getForeThemeColor()); + Assert.assertEquals(0.5, shape.getStroke().getForeTintAndShade()); + } + + @Test + public void strokeBackThemeColors() throws Exception + { + //ExStart:StrokeBackThemeColors + //GistId:b9e728d2381f759edd5b31d64c1c4d3f + //ExFor:Stroke.BackThemeColor + //ExFor:Stroke.BackTintAndShade + //ExSummary:Shows how to set back theme color and tint and shade. + Document doc = new Document(getMyDir() + "Stroke gradient outline.docx"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + Stroke stroke = shape.getStroke(); + stroke.setBackThemeColor(ThemeColor.DARK_2); + stroke.setBackTintAndShade(0.2d); + + doc.save(getArtifactsDir() + "Shape.StrokeBackThemeColors.docx"); + //ExEnd:StrokeBackThemeColors + + doc = new Document(getArtifactsDir() + "Shape.StrokeBackThemeColors.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(ThemeColor.DARK_2, shape.getStroke().getBackThemeColor()); + double precision = 1e-6; + Assert.assertEquals(0.2d, shape.getStroke().getBackTintAndShade(), precision); + } + + @Test + public void textBoxOleControl() throws Exception + { + //ExStart:TextBoxOleControl + //GistId:b9e728d2381f759edd5b31d64c1c4d3f + //ExFor:TextBoxControl + //ExFor:TextBoxControl.Text + //ExFor:TextBoxControl.Type + //ExSummary:Shows how to change text of the TextBox OLE control. + Document doc = new Document(getMyDir() + "Textbox control.docm"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + TextBoxControl textBoxControl = (TextBoxControl)shape.getOleFormat().getOleControl(); + Assert.assertEquals(textBoxControl.getText(), "Aspose.Words test"); + + textBoxControl.setText("Updated text"); + Assert.assertEquals(textBoxControl.getText(), "Updated text"); + //ExEnd:TextBoxOleControl + } + + @Test + public void glow() throws Exception + { + //ExStart:Glow + //GistId:31b7350f8d91d4b12eb43978940d566a + //ExFor:ShapeBase.Glow + //ExFor:GlowFormat + //ExFor:GlowFormat.Color + //ExFor:GlowFormat.Radius + //ExFor:GlowFormat.Transparency + //ExFor:GlowFormat.Remove() + //ExSummary:Shows how to interact with glow shape effect. + Document doc = new Document(getMyDir() + "Various shapes.docx"); + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + // Apply glow effect to the shape. + shape.getGlow().setColor(new Color(0xFFFA8072)); + shape.getGlow().setRadius(30.0); + shape.getGlow().setTransparency(0.15); + + doc.save(getArtifactsDir() + "Shape.Glow.docx"); + + doc = new Document(getArtifactsDir() + "Shape.Glow.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + // Check glow effect attributes. + Assert.assertEquals(new Color((250), (128), (114), (217)).getRGB(), shape.getGlow().getColor().getRGB()); + Assert.assertEquals(30, shape.getGlow().getRadius()); + Assert.assertEquals(0.15d, shape.getGlow().getTransparency(), 0.01d); + + // Remove glow effect from the shape. + shape.getGlow().remove(); + + Assert.assertEquals(Color.BLACK.getRGB(), shape.getGlow().getColor().getRGB()); + Assert.assertEquals(0, shape.getGlow().getRadius()); + Assert.assertEquals(0, shape.getGlow().getTransparency()); + //ExEnd:Glow + } + + @Test + public void reflection() throws Exception + { + //ExStart:Reflection + //GistId:31b7350f8d91d4b12eb43978940d566a + //ExFor:ShapeBase.Reflection + //ExFor:ReflectionFormat + //ExFor:ReflectionFormat.Size + //ExFor:ReflectionFormat.Blur + //ExFor:ReflectionFormat.Transparency + //ExFor:ReflectionFormat.Distance + //ExFor:ReflectionFormat.Remove() + //ExSummary:Shows how to interact with reflection shape effect. + Document doc = new Document(getMyDir() + "Various shapes.docx"); + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + // Apply reflection effect to the shape. + shape.getReflection().setTransparency(0.37); + shape.getReflection().setSize(0.48); + shape.getReflection().setBlur(17.5); + shape.getReflection().setDistance(9.2); + + doc.save(getArtifactsDir() + "Shape.Reflection.docx"); + + doc = new Document(getArtifactsDir() + "Shape.Reflection.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + // Check reflection effect attributes. + Assert.assertEquals(0.37d, shape.getReflection().getTransparency(), 0.01d); + Assert.assertEquals(0.48d, shape.getReflection().getSize(), 0.01d); + Assert.assertEquals(17.5d, shape.getReflection().getBlur(), 0.01d); + Assert.assertEquals(9.2d, shape.getReflection().getDistance(), 0.01d); + + // Remove reflection effect from the shape. + shape.getReflection().remove(); + + Assert.assertEquals(0, shape.getReflection().getTransparency()); + Assert.assertEquals(0, shape.getReflection().getSize()); + Assert.assertEquals(0, shape.getReflection().getBlur()); + Assert.assertEquals(0, shape.getReflection().getDistance()); + //ExEnd:Reflection + } + + @Test + public void softEdge() throws Exception + { + //ExStart:SoftEdge + //GistId:f99d87e10ab87a581c52206321d8b617 + //ExFor:ShapeBase.SoftEdge + //ExFor:SoftEdgeFormat + //ExFor:SoftEdgeFormat.Radius + //ExFor:SoftEdgeFormat.Remove + //ExSummary:Shows how to work with soft edge formatting. + DocumentBuilder builder = new DocumentBuilder(); + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 200.0, 200.0); + + // Apply soft edge to the shape. + shape.getSoftEdge().setRadius(30.0); + + builder.getDocument().save(getArtifactsDir() + "Shape.SoftEdge.docx"); + + // Load document with rectangle shape with soft edge. + Document doc = new Document(getArtifactsDir() + "Shape.SoftEdge.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + // Check soft edge radius. + Assert.assertEquals(30, shape.getSoftEdge().getRadius()); + + // Remove soft edge from the shape. + shape.getSoftEdge().remove(); + + // Check radius of the removed soft edge. + Assert.assertEquals(0, shape.getSoftEdge().getRadius()); + //ExEnd:SoftEdge + } + + @Test + public void adjustments() throws Exception + { + //ExStart:Adjustments + //GistId:f99d87e10ab87a581c52206321d8b617 + //ExFor:Shape.Adjustments + //ExFor:AdjustmentCollection + //ExFor:AdjustmentCollection.Count + //ExFor:AdjustmentCollection.Item(Int32) + //ExFor:Adjustment + //ExFor:Adjustment.Name + //ExFor:Adjustment.Value + //ExSummary:Shows how to work with adjustment raw values. + Document doc = new Document(getMyDir() + "Rounded rectangle shape.docx"); + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + AdjustmentCollection adjustments = shape.getAdjustments(); + Assert.assertEquals(1, adjustments.getCount()); + + Adjustment adjustment = adjustments.get(0); + Assert.assertEquals("adj", adjustment.getName()); + Assert.assertEquals(16667, adjustment.getValue()); + + adjustment.setValue(30000); + + doc.save(getArtifactsDir() + "Shape.Adjustments.docx"); + //ExEnd:Adjustments + + doc = new Document(getArtifactsDir() + "Shape.Adjustments.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + adjustments = shape.getAdjustments(); + Assert.assertEquals(1, adjustments.getCount()); + + adjustment = adjustments.get(0); + Assert.assertEquals("adj", adjustment.getName()); + Assert.assertEquals(30000, adjustment.getValue()); + } + + @Test + public void shadowFormatColor() throws Exception + { + //ExStart:ShadowFormatColor + //GistId:a76df4b18bee76d169e55cdf6af8129c + //ExFor:ShapeBase.ShadowFormat + //ExFor:ShadowFormat + //ExFor:ShadowFormat.Color + //ExFor:ShadowFormat.Type + //ExSummary:Shows how to get shadow color. + Document doc = new Document(getMyDir() + "Shadow color.docx"); + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + ShadowFormat shadowFormat = shape.getShadowFormat(); + + Assert.assertEquals(Color.RED.getRGB(), shadowFormat.getColor().getRGB()); + Assert.assertEquals(ShadowType.SHADOW_MIXED, shadowFormat.getType()); + //ExEnd:ShadowFormatColor + } + + @Test + public void setActiveXProperties() throws Exception + { + //ExStart:SetActiveXProperties + //GistId:67585b023474b7f73b0066dd022cf938 + //ExFor:Forms2OleControl.ForeColor + //ExFor:Forms2OleControl.BackColor + //ExFor:Forms2OleControl.Height + //ExFor:Forms2OleControl.Width + //ExSummary:Shows how to set properties for ActiveX control. + Document doc = new Document(getMyDir() + "ActiveX controls.docx"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + Forms2OleControl oleControl = (Forms2OleControl)shape.getOleFormat().getOleControl(); + oleControl.setForeColor(new Color((0x17), (0xE1), (0x35))); + oleControl.setBackColor(new Color((0x33), (0x97), (0xF4))); + oleControl.setHeight(100.54); + oleControl.setWidth(201.06); + //ExEnd:SetActiveXProperties + + Assert.assertEquals(new Color((0x17), (0xE1), (0x35)).getRGB(), oleControl.getForeColor().getRGB()); + Assert.assertEquals(new Color((0x33), (0x97), (0xF4)).getRGB(), oleControl.getBackColor().getRGB()); + Assert.assertEquals(100.54, oleControl.getHeight()); + Assert.assertEquals(201.06, oleControl.getWidth()); + } + + @Test + public void selectRadioControl() throws Exception + { + //ExStart:SelectRadioControl + //GistId:67585b023474b7f73b0066dd022cf938 + //ExFor:OptionButtonControl + //ExFor:OptionButtonControl.Selected + //ExFor:OptionButtonControl.Type + //ExSummary:Shows how to select radio button. + Document doc = new Document(getMyDir() + "Radio buttons.docx"); + + Shape shape1 = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + OptionButtonControl optionButton1 = (OptionButtonControl)shape1.getOleFormat().getOleControl(); + // Deselect selected first item. + optionButton1.setSelected(false); + + Shape shape2 = (Shape)doc.getChild(NodeType.SHAPE, 1, true); + OptionButtonControl optionButton2 = (OptionButtonControl)shape2.getOleFormat().getOleControl(); + // Select second option button. + optionButton2.setSelected(true); + + Assert.assertEquals(Forms2OleControlType.OPTION_BUTTON, optionButton1.getType()); + Assert.assertEquals(Forms2OleControlType.OPTION_BUTTON, optionButton2.getType()); + + doc.save(getArtifactsDir() + "Shape.SelectRadioControl.docx"); + //ExEnd:SelectRadioControl + } + + @Test + public void checkedCheckBox() throws Exception + { + //ExStart:CheckedCheckBox + //GistId:67585b023474b7f73b0066dd022cf938 + //ExFor:CheckBoxControl + //ExFor:CheckBoxControl.Checked + //ExFor:CheckBoxControl.Type + //ExFor:Forms2OleControlType + //ExSummary:Shows how to change state of the CheckBox control. + Document doc = new Document(getMyDir() + "ActiveX controls.docx"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + CheckBoxControl checkBoxControl = (CheckBoxControl)shape.getOleFormat().getOleControl(); + checkBoxControl.setChecked(true); + + Assert.assertEquals(true, checkBoxControl.getChecked()); + Assert.assertEquals(Forms2OleControlType.CHECK_BOX, checkBoxControl.getType()); + //ExEnd:CheckedCheckBox + } + + @Test + public void insertGroupShape() throws Exception + { + //ExStart:InsertGroupShape + //GistId:6280fd6c1c1854468bea095ec2af902b + //ExFor:DocumentBuilder.InsertGroupShape(double, double, double, double, ShapeBase[]) + //ExFor:DocumentBuilder.InsertGroupShape(ShapeBase[]) + //ExSummary:Shows how to insert DML group shape. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape1 = builder.insertShape(ShapeType.RECTANGLE, 200.0, 250.0); + shape1.setLeft(20.0); + shape1.setTop(20.0); + shape1.getStroke().setColor(Color.RED); + + Shape shape2 = builder.insertShape(ShapeType.ELLIPSE, 150.0, 200.0); + shape2.setLeft(40.0); + shape2.setTop(50.0); + shape2.getStroke().setColor(Color.GREEN); + + // Dimensions for the new GroupShape node. + double left = 10.0; + double top = 10.0; + double width = 200.0; + double height = 300.0; + // Insert GroupShape node for the specified size which is inserted into the specified position. + GroupShape groupShape1 = builder.insertGroupShape(left, top, width, height, new Shape[] { shape1, shape2 }); + + // Insert GroupShape node which position and dimension will be calculated automatically. + Shape shape3 = (Shape)shape1.deepClone(true); + GroupShape groupShape2 = builder.insertGroupShape(shape3); + + doc.save(getArtifactsDir() + "Shape.InsertGroupShape.docx"); + //ExEnd:InsertGroupShape + } + + @Test + public void combineGroupShape() throws Exception + { + //ExStart:CombineGroupShape + //GistId:3f058a176ba0e9f656c60c6d60d757a1 + //ExFor:DocumentBuilder.InsertGroupShape(ShapeBase[]) + //ExSummary:Shows how to combine group shape with the shape. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape1 = builder.insertShape(ShapeType.RECTANGLE, 200.0, 250.0); + shape1.setLeft(20.0); + shape1.setTop(20.0); + shape1.getStroke().setColor(Color.RED); + + Shape shape2 = builder.insertShape(ShapeType.ELLIPSE, 150.0, 200.0); + shape2.setLeft(40.0); + shape2.setTop(50.0); + shape2.getStroke().setColor(Color.GREEN); + + // Combine shapes into a GroupShape node which is inserted into the specified position. + GroupShape groupShape1 = builder.insertGroupShape(shape1, shape2); + + // Combine Shape and GroupShape nodes. + Shape shape3 = (Shape)shape1.deepClone(true); + GroupShape groupShape2 = builder.insertGroupShape(groupShape1, shape3); + + doc.save(getArtifactsDir() + "Shape.CombineGroupShape.docx"); + //ExEnd:CombineGroupShape + + doc = new Document(getArtifactsDir() + "Shape.CombineGroupShape.docx"); + + NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); + for (Shape shape : (Iterable) shapes) + { + Assert.assertNotEquals(0, shape.getWidth()); + Assert.assertNotEquals(0, shape.getHeight()); + } + } + + @Test + public void insertCommandButton() throws Exception + { + //ExStart:InsertCommandButton + //GistId:3f058a176ba0e9f656c60c6d60d757a1 + //ExFor:CommandButtonControl + //ExFor:CommandButtonControl.#ctor + //ExFor:CommandButtonControl.Type + //ExFor:DocumentBuilder.InsertForms2OleControl(Forms2OleControl) + //ExSummary:Shows how to insert ActiveX control. + DocumentBuilder builder = new DocumentBuilder(); + + CommandButtonControl button1 = new CommandButtonControl(); + Shape shape = builder.insertForms2OleControl(button1); + Assert.assertEquals(Forms2OleControlType.COMMAND_BUTTON, button1.getType()); + //ExEnd:InsertCommandButton + } + + @Test + public void hidden() throws Exception + { + //ExStart:Hidden + //GistId:3f058a176ba0e9f656c60c6d60d757a1 + //ExFor:ShapeBase.Hidden + //ExSummary:Shows how to hide the shape. + Document doc = new Document(getMyDir() + "Shadow color.docx"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + if (!shape.getHidden()) + shape.setHidden(true); + + doc.save(getArtifactsDir() + "Shape.Hidden.docx"); + //ExEnd:Hidden + } + + @Test + public void commandButtonCaption() throws Exception + { + //ExStart:CommandButtonCaption + //GistId:72d57eeddb7fb342fd51b26e5fcf9642 + //ExFor:Forms2OleControl.Caption + //ExSummary:Shows how to set caption for ActiveX control. + DocumentBuilder builder = new DocumentBuilder(); + + CommandButtonControl button1 = new CommandButtonControl(); { button1.setCaption("Button caption"); } + Shape shape = builder.insertForms2OleControl(button1); + Assert.assertEquals("Button caption", button1.getCaption()); + //ExEnd:CommandButtonCaption + } + + @Test + public void shadowFormatTransparency() throws Exception + { + //ExStart:ShadowFormatTransparency + //GistId:045648ef22da6b384ebcf0344717bfb5 + //ExFor:ShadowFormat.Color + //ExFor:ShadowFormat.Transparency + //ExSummary:Shows how to set a color with transparency. + Document doc = new Document(getMyDir() + "Shadow color.docx"); + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + ShadowFormat shadowFormat = shape.getShadowFormat(); + shadowFormat.setType(ShadowType.SHADOW_21); + shadowFormat.setColor(Color.RED); + shadowFormat.setTransparency(0.8); + + doc.save(getArtifactsDir() + "Shape.ShadowFormatTransparency.docx"); + //ExEnd:ShadowFormatTransparency + } +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExSignDocumentCustom.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExSignDocumentCustom.java new file mode 100644 index 00000000..24d8cbb9 --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExSignDocumentCustom.java @@ -0,0 +1,114 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import TestData.TestClasses.SignPersonTestClass; +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.UUID; + +/// +/// This example demonstrates how to add new signature line to the document and sign it with your personal signature . +/// +@Test +public class ExSignDocumentCustom extends ApiExampleBase { + //ExStart + //ExFor:CertificateHolder + //ExFor:SignatureLineOptions.Signer + //ExFor:SignatureLineOptions.SignerTitle + //ExFor:SignatureLine.Id + //ExFor:SignOptions.SignatureLineId + //ExFor:SignOptions.SignatureLineImage + //ExFor:DigitalSignatureUtil.Sign(String, String, CertificateHolder, SignOptions) + //ExSummary:Shows how to add a signature line to a document, and then sign it using a digital certificate. + @Test(description = "WORDSNET-16868") //ExSkip + public static void sign() throws Exception { + String signPersonName = "Ron Williams"; + String srcDocumentPath = getMyDir() + "Document.docx"; + String dstDocumentPath = getArtifactsDir() + "SignDocumentCustom.Sign.docx"; + String certificatePath = getMyDir() + "morzal.pfx"; + String certificatePassword = "aw"; + + // We need to create simple list with test signers for this example. + createSignPersonData(); + System.out.println("Test data successfully added!"); + + // Get sign person object by name of the person who must sign a document. + // This an example, in real use case you would return an object from a database. + SignPersonTestClass signPersonInfo = gSignPersonList.stream().filter(x -> x.getName() == signPersonName).findFirst().get(); + + if (signPersonInfo != null) { + signDocument(srcDocumentPath, dstDocumentPath, signPersonInfo, certificatePath, certificatePassword); + System.out.println("Document successfully signed!"); + } else { + System.out.println("Sign person does not exist, please check your parameters."); + Assert.fail(); //ExSkip + } + + // Now do something with a signed document, for example, save it to your database. + // Use 'new Document(dstDocumentPath)' for loading a signed document. + } + + /// + /// Signs the document obtained at the source location and saves it to the specified destination. + /// + private static void signDocument(final String srcDocumentPath, final String dstDocumentPath, + final SignPersonTestClass signPersonInfo, final String certificatePath, + final String certificatePassword) throws Exception { + // Create new document instance based on a test file that we need to sign. + Document document = new Document(srcDocumentPath); + DocumentBuilder builder = new DocumentBuilder(document); + + // Add info about responsible person who sign a document. + SignatureLineOptions signatureLineOptions = new SignatureLineOptions(); + signatureLineOptions.setSigner(signPersonInfo.getName()); + signatureLineOptions.setSignerTitle(signPersonInfo.getPosition()); + + // Add signature line for responsible person who sign a document. + SignatureLine signatureLine = builder.insertSignatureLine(signatureLineOptions).getSignatureLine(); + signatureLine.setId(signPersonInfo.getPersonId()); + + // Save a document with line signatures into temporary file for future signing. + builder.getDocument().save(dstDocumentPath); + + // Create holder of certificate instance based on your personal certificate. + // This is the test certificate generated for this example. + CertificateHolder certificateHolder = CertificateHolder.create(certificatePath, certificatePassword); + + // Link our signature line with personal signature. + SignOptions signOptions = new SignOptions(); + signOptions.setSignatureLineId(signPersonInfo.getPersonId()); + signOptions.setSignatureLineImage(signPersonInfo.getImage()); + + // Sign a document which contains signature line with personal certificate. + DigitalSignatureUtil.sign(dstDocumentPath, dstDocumentPath, certificateHolder, signOptions); + } + + /// + /// Create test data that contains info about sing persons. + /// + private static void createSignPersonData() throws IOException { + InputStream inputStream = new FileInputStream(getImageDir() + "Logo.jpg"); + + gSignPersonList = new ArrayList<>(); + gSignPersonList.add(new SignPersonTestClass(UUID.randomUUID(), "Ron Williams", "Chief Executive Officer", + DocumentHelper.getBytesFromStream(inputStream))); + gSignPersonList.add(new SignPersonTestClass(UUID.randomUUID(), "Stephen Morse", "Head of Compliance", + DocumentHelper.getBytesFromStream(inputStream))); + } + + private static ArrayList gSignPersonList; + //ExEnd +} diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExSmartTag.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExSmartTag.java new file mode 100644 index 00000000..2c3a9f4f --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExSmartTag.java @@ -0,0 +1,220 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.apache.commons.lang.StringUtils; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; + +public class ExSmartTag extends ApiExampleBase { + //ExStart + //ExFor:CompositeNode.RemoveSmartTags + //ExFor:CustomXmlProperty + //ExFor:CustomXmlProperty.#ctor(String,String,String) + //ExFor:CustomXmlProperty.Name + //ExFor:CustomXmlProperty.Value + //ExFor:SmartTag + //ExFor:SmartTag.#ctor(DocumentBase) + //ExFor:SmartTag.Accept(DocumentVisitor) + //ExFor:SmartTag.AcceptStart(DocumentVisitor) + //ExFor:SmartTag.AcceptEnd(DocumentVisitor) + //ExFor:SmartTag.Element + //ExFor:SmartTag.Properties + //ExFor:SmartTag.Uri + //ExSummary:Shows how to create smart tags. + @Test //ExSkip + public void create() throws Exception { + Document doc = new Document(); + + // A smart tag appears in a document with Microsoft Word recognizes a part of its text as some form of data, + // such as a name, date, or address, and converts it to a hyperlink that displays a purple dotted underline. + SmartTag smartTag = new SmartTag(doc); + + // Smart tags are composite nodes that contain their recognized text in its entirety. + // Add contents to this smart tag manually. + smartTag.appendChild(new Run(doc, "May 29, 2019")); + + // Microsoft Word may recognize the above contents as being a date. + // Smart tags use the "Element" property to reflect the type of data they contain. + smartTag.setElement("date"); + + // Some smart tag types process their contents further into custom XML properties. + smartTag.getProperties().add(new CustomXmlProperty("Day", "", "29")); + smartTag.getProperties().add(new CustomXmlProperty("Month", "", "5")); + smartTag.getProperties().add(new CustomXmlProperty("Year", "", "2019")); + + // Set the smart tag's URI to the default value. + smartTag.setUri("urn:schemas-microsoft-com:office:smarttags"); + + doc.getFirstSection().getBody().getFirstParagraph().appendChild(smartTag); + doc.getFirstSection().getBody().getFirstParagraph().appendChild(new Run(doc, " is a date. ")); + + // Create another smart tag for a stock ticker. + smartTag = new SmartTag(doc); + smartTag.setElement("stockticker"); + smartTag.setUri("urn:schemas-microsoft-com:office:smarttags"); + + smartTag.appendChild(new Run(doc, "MSFT")); + + doc.getFirstSection().getBody().getFirstParagraph().appendChild(smartTag); + doc.getFirstSection().getBody().getFirstParagraph().appendChild(new Run(doc, " is a stock ticker.")); + + // Print all the smart tags in our document using a document visitor. + doc.accept(new SmartTagPrinter()); + + // Older versions of Microsoft Word support smart tags. + doc.save(getArtifactsDir() + "SmartTag.Create.doc"); + + // Use the "RemoveSmartTags" method to remove all smart tags from a document. + Assert.assertEquals(2, doc.getChildNodes(NodeType.SMART_TAG, true).getCount()); + + doc.removeSmartTags(); + + Assert.assertEquals(0, doc.getChildNodes(NodeType.SMART_TAG, true).getCount()); + testCreate(new Document(getArtifactsDir() + "SmartTag.Create.doc")); //ExSkip + } + + /// + /// Prints visited smart tags and their contents. + /// + private static class SmartTagPrinter extends DocumentVisitor { + /// + /// Called when a SmartTag node is encountered in the document. + /// + public /*override*/ /*VisitorAction*/int visitSmartTagStart(SmartTag smartTag) { + System.out.println("Smart tag type: {smartTag.Element}"); + return VisitorAction.CONTINUE; + } + + /// + /// Called when the visiting of a SmartTag node is ended. + /// + public /*override*/ /*VisitorAction*/int visitSmartTagEnd(SmartTag smartTag) { + System.out.println("\tContents: \"{smartTag.ToString(SaveFormat.Text)}\""); + + if (smartTag.getProperties().getCount() == 0) { + System.out.println("\tContains no properties"); + } else { + System.out.println("\tProperties: "); + String[] properties = new String[smartTag.getProperties().getCount()]; + int index = 0; + + for (CustomXmlProperty cxp : smartTag.getProperties()) + properties[index++] = MessageFormat.format("\"{0}\" = \"{1}\"", cxp.getName(), cxp.getValue()); + + System.out.println(StringUtils.join(properties, ", ")); + } + + return VisitorAction.CONTINUE; + } + } + //ExEnd + + private void testCreate(Document doc) { + SmartTag smartTag = (SmartTag) doc.getChild(NodeType.SMART_TAG, 0, true); + + Assert.assertEquals("date", smartTag.getElement()); + Assert.assertEquals("May 29, 2019", smartTag.getText()); + Assert.assertEquals("urn:schemas-microsoft-com:office:smarttags", smartTag.getUri()); + + Assert.assertEquals("Day", smartTag.getProperties().get(0).getName()); + Assert.assertEquals("", smartTag.getProperties().get(0).getUri()); + Assert.assertEquals("29", smartTag.getProperties().get(0).getValue()); + Assert.assertEquals("Month", smartTag.getProperties().get(1).getName()); + Assert.assertEquals("", smartTag.getProperties().get(1).getUri()); + Assert.assertEquals("5", smartTag.getProperties().get(1).getValue()); + Assert.assertEquals("Year", smartTag.getProperties().get(2).getName()); + Assert.assertEquals("", smartTag.getProperties().get(2).getUri()); + Assert.assertEquals("2019", smartTag.getProperties().get(2).getValue()); + + smartTag = (SmartTag) doc.getChild(NodeType.SMART_TAG, 1, true); + + Assert.assertEquals("stockticker", smartTag.getElement()); + Assert.assertEquals("MSFT", smartTag.getText()); + Assert.assertEquals("urn:schemas-microsoft-com:office:smarttags", smartTag.getUri()); + Assert.assertEquals(0, smartTag.getProperties().getCount()); + } + + @Test + public void properties() throws Exception { + //ExStart + //ExFor:CustomXmlProperty.Uri + //ExFor:CustomXmlPropertyCollection + //ExFor:CustomXmlPropertyCollection.Add(CustomXmlProperty) + //ExFor:CustomXmlPropertyCollection.Clear + //ExFor:CustomXmlPropertyCollection.Contains(String) + //ExFor:CustomXmlPropertyCollection.Count + //ExFor:CustomXmlPropertyCollection.GetEnumerator + //ExFor:CustomXmlPropertyCollection.IndexOfKey(String) + //ExFor:CustomXmlPropertyCollection.Item(Int32) + //ExFor:CustomXmlPropertyCollection.Item(String) + //ExFor:CustomXmlPropertyCollection.Remove(String) + //ExFor:CustomXmlPropertyCollection.RemoveAt(Int32) + //ExSummary:Shows how to work with smart tag properties to get in depth information about smart tags. + Document doc = new Document(getMyDir() + "Smart tags.doc"); + + // A smart tag appears in a document with Microsoft Word recognizes a part of its text as some form of data, + // such as a name, date, or address, and converts it to a hyperlink that displays a purple dotted underline. + // In Word 2003, we can enable smart tags via "Tools" -> "AutoCorrect options..." -> "SmartTags". + // In our input document, there are three objects that Microsoft Word registered as smart tags. + // Smart tags may be nested, so this collection contains more. + List smartTags = Arrays.stream(doc.getChildNodes(NodeType.SMART_TAG, true).toArray()) + .filter(SmartTag.class::isInstance) + .map(SmartTag.class::cast) + .collect(Collectors.toList()); + + Assert.assertEquals(8, smartTags.size()); + + // The "Properties" member of a smart tag contains its metadata, which will be different for each type of smart tag. + // The properties of a "date"-type smart tag contain its year, month, and day. + CustomXmlPropertyCollection properties = smartTags.get(7).getProperties(); + + Assert.assertEquals(4, properties.getCount()); + + Iterator enumerator = properties.iterator(); + + while (enumerator.hasNext()) { + CustomXmlProperty customXmlProperty = enumerator.next(); + + System.out.println(MessageFormat.format("Property name: {0}, value: {1}", customXmlProperty.getName(), customXmlProperty.getValue())); + Assert.assertEquals("", enumerator.next().getUri()); + } + + // We can also access the properties in various ways, such as a key-value pair. + Assert.assertTrue(properties.contains("Day")); + Assert.assertEquals("22", properties.get("Day").getValue()); + Assert.assertEquals("2003", properties.get(2).getValue()); + Assert.assertEquals(1, properties.indexOfKey("Month")); + + // Below are three ways of removing elements from the properties collection. + // 1 - Remove by index: + properties.removeAt(3); + + Assert.assertEquals(3, properties.getCount()); + + // 2 - Remove by name: + properties.remove("Year"); + + Assert.assertEquals(2, properties.getCount()); + + // 3 - Clear the entire collection at once: + properties.clear(); + + Assert.assertEquals(0, properties.getCount()); + //ExEnd + } +} + diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExStructuredDocumentTag.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExStructuredDocumentTag.java new file mode 100644 index 00000000..6b76171a --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExStructuredDocumentTag.java @@ -0,0 +1,1323 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.pdf.TextAbsorber; +import com.aspose.words.*; +import com.aspose.words.ref.Ref; +import org.apache.commons.collections4.IterableUtils; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.awt.*; +import java.text.MessageFormat; +import java.util.List; +import java.util.*; +import java.util.stream.Collectors; + +@Test +public class ExStructuredDocumentTag extends ApiExampleBase { + @Test + public void repeatingSection() throws Exception { + //ExStart + //ExFor:StructuredDocumentTag.SdtType + //ExSummary:Shows how to get the type of a structured document tag. + Document doc = new Document(getMyDir() + "Structured document tags.docx"); + + List tags = Arrays.stream(doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG, true).toArray()) + .filter(StructuredDocumentTag.class::isInstance) + .map(StructuredDocumentTag.class::cast) + .collect(Collectors.toList()); + + Assert.assertEquals(SdtType.REPEATING_SECTION, tags.get(0).getSdtType()); + Assert.assertEquals(SdtType.REPEATING_SECTION_ITEM, tags.get(1).getSdtType()); + Assert.assertEquals(SdtType.RICH_TEXT, tags.get(2).getSdtType()); + //ExEnd + } + + @Test + public void flatOpcContent() throws Exception + { + //ExStart + //ExFor:StructuredDocumentTag.WordOpenXML + //ExFor:IStructuredDocumentTag.WordOpenXML + //ExSummary:Shows how to get XML contained within the node in the FlatOpc format. + Document doc = new Document(getMyDir() + "Structured document tags.docx"); + + List tags = Arrays.stream(doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG, true).toArray()) + .filter(StructuredDocumentTag.class::isInstance) + .map(StructuredDocumentTag.class::cast) + .collect(Collectors.toList()); + + Assert.assertTrue(tags.get(0).getWordOpenXML() + .contains( + "")); + //ExEnd + } + + @Test + public void applyStyle() throws Exception { + //ExStart + //ExFor:StructuredDocumentTag + //ExFor:StructuredDocumentTag.NodeType + //ExFor:StructuredDocumentTag.Style + //ExFor:StructuredDocumentTag.StyleName + //ExFor:StructuredDocumentTag.WordOpenXMLMinimal + //ExFor:MarkupLevel + //ExFor:SdtType + //ExSummary:Shows how to work with styles for content control elements. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are two ways to apply a style from the document to a structured document tag. + // 1 - Apply a style object from the document's style collection: + Style quoteStyle = doc.getStyles().getByStyleIdentifier(StyleIdentifier.QUOTE); + StructuredDocumentTag sdtPlainText = new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.INLINE); + sdtPlainText.setStyle(quoteStyle); + + // 2 - Reference a style in the document by name: + StructuredDocumentTag sdtRichText = new StructuredDocumentTag(doc, SdtType.RICH_TEXT, MarkupLevel.INLINE); + sdtRichText.setStyleName("Quote"); + + builder.insertNode(sdtPlainText); + builder.insertNode(sdtRichText); + + Assert.assertEquals(NodeType.STRUCTURED_DOCUMENT_TAG, sdtPlainText.getNodeType()); + + NodeCollection tags = doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG, true); + + for (StructuredDocumentTag sdt : (Iterable) tags) { + Assert.assertEquals(StyleIdentifier.QUOTE, sdt.getStyle().getStyleIdentifier()); + Assert.assertEquals("Quote", sdt.getStyleName()); + } + //ExEnd + } + + @Test + public void checkBox() throws Exception { + //ExStart + //ExFor:StructuredDocumentTag.#ctor(DocumentBase, SdtType, MarkupLevel) + //ExFor:StructuredDocumentTag.Checked + //ExFor:StructuredDocumentTag.SetCheckedSymbol(Int32, String) + //ExFor:StructuredDocumentTag.SetUncheckedSymbol(Int32, String) + //ExSummary:Show how to create a structured document tag in the form of a check box. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + StructuredDocumentTag sdtCheckBox = new StructuredDocumentTag(doc, SdtType.CHECKBOX, MarkupLevel.INLINE); + sdtCheckBox.setChecked(true); + sdtCheckBox.setCheckedSymbol(0x00A9, "Times New Roman"); + sdtCheckBox.setUncheckedSymbol(0x00AE, "Times New Roman"); + + builder.insertNode(sdtCheckBox); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.CheckBox.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "StructuredDocumentTag.CheckBox.docx"); + + NodeCollection sdts = doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG, true); + + StructuredDocumentTag sdt = (StructuredDocumentTag) sdts.get(0); + Assert.assertEquals(true, sdt.getChecked()); + Assert.assertEquals("", sdt.getXmlMapping().getStoreItemId()); + } + + @Test + public void date() throws Exception { + //ExStart + //ExFor:StructuredDocumentTag.CalendarType + //ExFor:StructuredDocumentTag.DateDisplayFormat + //ExFor:StructuredDocumentTag.DateDisplayLocale + //ExFor:StructuredDocumentTag.DateStorageFormat + //ExFor:StructuredDocumentTag.FullDate + //ExFor:SdtCalendarType + //ExFor:SdtDateStorageFormat + //ExSummary:Shows how to prompt the user to enter a date with a structured document tag. + Document doc = new Document(); + + // Insert a structured document tag that prompts the user to enter a date. + // In Microsoft Word, this element is known as a "Date picker content control". + // When we click on the arrow on the right end of this tag in Microsoft Word, + // we will see a pop up in the form of a clickable calendar. + // We can use that popup to select a date that the tag will display. + StructuredDocumentTag sdtDate = new StructuredDocumentTag(doc, SdtType.DATE, MarkupLevel.INLINE); + + // Display the date, according to the Saudi Arabian Arabic locale. + sdtDate.setDateDisplayLocale(1025); + + // Set the format with which to display the date. + sdtDate.setDateDisplayFormat("dd MMMM, yyyy"); + sdtDate.setDateStorageFormat(SdtDateStorageFormat.DATE_TIME); + + // Display the date according to the Hijri calendar. + sdtDate.setCalendarType(SdtCalendarType.HIJRI); + + // Before the user chooses a date in Microsoft Word, the tag will display the text "Click here to enter a date.". + // According to the tag's calendar, set the "FullDate" property to get the tag to display a default date. + Calendar cal = Calendar.getInstance(); + cal.set(1440, 10, 20); + sdtDate.setFullDate(cal.getTime()); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertNode(sdtDate); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.Date.docx"); + //ExEnd + } + + @Test + public void plainText() throws Exception { + //ExStart + //ExFor:StructuredDocumentTag.Color + //ExFor:StructuredDocumentTag.ContentsFont + //ExFor:StructuredDocumentTag.EndCharacterFont + //ExFor:StructuredDocumentTag.Id + //ExFor:StructuredDocumentTag.Level + //ExFor:StructuredDocumentTag.Multiline + //ExFor:IStructuredDocumentTag.Tag + //ExFor:StructuredDocumentTag.Tag + //ExFor:StructuredDocumentTag.Title + //ExFor:StructuredDocumentTag.RemoveSelfOnly + //ExFor:StructuredDocumentTag.Appearance + //ExSummary:Shows how to create a structured document tag in a plain text box and modify its appearance. + Document doc = new Document(); + + // Create a structured document tag that will contain plain text. + StructuredDocumentTag tag = new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.INLINE); + + // Set the title and color of the frame that appears when you mouse over the structured document tag in Microsoft Word. + tag.setTitle("My plain text"); + tag.setColor(Color.MAGENTA); + + // Set a tag for this structured document tag, which is obtainable + // as an XML element named "tag", with the string below in its "@val" attribute. + tag.setTag("MyPlainTextSDT"); + + // Every structured document tag has a random unique ID. + Assert.assertTrue(tag.getId() > 0); + + // Set the font for the text inside the structured document tag. + tag.getContentsFont().setName("Arial"); + + // Set the font for the text at the end of the structured document tag. + // Any text that we type in the document body after moving out of the tag with arrow keys will use this font. + tag.getEndCharacterFont().setName("Arial Black"); + + // By default, this is false and pressing enter while inside a structured document tag does nothing. + // When set to true, our structured document tag can have multiple lines. + + // Set the "Multiline" property to "false" to only allow the contents + // of this structured document tag to span a single line. + // Set the "Multiline" property to "true" to allow the tag to contain multiple lines of content. + tag.setMultiline(true); + + // Set the "Appearance" property to "SdtAppearance.Tags" to show tags around content. + // By default structured document tag shows as BoundingBox. + tag.setAppearance(SdtAppearance.TAGS); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertNode(tag); + + // Insert a clone of our structured document tag in a new paragraph. + StructuredDocumentTag tagClone = (StructuredDocumentTag) tag.deepClone(true); + builder.insertParagraph(); + builder.insertNode(tagClone); + + // Use the "RemoveSelfOnly" method to remove a structured document tag, while keeping its contents in the document. + tagClone.removeSelfOnly(); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.PlainText.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "StructuredDocumentTag.PlainText.docx"); + tag = (StructuredDocumentTag) doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + + Assert.assertEquals("My plain text", tag.getTitle()); + Assert.assertEquals(Color.MAGENTA.getRGB(), tag.getColor().getRGB()); + Assert.assertEquals("MyPlainTextSDT", tag.getTag()); + Assert.assertEquals("Arial", tag.getContentsFont().getName()); + Assert.assertEquals("Arial Black", tag.getEndCharacterFont().getName()); + Assert.assertTrue(tag.getMultiline()); + Assert.assertEquals(SdtAppearance.TAGS, tag.getAppearance()); + } + + @Test(dataProvider = "isTemporaryDataProvider") + public void isTemporary(boolean isTemporary) throws Exception { + //ExStart + //ExFor:StructuredDocumentTag.IsTemporary + //ExSummary:Shows how to make single-use controls. + Document doc = new Document(); + + // Insert a plain text structured document tag, + // which will act as a plain text form that the user may enter text into. + StructuredDocumentTag tag = new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.INLINE); + + // Set the "IsTemporary" property to "true" to make the structured document tag disappear and + // assimilate its contents into the document after the user edits it once in Microsoft Word. + // Set the "IsTemporary" property to "false" to allow the user to edit the contents + // of the structured document tag any number of times. + tag.isTemporary(isTemporary); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.write("Please enter text: "); + builder.insertNode(tag); + + // Insert another structured document tag in the form of a check box and set its default state to "checked". + tag = new StructuredDocumentTag(doc, SdtType.CHECKBOX, MarkupLevel.INLINE); + tag.setChecked(true); + + // Set the "IsTemporary" property to "true" to make the check box become a symbol + // once the user clicks on it in Microsoft Word. + // Set the "IsTemporary" property to "false" to allow the user to click on the check box any number of times. + tag.isTemporary(isTemporary); + + builder.write("\nPlease click the check box: "); + builder.insertNode(tag); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.IsTemporary.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "StructuredDocumentTag.IsTemporary.docx"); + + List stdTagsList = Arrays.stream(doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG, true).toArray()) + .filter(StructuredDocumentTag.class::isInstance) + .map(StructuredDocumentTag.class::cast) + .collect(Collectors.toList()); + + Assert.assertEquals(2, IterableUtils.countMatches(stdTagsList, s -> s.isTemporary() == isTemporary)); + } + + @DataProvider(name = "isTemporaryDataProvider") + public static Object[][] isTemporaryDataProvider() { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test(dataProvider = "placeholderBuildingBlockDataProvider") + public void placeholderBuildingBlock(boolean isShowingPlaceholderText) throws Exception { + //ExStart + //ExFor:StructuredDocumentTag.IsShowingPlaceholderText + //ExFor:IStructuredDocumentTag.IsShowingPlaceholderText + //ExFor:StructuredDocumentTag.Placeholder + //ExFor:StructuredDocumentTag.PlaceholderName + //ExFor:IStructuredDocumentTag.Placeholder + //ExFor:IStructuredDocumentTag.PlaceholderName + //ExSummary:Shows how to use a building block's contents as a custom placeholder text for a structured document tag. + Document doc = new Document(); + + // Insert a plain text structured document tag of the "PlainText" type, which will function as a text box. + // The contents that it will display by default are a "Click here to enter text." prompt. + StructuredDocumentTag tag = new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.INLINE); + + // We can get the tag to display the contents of a building block instead of the default text. + // First, add a building block with contents to the glossary document. + GlossaryDocument glossaryDoc = doc.getGlossaryDocument(); + + BuildingBlock substituteBlock = new BuildingBlock(glossaryDoc); + substituteBlock.setName("Custom Placeholder"); + substituteBlock.appendChild(new Section(glossaryDoc)); + substituteBlock.getFirstSection().appendChild(new Body(glossaryDoc)); + substituteBlock.getFirstSection().getBody().appendParagraph("Custom placeholder text."); + + glossaryDoc.appendChild(substituteBlock); + + // Then, use the structured document tag's "PlaceholderName" property to reference that building block by name. + tag.setPlaceholderName("Custom Placeholder"); + + // If "PlaceholderName" refers to an existing block in the parent document's glossary document, + // we will be able to verify the building block via the "Placeholder" property. + Assert.assertEquals(substituteBlock, tag.getPlaceholder()); + + // Set the "IsShowingPlaceholderText" property to "true" to treat the + // structured document tag's current contents as placeholder text. + // This means that clicking on the text box in Microsoft Word will immediately highlight all the tag's contents. + // Set the "IsShowingPlaceholderText" property to "false" to get the + // structured document tag to treat its contents as text that a user has already entered. + // Clicking on this text in Microsoft Word will place the blinking cursor at the clicked location. + tag.isShowingPlaceholderText(isShowingPlaceholderText); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertNode(tag); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.PlaceholderBuildingBlock.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "StructuredDocumentTag.PlaceholderBuildingBlock.docx"); + tag = (StructuredDocumentTag) doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + substituteBlock = (BuildingBlock) doc.getGlossaryDocument().getChild(NodeType.BUILDING_BLOCK, 0, true); + + Assert.assertEquals("Custom Placeholder", substituteBlock.getName()); + Assert.assertEquals(isShowingPlaceholderText, tag.isShowingPlaceholderText()); + Assert.assertEquals(substituteBlock, tag.getPlaceholder()); + Assert.assertEquals(substituteBlock.getName(), tag.getPlaceholderName()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "placeholderBuildingBlockDataProvider") + public static Object[][] placeholderBuildingBlockDataProvider() throws Exception { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void lock() throws Exception { + //ExStart + //ExFor:StructuredDocumentTag.LockContentControl + //ExFor:StructuredDocumentTag.LockContents + //ExFor:IStructuredDocumentTag.LockContentControl + //ExFor:IStructuredDocumentTag.LockContents + //ExSummary:Shows how to apply editing restrictions to structured document tags. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a plain text structured document tag, which acts as a text box that prompts the user to fill it in. + StructuredDocumentTag tag = new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.INLINE); + + // Set the "LockContents" property to "true" to prohibit the user from editing this text box's contents. + tag.setLockContents(true); + builder.write("The contents of this structured document tag cannot be edited: "); + builder.insertNode(tag); + + tag = new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.INLINE); + + // Set the "LockContentControl" property to "true" to prohibit the user from + // deleting this structured document tag manually in Microsoft Word. + tag.setLockContentControl(true); + + builder.insertParagraph(); + builder.write("This structured document tag cannot be deleted but its contents can be edited: "); + builder.insertNode(tag); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.Lock.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "StructuredDocumentTag.Lock.docx"); + tag = (StructuredDocumentTag) doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + + Assert.assertTrue(tag.getLockContents()); + Assert.assertFalse(tag.getLockContentControl()); + + tag = (StructuredDocumentTag) doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 1, true); + + Assert.assertFalse(tag.getLockContents()); + Assert.assertTrue(tag.getLockContentControl()); + } + + @Test + public void listItemCollection() throws Exception { + //ExStart + //ExFor:SdtListItem + //ExFor:SdtListItem.#ctor(String) + //ExFor:SdtListItem.#ctor(String,String) + //ExFor:SdtListItem.DisplayText + //ExFor:SdtListItem.Value + //ExFor:SdtListItemCollection + //ExFor:SdtListItemCollection.Add(SdtListItem) + //ExFor:SdtListItemCollection.Clear + //ExFor:SdtListItemCollection.Count + //ExFor:SdtListItemCollection.GetEnumerator + //ExFor:SdtListItemCollection.Item(Int32) + //ExFor:SdtListItemCollection.RemoveAt(Int32) + //ExFor:SdtListItemCollection.SelectedValue + //ExFor:StructuredDocumentTag.ListItems + //ExSummary:Shows how to work with drop down-list structured document tags. + Document doc = new Document(); + StructuredDocumentTag tag = new StructuredDocumentTag(doc, SdtType.DROP_DOWN_LIST, MarkupLevel.BLOCK); + doc.getFirstSection().getBody().appendChild(tag); + + // A drop-down list structured document tag is a form that allows the user to + // select an option from a list by left-clicking and opening the form in Microsoft Word. + // The "ListItems" property contains all list items, and each list item is an "SdtListItem". + SdtListItemCollection listItems = tag.getListItems(); + listItems.add(new SdtListItem("Value 1")); + + Assert.assertEquals(listItems.get(0).getDisplayText(), listItems.get(0).getValue()); + + // Add 3 more list items. Initialize these items using a different constructor to the first item + // to display strings that are different from their values. + listItems.add(new SdtListItem("Item 2", "Value 2")); + listItems.add(new SdtListItem("Item 3", "Value 3")); + listItems.add(new SdtListItem("Item 4", "Value 4")); + + Assert.assertEquals(4, listItems.getCount()); + + // The drop-down list is displaying the first item. Assign a different list item to the "SelectedValue" to display it. + listItems.setSelectedValue(listItems.get(3)); + + Assert.assertEquals(listItems.getSelectedValue().getValue(), "Value 4"); + + // Enumerate over the collection and print each element. + Iterator enumerator = listItems.iterator(); + while (enumerator.hasNext()) { + SdtListItem sdtListItem = enumerator.next(); + System.out.println(MessageFormat.format("List item: {0}, value: {1}", sdtListItem.getDisplayText(), sdtListItem.getValue())); + } + + // Remove the last list item. + listItems.removeAt(3); + + Assert.assertEquals(3, listItems.getCount()); + + // Since our drop-down control is set to display the removed item by default, give it an item to display which exists. + listItems.setSelectedValue(listItems.get(1)); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.ListItemCollection.docx"); + + // Use the "Clear" method to empty the entire drop-down item collection at once. + listItems.clear(); + + Assert.assertEquals(0, listItems.getCount()); + //ExEnd + } + + @Test + public void creatingCustomXml() throws Exception { + //ExStart + //ExFor:CustomXmlPart + //ExFor:CustomXmlPart.Clone + //ExFor:CustomXmlPart.Data + //ExFor:CustomXmlPart.Id + //ExFor:CustomXmlPart.Schemas + //ExFor:CustomXmlPartCollection + //ExFor:CustomXmlPartCollection.Add(CustomXmlPart) + //ExFor:CustomXmlPartCollection.Add(String, String) + //ExFor:CustomXmlPartCollection.Clear + //ExFor:CustomXmlPartCollection.Clone + //ExFor:CustomXmlPartCollection.Count + //ExFor:CustomXmlPartCollection.GetById(String) + //ExFor:CustomXmlPartCollection.GetEnumerator + //ExFor:CustomXmlPartCollection.Item(Int32) + //ExFor:CustomXmlPartCollection.RemoveAt(Int32) + //ExFor:Document.CustomXmlParts + //ExFor:StructuredDocumentTag.XmlMapping + //ExFor:IStructuredDocumentTag.XmlMapping + //ExFor:XmlMapping.SetMapping(CustomXmlPart, String, String) + //ExSummary:Shows how to create a structured document tag with custom XML data. + Document doc = new Document(); + + // Construct an XML part that contains data and add it to the document's collection. + // If we enable the "Developer" tab in Microsoft Word, + // we can find elements from this collection in the "XML Mapping Pane", along with a few default elements. + String xmlPartId = UUID.randomUUID().toString(); + String xmlPartContent = "Hello, World!"; + CustomXmlPart xmlPart = doc.getCustomXmlParts().add(xmlPartId, xmlPartContent); + + Assert.assertEquals(xmlPart.getData(), xmlPartContent.getBytes()); + Assert.assertEquals(xmlPart.getId(), xmlPartId); + + // Below are two ways to refer to XML parts. + // 1 - By an index in the custom XML part collection: + Assert.assertEquals(xmlPart, doc.getCustomXmlParts().get(0)); + + // 2 - By GUID: + Assert.assertEquals(xmlPart, doc.getCustomXmlParts().getById(xmlPartId)); + + // Add an XML schema association. + xmlPart.getSchemas().add("http://www.w3.org/2001/XMLSchema"); + + // Clone a part, and then insert it into the collection. + CustomXmlPart xmlPartClone = xmlPart.deepClone(); + xmlPartClone.setId(UUID.randomUUID().toString()); + doc.getCustomXmlParts().add(xmlPartClone); + + Assert.assertEquals(doc.getCustomXmlParts().getCount(), 2); + + // Iterate through the collection and print the contents of each part. + Iterator enumerator = doc.getCustomXmlParts().iterator(); + int index = 0; + while (enumerator.hasNext()) { + CustomXmlPart customXmlPart = enumerator.next(); + System.out.println(MessageFormat.format("XML part index {0}, ID: {1}", index, customXmlPart.getId())); + System.out.println(MessageFormat.format("\tContent: {0}", customXmlPart.getData())); + index++; + } + + // Use the "RemoveAt" method to remove the cloned part by index. + doc.getCustomXmlParts().removeAt(1); + + Assert.assertEquals(doc.getCustomXmlParts().getCount(), 1); + + // Clone the XML parts collection, and then use the "Clear" method to remove all its elements at once. + CustomXmlPartCollection customXmlParts = doc.getCustomXmlParts().deepClone(); + customXmlParts.clear(); + + // Create a structured document tag that will display our part's contents and insert it into the document body. + StructuredDocumentTag tag = new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.BLOCK); + tag.getXmlMapping().setMapping(xmlPart, "/root[1]/text[1]", ""); + + doc.getFirstSection().getBody().appendChild(tag); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.CustomXml.docx"); + //ExEnd + } + + @Test + public void dataChecksum() throws Exception + { + //ExStart + //ExFor:CustomXmlPart.DataChecksum + //ExSummary:Shows how the checksum is calculated in a runtime. + Document doc = new Document(); + + StructuredDocumentTag richText = new StructuredDocumentTag(doc, SdtType.RICH_TEXT, MarkupLevel.BLOCK); + doc.getFirstSection().getBody().appendChild(richText); + + // The checksum is read-only and computed using the data of the corresponding custom XML data part. + richText.getXmlMapping().setMapping(doc.getCustomXmlParts().add(UUID.randomUUID().toString(), + "ContentControl"), "/root/text", ""); + + long checksum = richText.getXmlMapping().getCustomXmlPart().getDataChecksum(); + System.out.println(checksum); + + richText.getXmlMapping().setMapping(doc.getCustomXmlParts().add(UUID.randomUUID().toString(), + "Updated ContentControl"), "/root/text", ""); + + long updatedChecksum = richText.getXmlMapping().getCustomXmlPart().getDataChecksum(); + System.out.println(updatedChecksum); + + // We changed the XmlPart of the tag, and the checksum was updated at runtime. + Assert.assertNotEquals(checksum, updatedChecksum); + //ExEnd + } + + @Test + public void xmlMapping() throws Exception { + //ExStart + //ExFor:XmlMapping + //ExFor:XmlMapping.CustomXmlPart + //ExFor:XmlMapping.Delete + //ExFor:XmlMapping.IsMapped + //ExFor:XmlMapping.PrefixMappings + //ExFor:XmlMapping.XPath + //ExSummary:Shows how to set XML mappings for custom XML parts. + Document doc = new Document(); + + // Construct an XML part that contains text and add it to the document's CustomXmlPart collection. + String xmlPartId = UUID.randomUUID().toString(); + String xmlPartContent = "Text element #1Text element #2"; + CustomXmlPart xmlPart = doc.getCustomXmlParts().add(xmlPartId, xmlPartContent); + + // Create a structured document tag that will display the contents of our CustomXmlPart. + StructuredDocumentTag tag = new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.BLOCK); + + // Set a mapping for our structured document tag. This mapping will instruct + // our structured document tag to display a portion of the XML part's text contents that the XPath points to. + // In this case, it will be contents of the the second "" element of the first "" element: "Text element #2". + tag.getXmlMapping().setMapping(xmlPart, "/root[1]/text[2]", "xmlns:ns='http://www.w3.org/2001/XMLSchema'"); + + Assert.assertTrue(tag.getXmlMapping().isMapped()); + Assert.assertEquals(tag.getXmlMapping().getCustomXmlPart(), xmlPart); + Assert.assertEquals(tag.getXmlMapping().getXPath(), "/root[1]/text[2]"); + Assert.assertEquals(tag.getXmlMapping().getPrefixMappings(), "xmlns:ns='http://www.w3.org/2001/XMLSchema'"); + + // Add the structured document tag to the document to display the content from our custom part. + doc.getFirstSection().getBody().appendChild(tag); + doc.save(getArtifactsDir() + "StructuredDocumentTag.XmlMapping.docx"); + //ExEnd + } + + @Test + public void structuredDocumentTagRangeStartXmlMapping() throws Exception { + //ExStart + //ExFor:StructuredDocumentTagRangeStart.XmlMapping + //ExSummary:Shows how to set XML mappings for the range start of a structured document tag. + Document doc = new Document(getMyDir() + "Multi-section structured document tags.docx"); + + // Construct an XML part that contains text and add it to the document's CustomXmlPart collection. + String xmlPartId = UUID.randomUUID().toString(); + String xmlPartContent = "Text element #1Text element #2"; + CustomXmlPart xmlPart = doc.getCustomXmlParts().add(xmlPartId, xmlPartContent); + + // Create a structured document tag that will display the contents of our CustomXmlPart in the document. + StructuredDocumentTagRangeStart sdtRangeStart = (StructuredDocumentTagRangeStart) doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_START, 0, true); + + // If we set a mapping for our structured document tag, + // it will only display a portion of the CustomXmlPart that the XPath points to. + // This XPath will point to the contents second "" element of the first "" element of our CustomXmlPart. + sdtRangeStart.getXmlMapping().setMapping(xmlPart, "/root[1]/text[2]", null); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.StructuredDocumentTagRangeStartXmlMapping.docx"); + //ExEnd + } + + @Test + public void customXmlSchemaCollection() throws Exception { + //ExStart + //ExFor:CustomXmlSchemaCollection + //ExFor:CustomXmlSchemaCollection.Add(String) + //ExFor:CustomXmlSchemaCollection.Clear + //ExFor:CustomXmlSchemaCollection.Clone + //ExFor:CustomXmlSchemaCollection.Count + //ExFor:CustomXmlSchemaCollection.GetEnumerator + //ExFor:CustomXmlSchemaCollection.IndexOf(String) + //ExFor:CustomXmlSchemaCollection.Item(Int32) + //ExFor:CustomXmlSchemaCollection.Remove(String) + //ExFor:CustomXmlSchemaCollection.RemoveAt(Int32) + //ExSummary:Shows how to work with an XML schema collection. + Document doc = new Document(); + + String xmlPartId = UUID.randomUUID().toString(); + String xmlPartContent = "Hello, World!"; + CustomXmlPart xmlPart = doc.getCustomXmlParts().add(xmlPartId, xmlPartContent); + + // Add an XML schema association. + xmlPart.getSchemas().add("http://www.w3.org/2001/XMLSchema"); + + // Clone the custom XML part's XML schema association collection, + // and then add a couple of new schemas to the clone. + CustomXmlSchemaCollection schemas = xmlPart.getSchemas().deepClone(); + schemas.add("http://www.w3.org/2001/XMLSchema-instance"); + schemas.add("http://schemas.microsoft.com/office/2006/metadata/contentType"); + + Assert.assertEquals(3, schemas.getCount()); + Assert.assertEquals(2, schemas.indexOf("http://schemas.microsoft.com/office/2006/metadata/contentType")); + + // Enumerate the schemas and print each element. + Iterator enumerator = schemas.iterator(); + while (enumerator.hasNext()) { + System.out.println(enumerator.next()); + } + + // Below are three ways of removing schemas from the collection. + // 1 - Remove a schema by index: + schemas.removeAt(2); + + // 2 - Remove a schema by value: + schemas.remove("http://www.w3.org/2001/XMLSchema"); + + // 3 - Use the "Clear" method to empty the collection at once. + schemas.clear(); + + Assert.assertEquals(schemas.getCount(), 0); + //ExEnd + } + + @Test + public void customXmlPartStoreItemIdReadOnly() throws Exception { + //ExStart + //ExFor:XmlMapping.StoreItemId + //ExSummary:Shows how to get the custom XML data identifier of an XML part. + Document doc = new Document(getMyDir() + "Custom XML part in structured document tag.docx"); + + // Structured document tags have IDs in the form of GUIDs. + StructuredDocumentTag tag = (StructuredDocumentTag) doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + + Assert.assertEquals("{F3029283-4FF8-4DD2-9F31-395F19ACEE85}", tag.getXmlMapping().getStoreItemId()); + //ExEnd + } + + @Test + public void customXmlPartStoreItemIdReadOnlyNull() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + StructuredDocumentTag sdtCheckBox = + new StructuredDocumentTag(doc, SdtType.CHECKBOX, MarkupLevel.INLINE); + { + sdtCheckBox.setChecked(true); + } + + builder.insertNode(sdtCheckBox); + + doc = DocumentHelper.saveOpen(doc); + + StructuredDocumentTag sdt = (StructuredDocumentTag) doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + System.out.println("The Id of your custom xml part is: " + sdt.getXmlMapping().getStoreItemId()); + } + + @Test + public void clearTextFromStructuredDocumentTags() throws Exception { + //ExStart + //ExFor:StructuredDocumentTag.Clear + //ExSummary:Shows how to delete contents of structured document tag elements. + Document doc = new Document(); + + // Create a plain text structured document tag, and then append it to the document. + StructuredDocumentTag tag = new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.BLOCK); + doc.getFirstSection().getBody().appendChild(tag); + + // This structured document tag, which is in the form of a text box, already displays placeholder text. + Assert.assertEquals("Click here to enter text.", tag.getText().trim()); + Assert.assertTrue(tag.isShowingPlaceholderText()); + + // Create a building block with text contents. + GlossaryDocument glossaryDoc = doc.getGlossaryDocument(); + BuildingBlock substituteBlock = new BuildingBlock(glossaryDoc); + substituteBlock.setName("My placeholder"); + substituteBlock.appendChild(new Section(glossaryDoc)); + substituteBlock.getFirstSection().ensureMinimum(); + substituteBlock.getFirstSection().getBody().getFirstParagraph().appendChild(new Run(glossaryDoc, "Custom placeholder text.")); + glossaryDoc.appendChild(substituteBlock); + + // Set the structured document tag's "PlaceholderName" property to our building block's name to get + // the structured document tag to display the contents of the building block in place of the original default text. + tag.setPlaceholderName("My placeholder"); + + Assert.assertEquals("Custom placeholder text.", tag.getText().trim()); + Assert.assertTrue(tag.isShowingPlaceholderText()); + + // Edit the text of the structured document tag and hide the placeholder text. + Run run = (Run) tag.getChild(NodeType.RUN, 0, true); + run.setText("New text."); + tag.isShowingPlaceholderText(false); + + Assert.assertEquals("New text.", tag.getText().trim()); + + // Use the "Clear" method to clear this structured document tag's contents and display the placeholder again. + tag.clear(); + + Assert.assertTrue(tag.isShowingPlaceholderText()); + Assert.assertEquals("Custom placeholder text.", tag.getText().trim()); + //ExEnd + } + + @Test + public void accessToBuildingBlockPropertiesFromDocPartObjSdt() throws Exception { + Document doc = new Document(getMyDir() + "Structured document tags with building blocks.docx"); + + StructuredDocumentTag docPartObjSdt = + (StructuredDocumentTag) doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + + Assert.assertEquals(docPartObjSdt.getSdtType(), SdtType.DOC_PART_OBJ); + Assert.assertEquals(docPartObjSdt.getBuildingBlockGallery(), "Table of Contents"); + } + + @Test + public void accessToBuildingBlockPropertiesFromPlainTextSdt() throws Exception { + Document doc = new Document(getMyDir() + "Structured document tags with building blocks.docx"); + + StructuredDocumentTag plainTextSdt = + (StructuredDocumentTag) doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 1, true); + + Assert.assertEquals(SdtType.PLAIN_TEXT, plainTextSdt.getSdtType()); + Assert.assertThrows(IllegalStateException.class, () -> plainTextSdt.getBuildingBlockGallery()); + } + + @Test + public void buildingBlockCategories() throws Exception { + //ExStart + //ExFor:StructuredDocumentTag.BuildingBlockCategory + //ExFor:StructuredDocumentTag.BuildingBlockGallery + //ExSummary:Shows how to insert a structured document tag as a building block, and set its category and gallery. + Document doc = new Document(); + + StructuredDocumentTag buildingBlockSdt = + new StructuredDocumentTag(doc, SdtType.BUILDING_BLOCK_GALLERY, MarkupLevel.BLOCK); + buildingBlockSdt.setBuildingBlockCategory("Built-in"); + buildingBlockSdt.setBuildingBlockGallery("Table of Contents"); + + doc.getFirstSection().getBody().appendChild(buildingBlockSdt); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.BuildingBlockCategories.docx"); + //ExEnd + + buildingBlockSdt = + (StructuredDocumentTag) doc.getFirstSection().getBody().getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + + Assert.assertEquals(SdtType.BUILDING_BLOCK_GALLERY, buildingBlockSdt.getSdtType()); + Assert.assertEquals("Table of Contents", buildingBlockSdt.getBuildingBlockGallery()); + Assert.assertEquals("Built-in", buildingBlockSdt.getBuildingBlockCategory()); + } + + @Test + public void updateSdtContent() throws Exception { + Document doc = new Document(); + + // Insert a drop-down list structured document tag. + StructuredDocumentTag tag = new StructuredDocumentTag(doc, SdtType.DROP_DOWN_LIST, MarkupLevel.BLOCK); + tag.getListItems().add(new SdtListItem("Value 1")); + tag.getListItems().add(new SdtListItem("Value 2")); + tag.getListItems().add(new SdtListItem("Value 3")); + + // The drop-down list currently displays "Choose an item" as the default text. + // Set the "SelectedValue" property to one of the list items to get the tag to + // display that list item's value instead of the default text. + tag.getListItems().setSelectedValue(tag.getListItems().get(1)); + + doc.getFirstSection().getBody().appendChild(tag); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.UpdateSdtContent.pdf"); + + com.aspose.pdf.Document pdfDoc = new com.aspose.pdf.Document(getArtifactsDir() + "StructuredDocumentTag.UpdateSdtContent.pdf"); + TextAbsorber textAbsorber = new TextAbsorber(); + textAbsorber.visit(pdfDoc); + + Assert.assertEquals("Value 2", textAbsorber.getText()); + + pdfDoc.close(); + } + + @Test + public void fillTableUsingRepeatingSectionItem() throws Exception { + //ExStart + //ExFor:SdtType + //ExSummary:Shows how to fill a table with data from in an XML part. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + CustomXmlPart xmlPart = doc.getCustomXmlParts().add("Books", + "" + + "" + + "Everyday Italian" + + "Giada De Laurentiis" + + "" + + "" + + "The C Programming Language" + + "Brian W. Kernighan, Dennis M. Ritchie" + + "" + + "" + + "Learning XML" + + "Erik T. Ray" + + "" + + ""); + + // Create headers for data from the XML content. + Table table = builder.startTable(); + builder.insertCell(); + builder.write("Title"); + builder.insertCell(); + builder.write("Author"); + builder.endRow(); + builder.endTable(); + + // Create a table with a repeating section inside. + StructuredDocumentTag repeatingSectionSdt = + new StructuredDocumentTag(doc, SdtType.REPEATING_SECTION, MarkupLevel.ROW); + repeatingSectionSdt.getXmlMapping().setMapping(xmlPart, "/books[1]/book", ""); + table.appendChild(repeatingSectionSdt); + + // Add repeating section item inside the repeating section and mark it as a row. + // This table will have a row for each element that we can find in the XML document + // using the "/books[1]/book" XPath, of which there are three. + StructuredDocumentTag repeatingSectionItemSdt = + new StructuredDocumentTag(doc, SdtType.REPEATING_SECTION_ITEM, MarkupLevel.ROW); + repeatingSectionSdt.appendChild(repeatingSectionItemSdt); + + Row row = new Row(doc); + repeatingSectionItemSdt.appendChild(row); + + // Map XML data with created table cells for the title and author of each book. + StructuredDocumentTag titleSdt = + new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.CELL); + titleSdt.getXmlMapping().setMapping(xmlPart, "/books[1]/book[1]/title[1]", ""); + row.appendChild(titleSdt); + + StructuredDocumentTag authorSdt = + new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.CELL); + authorSdt.getXmlMapping().setMapping(xmlPart, "/books[1]/book[1]/author[1]", ""); + row.appendChild(authorSdt); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.RepeatingSectionItem.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "StructuredDocumentTag.RepeatingSectionItem.docx"); + List stdTagsList = Arrays.stream(doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG, true).toArray()) + .filter(StructuredDocumentTag.class::isInstance) + .map(StructuredDocumentTag.class::cast) + .collect(Collectors.toList()); + + Assert.assertEquals("/books[1]/book", stdTagsList.get(0).getXmlMapping().getXPath()); + Assert.assertEquals("", stdTagsList.get(0).getXmlMapping().getPrefixMappings()); + + Assert.assertEquals("", stdTagsList.get(1).getXmlMapping().getXPath()); + Assert.assertEquals("", stdTagsList.get(1).getXmlMapping().getPrefixMappings()); + + Assert.assertEquals("/books[1]/book[1]/title[1]", stdTagsList.get(2).getXmlMapping().getXPath()); + Assert.assertEquals("", stdTagsList.get(2).getXmlMapping().getPrefixMappings()); + + Assert.assertEquals("/books[1]/book[1]/author[1]", stdTagsList.get(3).getXmlMapping().getXPath()); + Assert.assertEquals("", stdTagsList.get(3).getXmlMapping().getPrefixMappings()); + + Assert.assertEquals("Title\u0007Author\u0007\u0007" + + "Everyday Italian\u0007Giada De Laurentiis\u0007\u0007" + + "The C Programming Language\u0007Brian W. Kernighan, Dennis M. Ritchie\u0007\u0007" + + "Learning XML\u0007Erik T. Ray", doc.getFirstSection().getBody().getTables().get(0).getText().trim()); + } + + @Test + public void customXmlPart() throws Exception { + String xmlString = "" + + "" + + "" + + "John" + + "Doe" + + "" + + "" + + "Jane" + + "Doe" + + "" + + ""; + + Document doc = new Document(); + + // Insert the full XML document as a custom document part. + // We can find the mapping for this part in Microsoft Word via "Developer" -> "XML Mapping Pane", if it is enabled. + CustomXmlPart xmlPart = doc.getCustomXmlParts().add(UUID.randomUUID().toString(), xmlString); + + // Create a structured document tag, which will use an XPath to refer to a single element from the XML. + StructuredDocumentTag sdt = new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.BLOCK); + sdt.getXmlMapping().setMapping(xmlPart, "Company//Employee[@id='2']/FirstName", ""); + + // Add the StructuredDocumentTag to the document to display the element in the text. + doc.getFirstSection().getBody().appendChild(sdt); + } + + @Test + public void multiSectionTags() throws Exception { + //ExStart + //ExFor:StructuredDocumentTagRangeStart + //ExFor:IStructuredDocumentTag.Id + //ExFor:StructuredDocumentTagRangeStart.Id + //ExFor:StructuredDocumentTagRangeStart.Title + //ExFor:StructuredDocumentTagRangeStart.PlaceholderName + //ExFor:StructuredDocumentTagRangeStart.IsShowingPlaceholderText + //ExFor:StructuredDocumentTagRangeStart.LockContentControl + //ExFor:StructuredDocumentTagRangeStart.LockContents + //ExFor:IStructuredDocumentTag.Level + //ExFor:StructuredDocumentTagRangeStart.Level + //ExFor:StructuredDocumentTagRangeStart.RangeEnd + //ExFor:IStructuredDocumentTag.Color + //ExFor:StructuredDocumentTagRangeStart.Color + //ExFor:StructuredDocumentTagRangeStart.SdtType + //ExFor:StructuredDocumentTagRangeStart.WordOpenXML + //ExFor:StructuredDocumentTagRangeStart.Tag + //ExFor:StructuredDocumentTagRangeEnd + //ExFor:StructuredDocumentTagRangeEnd.Id + //ExSummary:Shows how to get the properties of multi-section structured document tags. + Document doc = new Document(getMyDir() + "Multi-section structured document tags.docx"); + + StructuredDocumentTagRangeStart rangeStartTag = (StructuredDocumentTagRangeStart) doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_START, true).get(0); + StructuredDocumentTagRangeEnd rangeEndTag = (StructuredDocumentTagRangeEnd) doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_END, true).get(0); + + Assert.assertEquals(rangeStartTag.getId(), rangeEndTag.getId()); //ExSkip + Assert.assertEquals(NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_START, rangeStartTag.getNodeType()); //ExSkip + Assert.assertEquals(NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_END, rangeEndTag.getNodeType()); //ExSkip + + System.out.println("StructuredDocumentTagRangeStart values:"); + System.out.println(MessageFormat.format("\t|Id: {0}", rangeStartTag.getId())); + System.out.println(MessageFormat.format("\t|Title: {0}", rangeStartTag.getTitle())); + System.out.println(MessageFormat.format("\t|PlaceholderName: {0}", rangeStartTag.getPlaceholderName())); + System.out.println(MessageFormat.format("\t|IsShowingPlaceholderText: {0}", rangeStartTag.isShowingPlaceholderText())); + System.out.println(MessageFormat.format("\t|LockContentControl: {0}", rangeStartTag.getLockContentControl())); + System.out.println(MessageFormat.format("\t|LockContents: {0}", rangeStartTag.getLockContents())); + System.out.println(MessageFormat.format("\t|Level: {0}", rangeStartTag.getLevel())); + System.out.println(MessageFormat.format("\t|NodeType: {0}", rangeStartTag.getNodeType())); + System.out.println(MessageFormat.format("\t|RangeEnd: {0}", rangeStartTag.getRangeEnd())); + System.out.println(MessageFormat.format("\t|Color: {0}", rangeStartTag.getColor())); + System.out.println(MessageFormat.format("\t|SdtType: {0}", rangeStartTag.getSdtType())); + System.out.println(MessageFormat.format("\t|FlatOpcContent: {0}", rangeStartTag.getWordOpenXML())); + System.out.println(MessageFormat.format("\t|Tag: {0}\n", rangeStartTag.getTag())); + + System.out.println("StructuredDocumentTagRangeEnd values:"); + System.out.println("\t|Id: {rangeEndTag.Id}"); + System.out.println("\t|NodeType: {rangeEndTag.NodeType}"); + //ExEnd + } + + @Test + public void sdtChildNodes() throws Exception + { + //ExStart + //ExFor:StructuredDocumentTagRangeStart.GetChildNodes(NodeType, bool) + //ExSummary:Shows how to get child nodes of StructuredDocumentTagRangeStart. + Document doc = new Document(getMyDir() + "Multi-section structured document tags.docx"); + StructuredDocumentTagRangeStart tag = (StructuredDocumentTagRangeStart) doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_START, true).get(0); + + System.out.println("StructuredDocumentTagRangeStart values:"); + System.out.println("\t|Child nodes count: {tag.ChildNodes.Count}\n"); + + for (Node node : (Iterable) tag.getChildNodes(NodeType.RUN, true)) + System.out.println(MessageFormat.format("\t|Child node text: {0}", node.getText())); + //ExEnd + } + + //ExStart + //ExFor:StructuredDocumentTagRangeStart.#ctor(DocumentBase, SdtType) + //ExFor:StructuredDocumentTagRangeEnd.#ctor(DocumentBase, int) + //ExFor:StructuredDocumentTagRangeStart.RemoveSelfOnly + //ExFor:StructuredDocumentTagRangeStart.RemoveAllChildren + //ExSummary:Shows how to create/remove structured document tag and its content. + @Test //ExSkip + public void sdtRangeExtendedMethods() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("StructuredDocumentTag element"); + + StructuredDocumentTagRangeStart rangeStart = insertStructuredDocumentTagRanges(doc); + + // Removes ranged structured document tag, but keeps content inside. + rangeStart.removeSelfOnly(); + + rangeStart = (StructuredDocumentTagRangeStart)doc.getChild( + NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_START, 0, false); + Assert.assertEquals(null, rangeStart); + + StructuredDocumentTagRangeEnd rangeEnd = (StructuredDocumentTagRangeEnd)doc.getChild( + NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_END, 0, false); + + Assert.assertEquals(null, rangeEnd); + Assert.assertEquals("StructuredDocumentTag element", doc.getText().trim()); + + rangeStart = insertStructuredDocumentTagRanges(doc); + + Node paragraphNode = rangeStart.getLastChild(); + if (paragraphNode != null) + Assert.assertEquals("StructuredDocumentTag element", paragraphNode.getText().trim()); + + // Removes ranged structured document tag and content inside. + rangeStart.removeAllChildren(); + + paragraphNode = rangeStart.getLastChild(); + Assert.assertEquals("", paragraphNode.getText()); + } + + @Test (enabled = false) + public StructuredDocumentTagRangeStart insertStructuredDocumentTagRanges(Document doc) + { + StructuredDocumentTagRangeStart rangeStart = new StructuredDocumentTagRangeStart(doc, SdtType.PLAIN_TEXT); + StructuredDocumentTagRangeEnd rangeEnd = new StructuredDocumentTagRangeEnd(doc, rangeStart.getId()); + + doc.getFirstSection().getBody().insertBefore(rangeStart, doc.getFirstSection().getBody().getFirstParagraph()); + doc.getLastSection().getBody().insertAfter(rangeEnd, doc.getFirstSection().getBody().getFirstParagraph()); + + return rangeStart; + } + //ExEnd + + @Test + public void getSdt() throws Exception + { + //ExStart + //ExFor:Range.StructuredDocumentTags + //ExFor:StructuredDocumentTagCollection.Remove(int) + //ExFor:StructuredDocumentTagCollection.RemoveAt(int) + //ExSummary:Shows how to remove structured document tag. + Document doc = new Document(getMyDir() + "Structured document tags.docx"); + + StructuredDocumentTagCollection structuredDocumentTags = doc.getRange().getStructuredDocumentTags(); + IStructuredDocumentTag sdt; + for (int i = 0; i < structuredDocumentTags.getCount(); i++) + { + sdt = structuredDocumentTags.get(i); + System.out.println(sdt.getTitle()); + } + + sdt = structuredDocumentTags.getById(1691867797); + Assert.assertEquals(1691867797, sdt.getId()); + + Assert.assertEquals(5, structuredDocumentTags.getCount()); + // Remove the structured document tag by Id. + structuredDocumentTags.remove(1691867797); + // Remove the structured document tag at position 0. + structuredDocumentTags.removeAt(0); + Assert.assertEquals(3, structuredDocumentTags.getCount()); + //ExEnd + } + + @Test + public void rangeSdt() throws Exception + { + //ExStart + //ExFor:StructuredDocumentTagCollection + //ExFor:StructuredDocumentTagCollection.GetById(int) + //ExFor:StructuredDocumentTagCollection.GetByTitle(String) + //ExFor:IStructuredDocumentTag.IsMultiSection + //ExFor:IStructuredDocumentTag.Title + //ExSummary:Shows how to get structured document tag. + Document doc = new Document(getMyDir() + "Structured document tags by id.docx"); + + // Get the structured document tag by Id. + IStructuredDocumentTag sdt = doc.getRange().getStructuredDocumentTags().getById(1160505028); + System.out.println(sdt.isMultiSection()); + System.out.println(sdt.getTitle()); + + // Get the structured document tag or ranged tag by Title. + sdt = doc.getRange().getStructuredDocumentTags().getByTitle("Alias4"); + System.out.println(sdt.getId()); + //ExEnd + } + + @Test + public void sdtAtRowLevel() throws Exception + { + //ExStart + //ExFor:SdtType + //ExSummary:Shows how to create group structured document tag at the Row level. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + + // Create a Group structured document tag at the Row level. + StructuredDocumentTag groupSdt = new StructuredDocumentTag(doc, SdtType.GROUP, MarkupLevel.ROW); + table.appendChild(groupSdt); + groupSdt.isShowingPlaceholderText(false); + groupSdt.removeAllChildren(); + + // Create a child row of the structured document tag. + Row row = new Row(doc); + groupSdt.appendChild(row); + + Cell cell = new Cell(doc); + row.appendChild(cell); + + builder.endTable(); + + // Insert cell contents. + cell.ensureMinimum(); + builder.moveTo(cell.getLastParagraph()); + builder.write("Lorem ipsum dolor."); + + // Insert text after the table. + builder.moveTo(table.getNextSibling()); + builder.write("Nulla blandit nisi."); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.SdtAtRowLevel.docx"); + //ExEnd + } + + @Test + public void ignoreStructuredDocumentTags() throws Exception + { + //ExStart + //ExFor:FindReplaceOptions.IgnoreStructuredDocumentTags + //ExSummary:Shows how to ignore content of tags from replacement. + Document doc = new Document(getMyDir() + "Structured document tags.docx"); + + // This paragraph contains SDT. + Paragraph p = (Paragraph)doc.getFirstSection().getBody().getChild(NodeType.PARAGRAPH, 2, true); + String textToSearch = p.toString(SaveFormat.TEXT).trim(); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setIgnoreStructuredDocumentTags(true); + doc.getRange().replace(textToSearch, "replacement", options); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.IgnoreStructuredDocumentTags.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "StructuredDocumentTag.IgnoreStructuredDocumentTags.docx"); + Assert.assertEquals("This document contains Structured Document Tags with text inside them\r\rRepeatingSection\rRichText\rreplacement", doc.getText().trim()); + } + + @Test + public void citation() throws Exception + { + //ExStart + //ExFor:SdtType + //ExSummary:Shows how to create a structured document tag of the Citation type. + Document doc = new Document(); + + StructuredDocumentTag sdt = new StructuredDocumentTag(doc, SdtType.CITATION, MarkupLevel.INLINE); + Paragraph paragraph = doc.getFirstSection().getBody().getFirstParagraph(); + paragraph.appendChild(sdt); + + // Create a Citation field. + DocumentBuilder builder = new DocumentBuilder(doc); + builder.moveToParagraph(0, -1); + builder.insertField("CITATION Ath22 \\l 1033 ", "(John Lennon, 2022)"); + + // Move the field to the structured document tag. + while (sdt.getNextSibling() != null) + sdt.appendChild(sdt.getNextSibling()); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.Citation.docx"); + //ExEnd + } + + @Test + public void rangeStartWordOpenXmlMinimal() throws Exception + { + //ExStart:RangeStartWordOpenXmlMinimal + //GistId:66dd22f0854357e394a013b536e2181b + //ExFor:StructuredDocumentTagRangeStart.WordOpenXMLMinimal + //ExSummary:Shows how to get minimal XML contained within the node in the FlatOpc format. + Document doc = new Document(getMyDir() + "Multi-section structured document tags.docx"); + StructuredDocumentTagRangeStart tag = (StructuredDocumentTagRangeStart) doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_START, 0, true); + + Assert.assertTrue(tag.getWordOpenXMLMinimal() + .contains( + "")); + Assert.assertFalse(tag.getWordOpenXMLMinimal().contains("xmlns:w16cid=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\"")); + //ExEnd:RangeStartWordOpenXmlMinimal + } + + @Test + public void removeSelfOnly() throws Exception + { + //ExStart:RemoveSelfOnly + //GistId:f0964b777330b758f6b82330b040b24c + //ExFor:IStructuredDocumentTag + //ExFor:IStructuredDocumentTag.GetChildNodes(NodeType, bool) + //ExFor:IStructuredDocumentTag.RemoveSelfOnly + //ExSummary:Shows how to remove structured document tag, but keeps content inside. + Document doc = new Document(getMyDir() + "Structured document tags.docx"); + + // This collection provides a unified interface for accessing ranged and non-ranged structured tags. + StructuredDocumentTagCollection sdts = doc.getRange().getStructuredDocumentTags(); + Assert.assertEquals(5, sdts.getCount()); + + // Here we can get child nodes from the common interface of ranged and non-ranged structured tags. + for (IStructuredDocumentTag sdt : sdts) + if (sdt.getChildNodes(NodeType.ANY, false).getCount() > 0) + sdt.removeSelfOnly(); + + sdts = doc.getRange().getStructuredDocumentTags(); + Assert.assertEquals(0, sdts.getCount()); + //ExEnd:RemoveSelfOnly + } + + @Test + public void appearance() throws Exception + { + //ExStart:Appearance + //GistId:9c17d666c47318436785490829a3984f + //ExFor:SdtAppearance + //ExFor:StructuredDocumentTagRangeStart.Appearance + //ExFor:IStructuredDocumentTag.Appearance + //ExSummary:Shows how to show tag around content. + Document doc = new Document(getMyDir() + "Multi-section structured document tags.docx"); + StructuredDocumentTagRangeStart tag = (StructuredDocumentTagRangeStart) doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_START, 0, true); + + if (tag.getAppearance() == SdtAppearance.HIDDEN) + tag.setAppearance(SdtAppearance.TAGS); + //ExEnd:Appearance + } + + @Test + public void insertStructuredDocumentTag() throws Exception + { + //ExStart:InsertStructuredDocumentTag + //GistId:6280fd6c1c1854468bea095ec2af902b + //ExFor:DocumentBuilder.InsertStructuredDocumentTag(SdtType) + //ExSummary:Shows how to simply insert structured document tag. + Document doc = new Document(getMyDir() + "Rendering.docx"); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.moveTo(doc.getFirstSection().getBody().getParagraphs().get(3)); + // Note, that only following StructuredDocumentTag types are allowed for insertion: + // SdtType.PlainText, SdtType.RichText, SdtType.Checkbox, SdtType.DropDownList, + // SdtType.ComboBox, SdtType.Picture, SdtType.Date. + // Markup level of inserted StructuredDocumentTag will be detected automatically and depends on position being inserted at. + // Added StructuredDocumentTag will inherit paragraph and font formatting from cursor position. + StructuredDocumentTag sdtPlain = builder.insertStructuredDocumentTag(SdtType.PLAIN_TEXT); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.InsertStructuredDocumentTag.docx"); + //ExEnd:InsertStructuredDocumentTag + } +} \ No newline at end of file diff --git a/Examples/ApiExamples/Java/src/main/java/Examples/ExStyles.java b/Examples/ApiExamples/Java/src/main/java/Examples/ExStyles.java new file mode 100644 index 00000000..d5c2d0ad --- /dev/null +++ b/Examples/ApiExamples/Java/src/main/java/Examples/ExStyles.java @@ -0,0 +1,417 @@ +package Examples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.*; +import org.apache.commons.collections4.IterableUtils; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.awt.*; +import java.text.MessageFormat; +import java.util.Iterator; + +public class ExStyles extends ApiExampleBase { + @Test + public void styles() throws Exception { + //ExStart + //ExFor:DocumentBase.Styles + //ExFor:Style.Document + //ExFor:Style.Name + //ExFor:Style.IsHeading + //ExFor:Style.IsQuickStyle + //ExFor:Style.NextParagraphStyleName + //ExFor:Style.Styles + //ExFor:Style.Type + //ExFor:StyleCollection.Document + //ExFor:StyleCollection.GetEnumerator + //ExSummary:Shows how to access a document's style collection. + Document doc = new Document(); + + Assert.assertEquals(4, doc.getStyles().getCount()); + + // Enumerate and list all the styles that a document created using Aspose.Words contains by default. + Iterator")); + Assert.assertTrue(outDocContents.contains("

          ")); + } + else + { + Assert.assertFalse(outDocContents.contains("style type=\"text/css\">")); + Assert.assertTrue(outDocContents.contains("

          ")); + } + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "exportPageMarginsDataProvider") + public static Object[][] exportPageMarginsDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "exportPageSetupDataProvider") + public void exportPageSetup(boolean exportPageSetup) throws Exception + { + //ExStart + //ExFor:HtmlSaveOptions.ExportPageSetup + //ExSummary:Shows how decide whether to preserve section structure/page setup information when saving to HTML. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Section 1"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.write("Section 2"); + + PageSetup pageSetup = doc.getSections().get(0).getPageSetup(); + pageSetup.setTopMargin(36.0); + pageSetup.setBottomMargin(36.0); + pageSetup.setPaperSize(PaperSize.A5); + + // When saving the document to HTML, we can pass a SaveOptions object + // to decide whether to preserve or discard page setup settings. + // If we set the "ExportPageSetup" flag to "true", the output HTML document will contain our page setup configuration. + // If we set the "ExportPageSetup" flag to "false", the save operation will discard our page setup settings + // for the first section, and both sections will look identical. + HtmlSaveOptions options = new HtmlSaveOptions(); { options.setExportPageSetup(exportPageSetup); } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.ExportPageSetup.html", options); + + String outDocContents = File.readAllText(getArtifactsDir() + "HtmlSaveOptions.ExportPageSetup.html"); + + if (exportPageSetup) + { + Assert.assertTrue(outDocContents.contains( + "")); + + Assert.assertTrue(outDocContents.contains( + "

          " + + "

          " + + "Section 1" + + "

          " + + "
          ")); + } + else + { + Assert.assertFalse(outDocContents.contains("style type=\"text/css\">")); + + Assert.assertTrue(outDocContents.contains( + "
          " + + "

          " + + "Section 1" + + "

          " + + "
          ")); + } + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "exportPageSetupDataProvider") + public static Object[][] exportPageSetupDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "relativeFontSizeDataProvider") + public void relativeFontSize(boolean exportRelativeFontSize) throws Exception + { + //ExStart + //ExFor:HtmlSaveOptions.ExportRelativeFontSize + //ExSummary:Shows how to use relative font sizes when saving to .html. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Default font size, "); + builder.getFont().setSize(24.0); + builder.writeln("2x default font size,"); + builder.getFont().setSize(96.0); + builder.write("8x default font size"); + + // When we save the document to HTML, we can pass a SaveOptions object + // to determine whether to use relative or absolute font sizes. + // Set the "ExportRelativeFontSize" flag to "true" to declare font sizes + // using the "em" measurement unit, which is a factor that multiplies the current font size. + // Set the "ExportRelativeFontSize" flag to "false" to declare font sizes + // using the "pt" measurement unit, which is the font's absolute size in points. + HtmlSaveOptions options = new HtmlSaveOptions(); { options.setExportRelativeFontSize(exportRelativeFontSize); } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.RelativeFontSize.html", options); + + String outDocContents = File.readAllText(getArtifactsDir() + "HtmlSaveOptions.RelativeFontSize.html"); + + if (exportRelativeFontSize) + { + Assert.assertTrue(outDocContents.contains( + "" + + "
          " + + "

          " + + "Default font size, " + + "

          " + + "

          " + + "2x default font size," + + "

          " + + "

          " + + "8x default font size" + + "

          " + + "
          " + + "")); + } + else + { + Assert.assertTrue(outDocContents.contains( + "" + + "
          " + + "

          " + + "Default font size, " + + "

          " + + "

          " + + "2x default font size," + + "

          " + + "

          " + + "8x default font size" + + "

          " + + "
          " + + "")); + } + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "relativeFontSizeDataProvider") + public static Object[][] relativeFontSizeDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "exportShapeDataProvider") + public void exportShape(boolean exportShapesAsSvg) throws Exception + { + //ExStart + //ExFor:HtmlSaveOptions.ExportShapesAsSvg + //ExSummary:Shows how to export shape as scalable vector graphics. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape textBox = builder.insertShape(ShapeType.TEXT_BOX, 100.0, 60.0); + builder.moveTo(textBox.getFirstParagraph()); + builder.write("My text box"); + + // When we save the document to HTML, we can pass a SaveOptions object + // to determine how the saving operation will export text box shapes. + // If we set the "ExportTextBoxAsSvg" flag to "true", + // the save operation will convert shapes with text into SVG objects. + // If we set the "ExportTextBoxAsSvg" flag to "false", + // the save operation will convert shapes with text into images. + HtmlSaveOptions options = new HtmlSaveOptions(); { options.setExportShapesAsSvg(exportShapesAsSvg); } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.ExportTextBox.html", options); + + String outDocContents = File.readAllText(getArtifactsDir() + "HtmlSaveOptions.ExportTextBox.html"); + + if (exportShapesAsSvg) + { + Assert.assertTrue(outDocContents.contains( + "" + + "")); + } + else + { + Assert.assertTrue(outDocContents.contains( + "

          " + + "\"\"" + + "

          ")); + } + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "exportShapeDataProvider") + public static Object[][] exportShapeDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "roundTripInformationDataProvider") + public void roundTripInformation(boolean exportRoundtripInformation) throws Exception + { + //ExStart + //ExFor:HtmlSaveOptions.ExportRoundtripInformation + //ExSummary:Shows how to preserve hidden elements when converting to .html. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // When converting a document to .html, some elements such as hidden bookmarks, original shape positions, + // or footnotes will be either removed or converted to plain text and effectively be lost. + // Saving with a HtmlSaveOptions object with ExportRoundtripInformation set to true will preserve these elements. + + // When we save the document to HTML, we can pass a SaveOptions object to determine + // how the saving operation will export document elements that HTML does not support or use, + // such as hidden bookmarks and original shape positions. + // If we set the "ExportRoundtripInformation" flag to "true", the save operation will preserve these elements. + // If we set the "ExportRoundTripInformation" flag to "false", the save operation will discard these elements. + // We will want to preserve such elements if we intend to load the saved HTML using Aspose.Words, + // as they could be of use once again. + HtmlSaveOptions options = new HtmlSaveOptions(); { options.setExportRoundtripInformation(exportRoundtripInformation); } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.RoundTripInformation.html", options); + + String outDocContents = File.readAllText(getArtifactsDir() + "HtmlSaveOptions.RoundTripInformation.html"); + doc = new Document(getArtifactsDir() + "HtmlSaveOptions.RoundTripInformation.html"); + + if (exportRoundtripInformation) + { + Assert.assertTrue(outDocContents.contains("
          ")); + Assert.assertTrue(outDocContents.contains(" ")); + + Assert.assertTrue(outDocContents.contains( + "td colspan=\"2\" style=\"width:210.6pt; border-style:solid; border-width:0.75pt 6pt 0.75pt 0.75pt; " + + "padding-right:2.4pt; padding-left:5.03pt; vertical-align:top; " + + "-aw-border-bottom:0.5pt single; -aw-border-left:0.5pt single; -aw-border-top:0.5pt single\">")); + + Assert.assertTrue(outDocContents.contains( + "
        2. ")); + + Assert.assertTrue(outDocContents.contains( + "\"\"")); + + + Assert.assertTrue(outDocContents.contains( + "Page number " + + "" + + "" + + "" + + "1" + + "")); + + Assert.That(doc.getRange().getFields().Count(f => f.Type == FieldType.FieldPage), assertEquals(1, ); + } + else + { + Assert.assertTrue(outDocContents.contains("
          ")); + Assert.assertTrue(outDocContents.contains(" ")); + + Assert.assertTrue(outDocContents.contains( + "
        3. Heading 1")); + + Assert.assertTrue(outDocContents.contains( + "
        4. ")); + + Assert.assertTrue(outDocContents.contains( + "\"\"")); + + Assert.assertTrue(outDocContents.contains( + "Page number 1")); + + Assert.That(doc.getRange().getFields().Count(f => f.Type == FieldType.FieldPage), assertEquals(0, ); + } + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "roundTripInformationDataProvider") + public static Object[][] roundTripInformationDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "exportTocPageNumbersDataProvider") + public void exportTocPageNumbers(boolean exportTocPageNumbers) throws Exception + { + //ExStart + //ExFor:HtmlSaveOptions.ExportTocPageNumbers + //ExSummary:Shows how to display page numbers when saving a document with a table of contents to .html. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a table of contents, and then populate the document with paragraphs formatted using a "Heading" + // style that the table of contents will pick up as entries. Each entry will display the heading paragraph on the left, + // and the page number that contains the heading on the right. + FieldToc fieldToc = (FieldToc)builder.insertField(FieldType.FIELD_TOC, true); + + builder.getParagraphFormat().setStyle(builder.getDocument().getStyles().get("Heading 1")); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Entry 1"); + builder.writeln("Entry 2"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Entry 3"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Entry 4"); + fieldToc.updatePageNumbers(); + doc.updateFields(); + + // HTML documents do not have pages. If we save this document to HTML, + // the page numbers that our TOC displays will have no meaning. + // When we save the document to HTML, we can pass a SaveOptions object to omit these page numbers from the TOC. + // If we set the "ExportTocPageNumbers" flag to "true", + // each TOC entry will display the heading, separator, and page number, preserving its appearance in Microsoft Word. + // If we set the "ExportTocPageNumbers" flag to "false", + // the save operation will omit both the separator and page number and leave the heading for each entry intact. + HtmlSaveOptions options = new HtmlSaveOptions(); { options.setExportTocPageNumbers(exportTocPageNumbers); } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.ExportTocPageNumbers.html", options); + + String outDocContents = File.readAllText(getArtifactsDir() + "HtmlSaveOptions.ExportTocPageNumbers.html"); + + if (exportTocPageNumbers) + { + Assert.assertTrue(outDocContents.contains( + "Entry 1" + + "......................................................................." + + "2" + + "

          ")); + } + else + { + Assert.assertTrue(outDocContents.contains( + "

          " + + "Entry 2" + + "

          ")); + } + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "exportTocPageNumbersDataProvider") + public static Object[][] exportTocPageNumbersDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "fontSubsettingDataProvider") + public void fontSubsetting(int fontResourcesSubsettingSizeThreshold) throws Exception + { + //ExStart + //ExFor:HtmlSaveOptions.FontResourcesSubsettingSizeThreshold + //ExSummary:Shows how to work with font subsetting. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Arial"); + builder.writeln("Hello world!"); + builder.getFont().setName("Times New Roman"); + builder.writeln("Hello world!"); + builder.getFont().setName("Courier New"); + builder.writeln("Hello world!"); + + // When we save the document to HTML, we can pass a SaveOptions object configure font subsetting. + // Suppose we set the "ExportFontResources" flag to "true" and also name a folder in the "FontsFolder" property. + // In that case, the saving operation will create that folder and place a .ttf file inside + // that folder for each font that our document uses. + // Each .ttf file will contain that font's entire glyph set, + // which may potentially result in a very large file that accompanies the document. + // When we apply subsetting to a font, its exported raw data will only contain the glyphs that the document is + // using instead of the entire glyph set. If the text in our document only uses a small fraction of a font's + // glyph set, then subsetting will significantly reduce our output documents' size. + // We can use the "FontResourcesSubsettingSizeThreshold" property to define a .ttf file size, in bytes. + // If an exported font creates a size bigger file than that, then the save operation will apply subsetting to that font. + // Setting a threshold of 0 applies subsetting to all fonts, + // and setting it to "int.MaxValue" effectively disables subsetting. + String fontsFolder = getArtifactsDir() + "HtmlSaveOptions.FontSubsetting.Fonts"; + + HtmlSaveOptions options = new HtmlSaveOptions(); + { + options.setExportFontResources(true); + options.setFontsFolder(fontsFolder); + options.setFontResourcesSubsettingSizeThreshold(fontResourcesSubsettingSizeThreshold); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.FontSubsetting.html", options); + + String[] fontFileNames = Directory.getFiles(fontsFolder).Where(s => s.EndsWith(".ttf")).ToArray(); + + Assert.assertEquals(3, fontFileNames.length); + + for (String filename : fontFileNames) + { + // By default, the .ttf files for each of our three fonts will be over 700MB. + // Subsetting will reduce them all to under 30MB. + FileInfo fontFileInfo = new FileInfo(filename); + + Assert.assertTrue(fontFileInfo.getLength() > 700000 || fontFileInfo.getLength() < 30000); + Assert.assertTrue(Math.max(fontResourcesSubsettingSizeThreshold, 30000) > new FileInfo(filename).getLength()); + } + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "fontSubsettingDataProvider") + public static Object[][] fontSubsettingDataProvider() throws Exception + { + return new Object[][] + { + {0}, + {1000000}, + {Integer.MAX_VALUE}, + }; + } + + @Test (dataProvider = "metafileFormatDataProvider") + public void metafileFormat(/*HtmlMetafileFormat*/int htmlMetafileFormat) throws Exception + { + //ExStart + //ExFor:HtmlMetafileFormat + //ExFor:HtmlSaveOptions.MetafileFormat + //ExFor:HtmlLoadOptions.ConvertSvgToEmf + //ExSummary:Shows how to convert SVG objects to a different format when saving HTML documents. + String html = + "\n \n Hello world!\n \n "; + + // Use 'ConvertSvgToEmf' to turn back the legacy behavior + // where all SVG images loaded from an HTML document were converted to EMF. + // Now SVG images are loaded without conversion + // if the MS Word version specified in load options supports SVG images natively. + HtmlLoadOptions loadOptions = new HtmlLoadOptions(); { loadOptions.setConvertSvgToEmf(true); } + + Document doc = new Document(new MemoryStream(Encoding.getUTF8().getBytes(html)), loadOptions); + + // This document contains a element in the form of text. + // When we save the document to HTML, we can pass a SaveOptions object + // to determine how the saving operation handles this object. + // Setting the "MetafileFormat" property to "HtmlMetafileFormat.Png" to convert it to a PNG image. + // Setting the "MetafileFormat" property to "HtmlMetafileFormat.Svg" preserve it as a SVG object. + // Setting the "MetafileFormat" property to "HtmlMetafileFormat.EmfOrWmf" to convert it to a metafile. + HtmlSaveOptions options = new HtmlSaveOptions(); { options.setMetafileFormat(htmlMetafileFormat); } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.MetafileFormat.html", options); + + String outDocContents = File.readAllText(getArtifactsDir() + "HtmlSaveOptions.MetafileFormat.html"); + + switch (htmlMetafileFormat) + { + case HtmlMetafileFormat.PNG: + Assert.assertTrue(outDocContents.contains( + "

          " + + "\"\"" + + "

          ")); + break; + case HtmlMetafileFormat.SVG: + Assert.assertTrue(outDocContents.contains( + "" + + "")); + break; + case HtmlMetafileFormat.EMF_OR_WMF: + Assert.assertTrue(outDocContents.contains( + "

          " + + "\"\"" + + "

          ")); + break; + } + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "metafileFormatDataProvider") + public static Object[][] metafileFormatDataProvider() throws Exception + { + return new Object[][] + { + {HtmlMetafileFormat.PNG}, + {HtmlMetafileFormat.SVG}, + {HtmlMetafileFormat.EMF_OR_WMF}, + }; + } + + @Test (dataProvider = "officeMathOutputModeDataProvider") + public void officeMathOutputMode(/*HtmlOfficeMathOutputMode*/int htmlOfficeMathOutputMode) throws Exception + { + //ExStart + //ExFor:HtmlOfficeMathOutputMode + //ExFor:HtmlSaveOptions.OfficeMathOutputMode + //ExSummary:Shows how to specify how to export Microsoft OfficeMath objects to HTML. + Document doc = new Document(getMyDir() + "Office math.docx"); + + // When we save the document to HTML, we can pass a SaveOptions object + // to determine how the saving operation handles OfficeMath objects. + // Setting the "OfficeMathOutputMode" property to "HtmlOfficeMathOutputMode.Image" + // will render each OfficeMath object into an image. + // Setting the "OfficeMathOutputMode" property to "HtmlOfficeMathOutputMode.MathML" + // will convert each OfficeMath object into MathML. + // Setting the "OfficeMathOutputMode" property to "HtmlOfficeMathOutputMode.Text" + // will represent each OfficeMath formula using plain HTML text. + HtmlSaveOptions options = new HtmlSaveOptions(); { options.setOfficeMathOutputMode(htmlOfficeMathOutputMode); } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.OfficeMathOutputMode.html", options); + String outDocContents = File.readAllText(getArtifactsDir() + "HtmlSaveOptions.OfficeMathOutputMode.html"); + + switch (htmlOfficeMathOutputMode) + { + case HtmlOfficeMathOutputMode.IMAGE: + Assert.assertTrue(Regex.match(outDocContents, + "

          " + + "\"\"" + + "

          ").getSuccess()); + break; + case HtmlOfficeMathOutputMode.MATH_ML: + Assert.assertTrue(Regex.match(outDocContents, + "

          " + + "" + + "i" + + "[+]" + + "b" + + "-" + + "c" + + "" + + ".*" + + "" + + "

          ").getSuccess()); + break; + case HtmlOfficeMathOutputMode.TEXT: + Assert.assertTrue(Regex.match(outDocContents, + "

          " + + "i[+]b-c≥iM[+]bM-cM " + + "

          ").getSuccess()); + break; + } + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "officeMathOutputModeDataProvider") + public static Object[][] officeMathOutputModeDataProvider() throws Exception + { + return new Object[][] + { + {HtmlOfficeMathOutputMode.IMAGE}, + {HtmlOfficeMathOutputMode.MATH_ML}, + {HtmlOfficeMathOutputMode.TEXT}, + }; + } + + @Test (dataProvider = "scaleImageToShapeSizeDataProvider") + public void scaleImageToShapeSize(boolean scaleImageToShapeSize) throws Exception + { + //ExStart + //ExFor:HtmlSaveOptions.ScaleImageToShapeSize + //ExSummary:Shows how to disable the scaling of images to their parent shape dimensions when saving to .html. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a shape which contains an image, and then make that shape considerably smaller than the image. + Shape imageShape = builder.insertImage(getImageDir() + "Transparent background logo.png"); + imageShape.setWidth(50.0); + imageShape.setHeight(50.0); + + // Saving a document that contains shapes with images to HTML will create an image file in the local file system + // for each such shape. The output HTML document will use tags to link to and display these images. + // When we save the document to HTML, we can pass a SaveOptions object to determine + // whether to scale all images that are inside shapes to the sizes of their shapes. + // Setting the "ScaleImageToShapeSize" flag to "true" will shrink every image + // to the size of the shape that contains it, so that no saved images will be larger than the document requires them to be. + // Setting the "ScaleImageToShapeSize" flag to "false" will preserve these images' original sizes, + // which will take up more space in exchange for preserving image quality. + HtmlSaveOptions options = new HtmlSaveOptions(); { options.setScaleImageToShapeSize(scaleImageToShapeSize); } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.ScaleImageToShapeSize.html", options); + //ExEnd + + long testedImageLength = new FileInfo(getArtifactsDir() + "HtmlSaveOptions.ScaleImageToShapeSize.001.png").getLength(); + + if (scaleImageToShapeSize) + Assert.assertTrue(testedImageLength < 3000); + else + Assert.assertTrue(testedImageLength < 16000); + + } + + //JAVA-added data provider for test method + @DataProvider(name = "scaleImageToShapeSizeDataProvider") + public static Object[][] scaleImageToShapeSizeDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void imageFolder() throws Exception + { + //ExStart + //ExFor:HtmlSaveOptions + //ExFor:HtmlSaveOptions.ExportTextInputFormFieldAsText + //ExFor:HtmlSaveOptions.ImagesFolder + //ExSummary:Shows how to specify the folder for storing linked images after saving to .html. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + String imagesDir = Path.combine(getArtifactsDir(), "SaveHtmlWithOptions"); + + if (Directory.exists(imagesDir)) + Directory.delete(imagesDir, true); + + Directory.createDirectory(imagesDir); + + // Set an option to export form fields as plain text instead of HTML input elements. + HtmlSaveOptions options = new HtmlSaveOptions(SaveFormat.HTML); + { + options.setExportTextInputFormFieldAsText(true); + options.setImagesFolder(imagesDir); + } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.SaveHtmlWithOptions.html", options); + //ExEnd + + Assert.assertTrue(File.exists(getArtifactsDir() + "HtmlSaveOptions.SaveHtmlWithOptions.html")); + Assert.assertEquals(9, Directory.getFiles(imagesDir).length); + + Directory.delete(imagesDir, true); + } + + //ExStart + //ExFor:ImageSavingArgs.CurrentShape + //ExFor:ImageSavingArgs.Document + //ExFor:ImageSavingArgs.ImageStream + //ExFor:ImageSavingArgs.IsImageAvailable + //ExFor:ImageSavingArgs.KeepImageStreamOpen + //ExSummary:Shows how to involve an image saving callback in an HTML conversion process. + @Test //ExSkip + public void imageSavingCallback() throws Exception + { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // When we save the document to HTML, we can pass a SaveOptions object to designate a callback + // to customize the image saving process. + HtmlSaveOptions options = new HtmlSaveOptions(); + options.setImageSavingCallback(new ImageShapePrinter()); + + doc.save(getArtifactsDir() + "HtmlSaveOptions.ImageSavingCallback.html", options); + } + + /// + /// Prints the properties of each image as the saving process saves it to an image file in the local file system + /// during the exporting of a document to HTML. + /// + private static class ImageShapePrinter implements IImageSavingCallback + { + public void /*IImageSavingCallback.*/imageSaving(ImageSavingArgs args) + { + args.setKeepImageStreamOpen(false); + Assert.assertTrue(args.isImageAvailable()); + + System.out.println("{args.Document.OriginalFileName.Split('\\').Last()} Image #{++mImageCount}"); + + LayoutCollector layoutCollector = new LayoutCollector(args.getDocument()); + + System.out.println("\tOn page:\t{layoutCollector.GetStartPageIndex(args.CurrentShape)}"); + System.out.println("\tDimensions:\t{args.CurrentShape.Bounds}"); + System.out.println("\tAlignment:\t{args.CurrentShape.VerticalAlignment}"); + System.out.println("\tWrap type:\t{args.CurrentShape.WrapType}"); + System.out.println("Output filename:\t{args.ImageFileName}\n"); + } + + private int mImageCount; + } + //ExEnd + + @Test (dataProvider = "prettyFormatDataProvider") + public void prettyFormat(boolean usePrettyFormat) throws Exception + { + //ExStart + //ExFor:SaveOptions.PrettyFormat + //ExSummary:Shows how to enhance the readability of the raw code of a saved .html document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + HtmlSaveOptions htmlOptions = new HtmlSaveOptions(SaveFormat.HTML); { htmlOptions.setPrettyFormat(usePrettyFormat); } + + doc.save(getArtifactsDir() + "HtmlSaveOptions.PrettyFormat.html", htmlOptions); + + // Enabling pretty format makes the raw html code more readable by adding tab stop and new line characters. + String html = File.readAllText(getArtifactsDir() + "HtmlSaveOptions.PrettyFormat.html"); + + String newLine = Environment.getNewLine(); + if (usePrettyFormat) + Assert.assertEquals("{newLine}" + + $"\t{newLine}" + + $"\t\t{newLine}" + + $"\t\t{newLine}" + + $"\t\t{newLine}" + + $"\t\t{newLine}" + + $"\t\t{newLine}" + + $"\t{newLine}" + + $"\t{newLine}" + + $"\t\t
          {newLine}" + + $"\t\t\t

          {newLine}" + + $"\t\t\t\tHello world!{newLine}" + + $"\t\t\t

          {newLine}" + + $"\t\t\t

          {newLine}" + + $"\t\t\t\t {newLine}" + + $"\t\t\t

          {newLine}" + + $"\t\t
          {newLine}" + + $"\t{newLine}", html); + else + Assert.assertEquals("" + + "" + + $"" + + "" + + "

          Hello world!

          " + + "

           

          ", html); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "prettyFormatDataProvider") + public static Object[][] prettyFormatDataProvider() throws Exception + { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test (dataProvider = "progressCallbackDataProvider") + //ExStart + //ExFor:SaveOptions.ProgressCallback + //ExFor:IDocumentSavingCallback + //ExFor:IDocumentSavingCallback.Notify(DocumentSavingArgs) + //ExFor:DocumentSavingArgs.EstimatedProgress + //ExFor:DocumentSavingArgs + //ExSummary:Shows how to manage a document while saving to html. + public void progressCallback(/*SaveFormat*/int saveFormat, String ext) throws Exception + { + Document doc = new Document(getMyDir() + "Big document.docx"); + + // Following formats are supported: Html, Mhtml, Epub. + HtmlSaveOptions saveOptions = new HtmlSaveOptions(saveFormat); + { + saveOptions.setProgressCallback(new SavingProgressCallback()); + } + + IllegalStateException exception = Assert.Throws(() => + doc.save(getArtifactsDir() + $"HtmlSaveOptions.ProgressCallback.{ext}", saveOptions)); + Assert.That(exception?.Message.Contains("EstimatedProgress"), assertTrue(); + } + + //JAVA-added data provider for test method + @DataProvider(name = "progressCallbackDataProvider") + public static Object[][] progressCallbackDataProvider() throws Exception + { + return new Object[][] + { + {SaveFormat.HTML, "html"}, + {SaveFormat.MHTML, "mhtml"}, + {SaveFormat.EPUB, "epub"}, + }; + } + + /// + /// Saving progress callback. Cancel a document saving after the "MaxDuration" seconds. + /// + public static class SavingProgressCallback implements IDocumentSavingCallback + { + /// + /// Ctr. + /// + public SavingProgressCallback() + { + mSavingStartedAt = new Date; + } + + /// + /// Callback method which called during document saving. + /// + /// Saving arguments. + public void notify(DocumentSavingArgs args) + { + DateTime canceledAt = new Date; + double ellapsedSeconds = (DateTime.subtract(canceledAt, mSavingStartedAt)).getTotalSeconds(); + if (ellapsedSeconds > MAX_DURATION) + throw new IllegalStateException($"EstimatedProgress = {args.EstimatedProgress}; CanceledAt = {canceledAt}"); + } + + /// + /// Date and time when document saving is started. + /// + private /*final*/ DateTime mSavingStartedAt; + + /// + /// Maximum allowed duration in sec. + /// + private static final double MAX_DURATION = 0.1d; + } + //ExEnd + + @Test (dataProvider = "mobiAzw3DefaultEncodingDataProvider") + public void mobiAzw3DefaultEncoding(/*SaveFormat*/int saveFormat) throws Exception + { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + saveOptions.setSaveFormat(saveFormat); + saveOptions.setEncodingInternal(Encoding.getASCII()); + + String outputFileName = $"{ArtifactsDir}HtmlSaveOptions.MobiDefaultEncoding{FileFormatUtil.SaveFormatToExtension(saveFormat)}"; + doc.save(outputFileName); + + Encoding encoding = TestUtil.getEncoding(outputFileName); + Assert.Is.Not.EqualTo(Encoding.getASCII())encoding); + Assert.assertEquals(Encoding.getUTF8(), encoding); + } + + //JAVA-added data provider for test method + @DataProvider(name = "mobiAzw3DefaultEncodingDataProvider") + public static Object[][] mobiAzw3DefaultEncodingDataProvider() throws Exception + { + return new Object[][] + { + {SaveFormat.MOBI}, + {SaveFormat.AZW_3}, + }; + } + + @Test + public void htmlReplaceBackslashWithYenSign() throws Exception + { + //ExStart:HtmlReplaceBackslashWithYenSign + //GistId:708ce40a68fac5003d46f6b4acfd5ff1 + //ExFor:HtmlSaveOptions.ReplaceBackslashWithYenSign + //ExSummary:Shows how to replace backslash characters with yen signs (Html). + Document doc = new Document(getMyDir() + "Korean backslash symbol.docx"); + + // By default, Aspose.Words mimics MS Word's behavior and doesn't replace backslash characters with yen signs in + // generated HTML documents. However, previous versions of Aspose.Words performed such replacements in certain + // scenarios. This flag enables backward compatibility with previous versions of Aspose.Words. + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + saveOptions.setReplaceBackslashWithYenSign(true); + + doc.save(getArtifactsDir() + "HtmlSaveOptions.ReplaceBackslashWithYenSign.html", saveOptions); + //ExEnd:HtmlReplaceBackslashWithYenSign + } + + @Test + public void removeJavaScriptFromLinks() throws Exception + { + //ExStart:HtmlRemoveJavaScriptFromLinks + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:HtmlFixedSaveOptions.RemoveJavaScriptFromLinks + //ExSummary:Shows how to remove JavaScript from the links. + Document doc = new Document(getMyDir() + "JavaScript in HREF.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + saveOptions.setRemoveJavaScriptFromLinks(true); + + doc.save(getArtifactsDir() + "HtmlSaveOptions.RemoveJavaScriptFromLinks.html", saveOptions); + //ExEnd:HtmlRemoveJavaScriptFromLinks + } +} + diff --git a/Examples/ApiExamples/JavaPorting/ExHyphenation.java b/Examples/ApiExamples/JavaPorting/ExHyphenation.java new file mode 100644 index 00000000..eb85c49c --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExHyphenation.java @@ -0,0 +1,175 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Hyphenation; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.Document; +import com.aspose.words.Run; +import com.aspose.words.WarningInfoCollection; +import com.aspose.ms.System.IO.Stream; +import com.aspose.ms.System.IO.FileStream; +import com.aspose.ms.System.IO.FileMode; +import com.aspose.words.WarningType; +import com.aspose.words.WarningSource; +import com.aspose.words.IHyphenationCallback; +import java.util.HashMap; +import com.aspose.ms.System.msConsole; + + +@Test +public class ExHyphenation extends ApiExampleBase +{ + @Test + public void dictionary() throws Exception + { + //ExStart + //ExFor:Hyphenation.IsDictionaryRegistered(String) + //ExFor:Hyphenation.RegisterDictionary(String, String) + //ExFor:Hyphenation.UnregisterDictionary(String) + //ExSummary:Shows how to register a hyphenation dictionary. + // A hyphenation dictionary contains a list of strings that define hyphenation rules for the dictionary's language. + // When a document contains lines of text in which a word could be split up and continued on the next line, + // hyphenation will look through the dictionary's list of strings for that word's substrings. + // If the dictionary contains a substring, then hyphenation will split the word across two lines + // by the substring and add a hyphen to the first half. + // Register a dictionary file from the local file system to the "de-CH" locale. + Hyphenation.registerDictionary("de-CH", getMyDir() + "hyph_de_CH.dic"); + + Assert.assertTrue(Hyphenation.isDictionaryRegistered("de-CH")); + + // Open a document containing text with a locale matching that of our dictionary, + // and save it to a fixed-page save format. The text in that document will be hyphenated. + Document doc = new Document(getMyDir() + "German text.docx"); + + Assert.That(doc.getFirstSection().getBody().getFirstParagraph().getRuns().OfType().All( + r => r.Font.LocaleId == new CultureInfo("de-CH").LCID), assertTrue(); + + doc.save(getArtifactsDir() + "Hyphenation.Dictionary.Registered.pdf"); + + // Re-load the document after un-registering the dictionary, + // and save it to another PDF, which will not have hyphenated text. + Hyphenation.unregisterDictionary("de-CH"); + + Assert.assertFalse(Hyphenation.isDictionaryRegistered("de-CH")); + + doc = new Document(getMyDir() + "German text.docx"); + doc.save(getArtifactsDir() + "Hyphenation.Dictionary.Unregistered.pdf"); + //ExEnd + } + + @Test + public void usePdfDocumentForDictionary() throws Exception + { + final String UNICODE_OPTIONAL_HYPHEN = "\u00ad"; + + dictionary(); + + Aspose.Pdf.Document pdfDoc = new Aspose.Pdf.Document(getArtifactsDir() + "Hyphenation.Dictionary.Registered.pdf"); + TextAbsorber textAbsorber = new TextAbsorber(); + textAbsorber.Visit(pdfDoc); + Assert.That(textAbsorber.Text.Replace(" ", " ").Contains($"La ob storen an deinen am sachen. Dop{unicodeOptionalHyphen}{Environment.NewLine}" + + $"pelte um da am spateren verlogen ge{unicodeOptionalHyphen}{Environment.NewLine}" + + $"kommen achtzehn blaulich."), assertTrue(); + + pdfDoc = new Aspose.Pdf.Document(getArtifactsDir() + "Hyphenation.Dictionary.Unregistered.pdf"); + textAbsorber = new TextAbsorber(); + textAbsorber.Visit(pdfDoc); + + Assert.That(textAbsorber.Text.Replace(" ", " ").Contains($"La ob storen an deinen am sachen. {Environment.NewLine}" + + $"Doppelte um da am spateren verlogen {Environment.NewLine}" + + $"gekommen achtzehn blaulich."), assertTrue(); + } + + //ExStart + //ExFor:Hyphenation + //ExFor:Hyphenation.Callback + //ExFor:Hyphenation.RegisterDictionary(String, Stream) + //ExFor:Hyphenation.RegisterDictionary(String, String) + //ExFor:Hyphenation.WarningCallback + //ExFor:IHyphenationCallback + //ExFor:IHyphenationCallback.RequestDictionary(String) + //ExSummary:Shows how to open and register a dictionary from a file. + @Test //ExSkip + public void registerDictionary() throws Exception + { + // Set up a callback that tracks warnings that occur during hyphenation dictionary registration. + WarningInfoCollection warningInfoCollection = new WarningInfoCollection(); + Hyphenation.setWarningCallback(warningInfoCollection); + + // Register an English (US) hyphenation dictionary by stream. + Stream dictionaryStream = new FileStream(getMyDir() + "hyph_en_US.dic", FileMode.OPEN); + Hyphenation.registerDictionaryInternal("en-US", dictionaryStream); + + Assert.assertEquals(0, warningInfoCollection.getCount()); + + // Open a document with a locale that Microsoft Word may not hyphenate on an English machine, such as German. + Document doc = new Document(getMyDir() + "German text.docx"); + + // To hyphenate that document upon saving, we need a hyphenation dictionary for the "de-CH" language code. + // This callback will handle the automatic request for that dictionary. + Hyphenation.setCallback(new CustomHyphenationDictionaryRegister()); + + // When we save the document, German hyphenation will take effect. + doc.save(getArtifactsDir() + "Hyphenation.RegisterDictionary.pdf"); + + // This dictionary contains two identical patterns, which will trigger a warning. + Assert.assertEquals(1, warningInfoCollection.getCount()); + Assert.assertEquals(WarningType.MINOR_FORMATTING_LOSS, warningInfoCollection.get(0).getWarningType()); + Assert.assertEquals(WarningSource.LAYOUT, warningInfoCollection.get(0).getSource()); + Assert.assertEquals("Hyphenation dictionary contains duplicate patterns. The only first found pattern will be used. " + + "Content can be wrapped differently.", warningInfoCollection.get(0).getDescription()); + + Hyphenation.setWarningCallback(null); //ExSkip + Hyphenation.unregisterDictionary("en-US"); //ExSkip + Hyphenation.setCallback(null); //ExSkip + } + + /// + /// Associates ISO language codes with local system filenames for hyphenation dictionary files. + /// + private static class CustomHyphenationDictionaryRegister implements IHyphenationCallback + { + public CustomHyphenationDictionaryRegister() + { + mHyphenationDictionaryFiles = new HashMap(); + { + mHyphenationDictionaryFiles.put( "en-US", getMyDir() + "hyph_en_US.dic"); + mHyphenationDictionaryFiles.put( "de-CH", getMyDir() + "hyph_de_CH.dic"); + } + } + + public void requestDictionary(String language) throws Exception + { + msConsole.write("Hyphenation dictionary requested: " + language); + + if (Hyphenation.isDictionaryRegistered(language)) + { + System.out.println(", is already registered."); + return; + } + + if (mHyphenationDictionaryFiles.containsKey(language)) + { + Hyphenation.registerDictionary(language, mHyphenationDictionaryFiles.get(language)); + System.out.println(", successfully registered."); + return; + } + + System.out.println(", no respective dictionary file known by this Callback."); + } + + private /*final*/ HashMap mHyphenationDictionaryFiles; + } + //ExEnd +} + diff --git a/Examples/ApiExamples/JavaPorting/ExImage.java b/Examples/ApiExamples/JavaPorting/ExImage.java new file mode 100644 index 00000000..b8c0ec63 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExImage.java @@ -0,0 +1,461 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.Shape; +import com.aspose.words.ShapeType; +import com.aspose.words.NodeType; +import com.aspose.words.ImageType; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.NodeCollection; +import com.aspose.ms.System.IO.Stream; +import java.io.FileInputStream; +import com.aspose.ms.System.IO.File; +import com.aspose.words.WrapType; +import com.aspose.words.RelativeHorizontalPosition; +import com.aspose.words.RelativeVerticalPosition; +import com.aspose.words.HorizontalAlignment; +import com.aspose.words.VerticalAlignment; +import com.aspose.ms.System.IO.FileInfo; +import com.aspose.words.Node; +import com.aspose.words.ImageSize; + + +/// +/// Mostly scenarios that deal with image shapes. +/// +@Test +public class ExImage extends ApiExampleBase +{ + @Test + public void fromFile() throws Exception + { + //ExStart + //ExFor:Shape.#ctor(DocumentBase,ShapeType) + //ExFor:ShapeType + //ExSummary:Shows how to insert a shape with an image from the local file system into a document. + Document doc = new Document(); + + // The "Shape" class's public constructor will create a shape with "ShapeMarkupLanguage.Vml" markup type. + // If you need to create a shape of a non-primitive type, such as SingleCornerSnipped, TopCornersSnipped, DiagonalCornersSnipped, + // TopCornersOneRoundedOneSnipped, SingleCornerRounded, TopCornersRounded, or DiagonalCornersRounded, + // please use DocumentBuilder.InsertShape. + Shape shape = new Shape(doc, ShapeType.IMAGE); + shape.getImageData().setImage(getImageDir() + "Windows MetaFile.wmf"); + shape.setWidth(100.0); + shape.setHeight(100.0); + + doc.getFirstSection().getBody().getFirstParagraph().appendChild(shape); + + doc.save(getArtifactsDir() + "Image.FromFile.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Image.FromFile.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(1600, 1600, ImageType.WMF, shape); + Assert.assertEquals(100.0d, shape.getHeight()); + Assert.assertEquals(100.0d, shape.getWidth()); + } + + @Test (groups = "IgnoreOnJenkins") + public void fromUrl() throws Exception + { + //ExStart + //ExFor:DocumentBuilder.InsertImage(String) + //ExSummary:Shows how to insert a shape with an image into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are two locations where the document builder's "InsertShape" method + // can source the image that the shape will display. + // 1 - Pass a local file system filename of an image file: + builder.write("Image from local file: "); + builder.insertImage(getImageDir() + "Logo.jpg"); + builder.writeln(); + + // 2 - Pass a URL which points to an image. + builder.write("Image from a URL: "); + builder.insertImage(getImageUrl()); + builder.writeln(); + + doc.save(getArtifactsDir() + "Image.FromUrl.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Image.FromUrl.docx"); + NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); + + Assert.assertEquals(2, shapes.getCount()); + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, (Shape)shapes.get(0)); + TestUtil.verifyImageInShape(272, 92, ImageType.PNG, (Shape)shapes.get(1)); + } + + @Test + public void fromStream() throws Exception + { + //ExStart + //ExFor:DocumentBuilder.InsertImage(Stream) + //ExSummary:Shows how to insert a shape with an image from a stream into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Stream stream = new FileInputStream(getImageDir() + "Logo.jpg"); + try /*JAVA: was using*/ + { + builder.write("Image from stream: "); + builder.insertImageInternal(stream); + } + finally { if (stream != null) stream.close(); } + + doc.save(getArtifactsDir() + "Image.FromStream.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Image.FromStream.docx"); + + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, (Shape)doc.getChildNodes(NodeType.SHAPE, true).get(0)); + } + + @Test + public void createFloatingPageCenter() throws Exception + { + //ExStart + //ExFor:DocumentBuilder.InsertImage(String) + //ExFor:Shape + //ExFor:ShapeBase + //ExFor:ShapeBase.WrapType + //ExFor:ShapeBase.BehindText + //ExFor:ShapeBase.RelativeHorizontalPosition + //ExFor:ShapeBase.RelativeVerticalPosition + //ExFor:ShapeBase.HorizontalAlignment + //ExFor:ShapeBase.VerticalAlignment + //ExFor:WrapType + //ExFor:RelativeHorizontalPosition + //ExFor:RelativeVerticalPosition + //ExFor:HorizontalAlignment + //ExFor:VerticalAlignment + //ExSummary:Shows how to insert a floating image to the center of a page. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a floating image that will appear behind the overlapping text and align it to the page's center. + Shape shape = builder.insertImage(getImageDir() + "Logo.jpg"); + shape.setWrapType(WrapType.NONE); + shape.setBehindText(true); + shape.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE); + shape.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE); + shape.setHorizontalAlignment(HorizontalAlignment.CENTER); + shape.setVerticalAlignment(VerticalAlignment.CENTER); + + doc.save(getArtifactsDir() + "Image.CreateFloatingPageCenter.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Image.CreateFloatingPageCenter.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, shape); + Assert.assertEquals(WrapType.NONE, shape.getWrapType()); + Assert.assertTrue(shape.getBehindText()); + Assert.assertEquals(RelativeHorizontalPosition.PAGE, shape.getRelativeHorizontalPosition()); + Assert.assertEquals(RelativeVerticalPosition.PAGE, shape.getRelativeVerticalPosition()); + Assert.assertEquals(HorizontalAlignment.CENTER, shape.getHorizontalAlignment()); + Assert.assertEquals(VerticalAlignment.CENTER, shape.getVerticalAlignment()); + } + + @Test + public void createFloatingPositionSize() throws Exception + { + //ExStart + //ExFor:ShapeBase.Left + //ExFor:ShapeBase.Right + //ExFor:ShapeBase.Top + //ExFor:ShapeBase.Bottom + //ExFor:ShapeBase.Width + //ExFor:ShapeBase.Height + //ExFor:DocumentBuilder.CurrentSection + //ExFor:PageSetup.PageWidth + //ExSummary:Shows how to insert a floating image, and specify its position and size. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertImage(getImageDir() + "Logo.jpg"); + shape.setWrapType(WrapType.NONE); + + // Configure the shape's "RelativeHorizontalPosition" property to treat the value of the "Left" property + // as the shape's horizontal distance, in points, from the left side of the page. + shape.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE); + + // Set the shape's horizontal distance from the left side of the page to 100. + shape.setLeft(100.0); + + // Use the "RelativeVerticalPosition" property in a similar way to position the shape 80pt below the top of the page. + shape.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE); + shape.setTop(80.0); + + // Set the shape's height, which will automatically scale the width to preserve dimensions. + shape.setHeight(125.0); + + Assert.assertEquals(125.0d, shape.getWidth()); + + // The "Bottom" and "Right" properties contain the bottom and right edges of the image. + Assert.assertEquals(shape.getTop() + shape.getHeight(), shape.getBottom()); + Assert.assertEquals(shape.getLeft() + shape.getWidth(), shape.getRight()); + + doc.save(getArtifactsDir() + "Image.CreateFloatingPositionSize.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Image.CreateFloatingPositionSize.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, shape); + Assert.assertEquals(WrapType.NONE, shape.getWrapType()); + Assert.assertEquals(RelativeHorizontalPosition.PAGE, shape.getRelativeHorizontalPosition()); + Assert.assertEquals(RelativeVerticalPosition.PAGE, shape.getRelativeVerticalPosition()); + Assert.assertEquals(100.0d, shape.getLeft()); + Assert.assertEquals(80.0d, shape.getTop()); + Assert.assertEquals(125.0d, shape.getHeight()); + Assert.assertEquals(125.0d, shape.getWidth()); + Assert.assertEquals(shape.getTop() + shape.getHeight(), shape.getBottom()); + Assert.assertEquals(shape.getLeft() + shape.getWidth(), shape.getRight()); + } + + @Test + public void insertImageWithHyperlink() throws Exception + { + //ExStart + //ExFor:ShapeBase.HRef + //ExFor:ShapeBase.ScreenTip + //ExFor:ShapeBase.Target + //ExSummary:Shows how to insert a shape which contains an image, and is also a hyperlink. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertImage(getImageDir() + "Logo.jpg"); + shape.setHRef("https://forum.aspose.com/"); + shape.setTarget("New Window"); + shape.setScreenTip("Aspose.Words Support Forums"); + + // Ctrl + left-clicking the shape in Microsoft Word will open a new web browser window + // and take us to the hyperlink in the "HRef" property. + doc.save(getArtifactsDir() + "Image.InsertImageWithHyperlink.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Image.InsertImageWithHyperlink.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals("https://forum.aspose.com/", shape.getHRef()); + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, shape); + Assert.assertEquals("New Window", shape.getTarget()); + Assert.assertEquals("Aspose.Words Support Forums", shape.getScreenTip()); + } + + @Test + public void createLinkedImage() throws Exception + { + //ExStart + //ExFor:Shape.ImageData + //ExFor:ImageData + //ExFor:ImageData.SourceFullName + //ExFor:ImageData.SetImage(String) + //ExFor:DocumentBuilder.InsertNode + //ExSummary:Shows how to insert a linked image into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + String imageFileName = getImageDir() + "Windows MetaFile.wmf"; + + // Below are two ways of applying an image to a shape so that it can display it. + // 1 - Set the shape to contain the image. + Shape shape = new Shape(builder.getDocument(), ShapeType.IMAGE); + shape.setWrapType(WrapType.INLINE); + shape.getImageData().setImage(imageFileName); + + builder.insertNode(shape); + + doc.save(getArtifactsDir() + "Image.CreateLinkedImage.Embedded.docx"); + + // Every image that we store in shape will increase the size of our document. + Assert.assertTrue(70000 < new FileInfo(getArtifactsDir() + "Image.CreateLinkedImage.Embedded.docx").getLength()); + + doc.getFirstSection().getBody().getFirstParagraph().removeAllChildren(); + + // 2 - Set the shape to link to an image file in the local file system. + shape = new Shape(builder.getDocument(), ShapeType.IMAGE); + shape.setWrapType(WrapType.INLINE); + shape.getImageData().setSourceFullName(imageFileName); + + builder.insertNode(shape); + doc.save(getArtifactsDir() + "Image.CreateLinkedImage.Linked.docx"); + + // Linking to images will save space and result in a smaller document. + // However, the document can only display the image correctly while + // the image file is present at the location that the shape's "SourceFullName" property points to. + Assert.assertTrue(10000 > new FileInfo(getArtifactsDir() + "Image.CreateLinkedImage.Linked.docx").getLength()); + //ExEnd + + doc = new Document(getArtifactsDir() + "Image.CreateLinkedImage.Embedded.docx"); + + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(1600, 1600, ImageType.WMF, shape); + Assert.assertEquals(WrapType.INLINE, shape.getWrapType()); + Assert.assertEquals("", shape.getImageData().getSourceFullName().replace("%20", " ")); + + doc = new Document(getArtifactsDir() + "Image.CreateLinkedImage.Linked.docx"); + + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(0, 0, ImageType.WMF, shape); + Assert.assertEquals(WrapType.INLINE, shape.getWrapType()); + Assert.assertEquals(imageFileName, shape.getImageData().getSourceFullName().replace("%20", " ")); + } + + @Test + public void deleteAllImages() throws Exception + { + //ExStart + //ExFor:Shape.HasImage + //ExFor:Node.Remove + //ExSummary:Shows how to delete all shapes with images from a document. + Document doc = new Document(getMyDir() + "Images.docx"); + NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); + + Assert.That(shapes.OfType().Count(s => s.HasImage), assertEquals(9, ); + + for (Shape shape : shapes.OfType() !!Autoporter error: Undefined expression type ) + if (shape.hasImage()) + shape.remove(); + + Assert.That(shapes.OfType().Count(s => s.HasImage), assertEquals(0, ); + //ExEnd + } + + @Test + public void deleteAllImagesPreOrder() throws Exception + { + //ExStart + //ExFor:Node.NextPreOrder(Node) + //ExFor:Node.PreviousPreOrder(Node) + //ExSummary:Shows how to traverse the document's node tree using the pre-order traversal algorithm, and delete any encountered shape with an image. + Document doc = new Document(getMyDir() + "Images.docx"); + + Assert.That(doc.getChildNodes(NodeType.SHAPE, true).OfType().Count(s => s.HasImage), assertEquals(9, ); + + Node curNode = doc; + while (curNode != null) + { + Node nextNode = curNode.nextPreOrder(doc); + + if (curNode.previousPreOrder(doc) != null && nextNode != null) + Assert.assertEquals(curNode, nextNode.previousPreOrder(doc)); + + if (curNode.getNodeType() == NodeType.SHAPE && ((Shape)curNode).hasImage()) + curNode.remove(); + + curNode = nextNode; + } + + Assert.That(doc.getChildNodes(NodeType.SHAPE, true).OfType().Count(s => s.HasImage), assertEquals(0, ); + //ExEnd + } + + @Test + public void scaleImage() throws Exception + { + //ExStart + //ExFor:ImageData.ImageSize + //ExFor:ImageSize + //ExFor:ImageSize.WidthPoints + //ExFor:ImageSize.HeightPoints + //ExFor:ShapeBase.Width + //ExFor:ShapeBase.Height + //ExSummary:Shows how to resize a shape with an image. + // When we insert an image using the "InsertImage" method, the builder scales the shape that displays the image so that, + // when we view the document using 100% zoom in Microsoft Word, the shape displays the image in its actual size. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + Shape shape = builder.insertImage(getImageDir() + "Logo.jpg"); + + // A 400x400 image will create an ImageData object with an image size of 300x300pt. + ImageSize imageSize = shape.getImageData().getImageSize(); + + Assert.assertEquals(300.0d, imageSize.getWidthPoints()); + Assert.assertEquals(300.0d, imageSize.getHeightPoints()); + + // If a shape's dimensions match the image data's dimensions, + // then the shape is displaying the image in its original size. + Assert.assertEquals(300.0d, shape.getWidth()); + Assert.assertEquals(300.0d, shape.getHeight()); + + // Reduce the overall size of the shape by 50%. + shape.setWidth(shape.getWidth() * 0.5); + + // Scaling factors apply to both the width and the height at the same time to preserve the shape's proportions. + Assert.assertEquals(150.0d, shape.getWidth()); + Assert.assertEquals(150.0d, shape.getHeight()); + + // When we resize the shape, the size of the image data remains the same. + Assert.assertEquals(300.0d, imageSize.getWidthPoints()); + Assert.assertEquals(300.0d, imageSize.getHeightPoints()); + + // We can reference the image data dimensions to apply a scaling based on the size of the image. + shape.setWidth(imageSize.getWidthPoints() * 1.1); + + Assert.assertEquals(330.0d, shape.getWidth()); + Assert.assertEquals(330.0d, shape.getHeight()); + + doc.save(getArtifactsDir() + "Image.ScaleImage.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Image.ScaleImage.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(330.0d, shape.getWidth()); + Assert.assertEquals(330.0d, shape.getHeight()); + + imageSize = shape.getImageData().getImageSize(); + + Assert.assertEquals(300.0d, imageSize.getWidthPoints()); + Assert.assertEquals(300.0d, imageSize.getHeightPoints()); + } + + @Test + public void insertWebpImage() throws Exception + { + //ExStart:InsertWebpImage + //GistId:e386727403c2341ce4018bca370a5b41 + //ExFor:DocumentBuilder.InsertImage(String) + //ExSummary:Shows how to insert WebP image. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertImage(getImageDir() + "WebP image.webp"); + + doc.save(getArtifactsDir() + "Image.InsertWebpImage.docx"); + //ExEnd:InsertWebpImage + } + + @Test + public void readWebpImage() throws Exception + { + //ExStart:ReadWebpImage + //GistId:e386727403c2341ce4018bca370a5b41 + //ExFor:ImageType + //ExSummary:Shows how to read WebP image. + Document doc = new Document(getMyDir() + "Document with WebP image.docx"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + Assert.assertEquals(ImageType.WEB_P, shape.getImageData().getImageType()); + //ExEnd:ReadWebpImage + } +} diff --git a/Examples/ApiExamples/JavaPorting/ExImageSaveOptions.java b/Examples/ApiExamples/JavaPorting/ExImageSaveOptions.java new file mode 100644 index 00000000..04e6907f --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExImageSaveOptions.java @@ -0,0 +1,734 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.BreakType; +import com.aspose.words.ImageSaveOptions; +import com.aspose.words.SaveFormat; +import com.aspose.words.PageSet; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.ms.System.IO.File; +import com.aspose.words.GraphicsQualityOptions; +import com.aspose.ms.System.Drawing.Drawing2D.SmoothingMode; +import com.aspose.ms.System.Drawing.Text.TextRenderingHint; +import com.aspose.ms.System.Drawing.Drawing2D.CompositingMode; +import com.aspose.ms.System.Drawing.Drawing2D.InterpolationMode; +import com.aspose.words.Shape; +import com.aspose.words.NodeType; +import com.aspose.words.ShapeRenderer; +import com.aspose.words.MetafileRenderingMode; +import com.aspose.ms.System.Drawing.msSize; +import java.util.ArrayList; +import com.aspose.ms.System.IO.Directory; +import com.aspose.words.ImageColorMode; +import com.aspose.ms.System.IO.FileInfo; +import com.aspose.ms.System.Drawing.msColor; +import java.awt.Color; +import com.aspose.words.ImagePixelFormat; +import com.aspose.words.TiffCompression; +import com.aspose.words.ImageBinarizationMethod; +import com.aspose.words.PageRange; +import com.aspose.words.ImlRenderingMode; +import com.aspose.words.MultiPageLayout; +import org.testng.annotations.DataProvider; + + +@Test +class ExImageSaveOptions !Test class should be public in Java to run, please fix .Net source! extends ApiExampleBase +{ + @Test + public void onePage() throws Exception + { + //ExStart + //ExFor:Document.Save(String, SaveOptions) + //ExFor:FixedPageSaveOptions + //ExFor:ImageSaveOptions.PageSet + //ExFor:PageSet + //ExFor:PageSet.#ctor(Int32) + //ExSummary:Shows how to render one page from a document to a JPEG image. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Page 1."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 2."); + builder.insertImage(getImageDir() + "Logo.jpg"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 3."); + + // Create an "ImageSaveOptions" object which we can pass to the document's "Save" method + // to modify the way in which that method renders the document into an image. + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.JPEG); + // Set the "PageSet" to "1" to select the second page via + // the zero-based index to start rendering the document from. + options.setPageSet(new PageSet(1)); + + // When we save the document to the JPEG format, Aspose.Words only renders one page. + // This image will contain one page starting from page two, + // which will just be the second page of the original document. + doc.save(getArtifactsDir() + "ImageSaveOptions.OnePage.jpg", options); + //ExEnd + + TestUtil.verifyImage(816, 1056, getArtifactsDir() + "ImageSaveOptions.OnePage.jpg"); + } + + @Test (dataProvider = "rendererDataProvider") + public void renderer(boolean useGdiEmfRenderer) throws Exception + { + //ExStart + //ExFor:ImageSaveOptions.UseGdiEmfRenderer + //ExSummary:Shows how to choose a renderer when converting a document to .emf. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 1")); + builder.writeln("Hello world!"); + builder.insertImage(getImageDir() + "Logo.jpg"); + + // When we save the document as an EMF image, we can pass a SaveOptions object to select a renderer for the image. + // If we set the "UseGdiEmfRenderer" flag to "true", Aspose.Words will use the GDI+ renderer. + // If we set the "UseGdiEmfRenderer" flag to "false", Aspose.Words will use its own metafile renderer. + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.EMF); + saveOptions.setUseGdiEmfRenderer(useGdiEmfRenderer); + + doc.save(getArtifactsDir() + "ImageSaveOptions.Renderer.emf", saveOptions); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "rendererDataProvider") + public static Object[][] rendererDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void pageSet() throws Exception + { + //ExStart + //ExFor:ImageSaveOptions.PageSet + //ExSummary:Shows how to specify which page in a document to render as an image. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 1")); + builder.writeln("Hello world! This is page 1."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("This is page 2."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("This is page 3."); + + Assert.assertEquals(3, doc.getPageCount()); + + // When we save the document as an image, Aspose.Words only renders the first page by default. + // We can pass a SaveOptions object to specify a different page to render. + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.GIF); + // Render every page of the document to a separate image file. + for (int i = 1; i <= doc.getPageCount(); i++) + { + saveOptions.setPageSet(new PageSet(1)); + + doc.save(getArtifactsDir() + $"ImageSaveOptions.PageIndex.Page {i}.gif", saveOptions); + } + //ExEnd + + TestUtil.verifyImage(816, 1056, getArtifactsDir() + "ImageSaveOptions.PageIndex.Page 1.gif"); + TestUtil.verifyImage(816, 1056, getArtifactsDir() + "ImageSaveOptions.PageIndex.Page 2.gif"); + TestUtil.verifyImage(816, 1056, getArtifactsDir() + "ImageSaveOptions.PageIndex.Page 3.gif"); + Assert.assertFalse(File.exists(getArtifactsDir() + "ImageSaveOptions.PageIndex.Page 4.gif")); + } + + @Test + public void graphicsQuality() throws Exception + { + //ExStart + //ExFor:GraphicsQualityOptions + //ExFor:GraphicsQualityOptions.CompositingMode + //ExFor:GraphicsQualityOptions.CompositingQuality + //ExFor:GraphicsQualityOptions.InterpolationMode + //ExFor:GraphicsQualityOptions.StringFormat + //ExFor:GraphicsQualityOptions.SmoothingMode + //ExFor:GraphicsQualityOptions.TextRenderingHint + //ExFor:ImageSaveOptions.GraphicsQualityOptions + //ExSummary:Shows how to set render quality options while converting documents to image formats. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + GraphicsQualityOptions qualityOptions = new GraphicsQualityOptions(); + { + qualityOptions.setSmoothingMode(SmoothingMode.ANTI_ALIAS); + qualityOptions.setTextRenderingHint(TextRenderingHint.CLEAR_TYPE_GRID_FIT); + qualityOptions.setCompositingMode(CompositingMode.SOURCE_OVER); + qualityOptions.setCompositingQuality(CompositingQuality.HighQuality); + qualityOptions.setInterpolationMode(InterpolationMode.HIGH); + qualityOptions.setStringFormat(StringFormat.GenericTypographic); + } + + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.JPEG); + saveOptions.setGraphicsQualityOptions(qualityOptions); + + doc.save(getArtifactsDir() + "ImageSaveOptions.GraphicsQuality.jpg", saveOptions); + //ExEnd + + TestUtil.verifyImage(794, 1122, getArtifactsDir() + "ImageSaveOptions.GraphicsQuality.jpg"); + } + + @Test + public void useTileFlipMode() throws Exception + { + //ExStart + //ExFor:GraphicsQualityOptions.UseTileFlipMode + //ExSummary:Shows how to prevent the white line appears when rendering with a high resolution. + Document doc = new Document(getMyDir() + "Shape high dpi.docx"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + ShapeRenderer renderer = shape.getShapeRenderer(); + + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.PNG); + { + saveOptions.setResolution(500f); saveOptions.setGraphicsQualityOptions(new GraphicsQualityOptions()); { saveOptions.getGraphicsQualityOptions().setUseTileFlipMode(true); } + } + renderer.save(getArtifactsDir() + "ImageSaveOptions.UseTileFlipMode.png", saveOptions); + //ExEnd + } + + @Test (groups = "SkipMono", dataProvider = "windowsMetaFileDataProvider") + public void windowsMetaFile(/*MetafileRenderingMode*/int metafileRenderingMode) throws Exception + { + //ExStart + //ExFor:ImageSaveOptions.MetafileRenderingOptions + //ExFor:MetafileRenderingOptions.UseGdiRasterOperationsEmulation + //ExSummary:Shows how to set the rendering mode when saving documents with Windows Metafile images to other image formats. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertImage(getImageDir() + "Windows MetaFile.wmf"); + + // When we save the document as an image, we can pass a SaveOptions object to + // determine how the saving operation will process Windows Metafiles in the document. + // If we set the "RenderingMode" property to "MetafileRenderingMode.Vector", + // or "MetafileRenderingMode.VectorWithFallback", we will render all metafiles as vector graphics. + // If we set the "RenderingMode" property to "MetafileRenderingMode.Bitmap", we will render all metafiles as bitmaps. + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.PNG); + options.getMetafileRenderingOptions().setRenderingMode(metafileRenderingMode); + // Aspose.Words uses GDI+ for raster operations emulation, when value is set to true. + options.getMetafileRenderingOptions().setUseGdiRasterOperationsEmulation(true); + + doc.save(getArtifactsDir() + "ImageSaveOptions.WindowsMetaFile.png", options); + //ExEnd + + TestUtil.verifyImage(816, 1056, getArtifactsDir() + "ImageSaveOptions.WindowsMetaFile.png"); + } + + //JAVA-added data provider for test method + @DataProvider(name = "windowsMetaFileDataProvider") + public static Object[][] windowsMetaFileDataProvider() throws Exception + { + return new Object[][] + { + {MetafileRenderingMode.VECTOR}, + {MetafileRenderingMode.BITMAP}, + {MetafileRenderingMode.VECTOR_WITH_FALLBACK}, + }; + } + + @Test (groups = "SkipMono") + public void pageByPage() throws Exception + { + //ExStart + //ExFor:Document.Save(String, SaveOptions) + //ExFor:FixedPageSaveOptions + //ExFor:ImageSaveOptions.PageSet + //ExFor:ImageSaveOptions.ImageSize + //ExSummary:Shows how to render every page of a document to a separate TIFF image. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Page 1."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 2."); + builder.insertImage(getImageDir() + "Logo.jpg"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 3."); + + // Create an "ImageSaveOptions" object which we can pass to the document's "Save" method + // to modify the way in which that method renders the document into an image. + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.TIFF); + + for (int i = 0; i < doc.getPageCount(); i++) + { + // Set the "PageSet" property to the number of the first page from + // which to start rendering the document from. + options.setPageSet(new PageSet(i)); + // Export page at 2325x5325 pixels and 600 dpi. + options.setResolution(600f); + options.setImageSizeInternal(msSize.ctor(2325, 5325)); + + doc.save(getArtifactsDir() + $"ImageSaveOptions.PageByPage.{i + 1}.tiff", options); + } + //ExEnd + + ArrayList imageFileNames = Directory.getFiles(getArtifactsDir(), "*.tiff") + .Where(item => item.Contains("ImageSaveOptions.PageByPage.") && item.EndsWith(".tiff")).ToList(); + Assert.assertEquals(3, imageFileNames.size()); + } + + @Test (dataProvider = "colorModeDataProvider") + public void colorMode(/*ImageColorMode*/int imageColorMode) throws Exception + { + //ExStart + //ExFor:ImageColorMode + //ExFor:ImageSaveOptions.ImageColorMode + //ExSummary:Shows how to set a color mode when rendering documents. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 1")); + builder.writeln("Hello world!"); + builder.insertImage(getImageDir() + "Logo.jpg"); + + // When we save the document as an image, we can pass a SaveOptions object to + // select a color mode for the image that the saving operation will generate. + // If we set the "ImageColorMode" property to "ImageColorMode.BlackAndWhite", + // the saving operation will apply grayscale color reduction while rendering the document. + // If we set the "ImageColorMode" property to "ImageColorMode.Grayscale", + // the saving operation will render the document into a monochrome image. + // If we set the "ImageColorMode" property to "None", the saving operation will apply the default method + // and preserve all the document's colors in the output image. + ImageSaveOptions imageSaveOptions = new ImageSaveOptions(SaveFormat.PNG); + imageSaveOptions.setImageColorMode(imageColorMode); + + doc.save(getArtifactsDir() + "ImageSaveOptions.ColorMode.png", imageSaveOptions); + //ExEnd + + long testedImageLength = new FileInfo(getArtifactsDir() + "ImageSaveOptions.ColorMode.png").getLength(); + + switch (imageColorMode) + { + case ImageColorMode.NONE: + Assert.assertTrue(testedImageLength < 175000); + break; + case ImageColorMode.GRAYSCALE: + Assert.assertTrue(testedImageLength < 90000); + break; + case ImageColorMode.BLACK_AND_WHITE: + Assert.assertTrue(testedImageLength < 15000); + break; + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "colorModeDataProvider") + public static Object[][] colorModeDataProvider() throws Exception + { + return new Object[][] + { + {ImageColorMode.BLACK_AND_WHITE}, + {ImageColorMode.GRAYSCALE}, + {ImageColorMode.NONE}, + }; + } + + @Test + public void paperColor() throws Exception + { + //ExStart + //ExFor:ImageSaveOptions + //ExFor:ImageSaveOptions.PaperColor + //ExSummary:Renders a page of a Word document into an image with transparent or colored background. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Times New Roman"); + builder.getFont().setSize(24.0); + builder.writeln("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + + builder.insertImage(getImageDir() + "Logo.jpg"); + + // Create an "ImageSaveOptions" object which we can pass to the document's "Save" method + // to modify the way in which that method renders the document into an image. + ImageSaveOptions imgOptions = new ImageSaveOptions(SaveFormat.PNG); + // Set the "PaperColor" property to a transparent color to apply a transparent + // background to the document while rendering it to an image. + imgOptions.setPaperColor(msColor.getTransparent()); + + doc.save(getArtifactsDir() + "ImageSaveOptions.PaperColor.Transparent.png", imgOptions); + + // Set the "PaperColor" property to an opaque color to apply that color + // as the background of the document as we render it to an image. + imgOptions.setPaperColor(msColor.getLightCoral()); + + doc.save(getArtifactsDir() + "ImageSaveOptions.PaperColor.LightCoral.png", imgOptions); + //ExEnd + + TestUtil.imageContainsTransparency(getArtifactsDir() + "ImageSaveOptions.PaperColor.Transparent.png"); + Assert.Throws(() => + TestUtil.imageContainsTransparency(getArtifactsDir() + "ImageSaveOptions.PaperColor.LightCoral.png")); + } + + @Test (dataProvider = "pixelFormatDataProvider") + public void pixelFormat(/*ImagePixelFormat*/int imagePixelFormat) throws Exception + { + //ExStart + //ExFor:ImagePixelFormat + //ExFor:ImageSaveOptions.Clone + //ExFor:ImageSaveOptions.PixelFormat + //ExSummary:Shows how to select a bit-per-pixel rate with which to render a document to an image. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 1")); + builder.writeln("Hello world!"); + builder.insertImage(getImageDir() + "Logo.jpg"); + + // When we save the document as an image, we can pass a SaveOptions object to + // select a pixel format for the image that the saving operation will generate. + // Various bit per pixel rates will affect the quality and file size of the generated image. + ImageSaveOptions imageSaveOptions = new ImageSaveOptions(SaveFormat.PNG); + imageSaveOptions.setPixelFormat(imagePixelFormat); + + // We can clone ImageSaveOptions instances. + Assert.Is.Not.EqualTo(imageSaveOptions)imageSaveOptions.deepClone()); + + doc.save(getArtifactsDir() + "ImageSaveOptions.PixelFormat.png", imageSaveOptions); + //ExEnd + + long testedImageLength = new FileInfo(getArtifactsDir() + "ImageSaveOptions.PixelFormat.png").getLength(); + + switch (imagePixelFormat) + { + case ImagePixelFormat.FORMAT_1_BPP_INDEXED: + Assert.assertTrue(testedImageLength < 2500); + break; + case ImagePixelFormat.FORMAT_16_BPP_RGB_565: + Assert.assertTrue(testedImageLength < 104000); + break; + case ImagePixelFormat.FORMAT_16_BPP_RGB_555: + Assert.assertTrue(testedImageLength < 88000); + break; + case ImagePixelFormat.FORMAT_24_BPP_RGB: + Assert.assertTrue(testedImageLength < 160000); + break; + case ImagePixelFormat.FORMAT_32_BPP_RGB: + case ImagePixelFormat.FORMAT_32_BPP_ARGB: + Assert.assertTrue(testedImageLength < 175000); + break; + case ImagePixelFormat.FORMAT_48_BPP_RGB: + Assert.assertTrue(testedImageLength < 212000); + break; + case ImagePixelFormat.FORMAT_64_BPP_ARGB: + case ImagePixelFormat.FORMAT_64_BPP_P_ARGB: + Assert.assertTrue(testedImageLength < 239000); + break; + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "pixelFormatDataProvider") + public static Object[][] pixelFormatDataProvider() throws Exception + { + return new Object[][] + { + {ImagePixelFormat.FORMAT_1_BPP_INDEXED}, + {ImagePixelFormat.FORMAT_16_BPP_RGB_555}, + {ImagePixelFormat.FORMAT_16_BPP_RGB_565}, + {ImagePixelFormat.FORMAT_24_BPP_RGB}, + {ImagePixelFormat.FORMAT_32_BPP_RGB}, + {ImagePixelFormat.FORMAT_32_BPP_ARGB}, + {ImagePixelFormat.FORMAT_32_BPP_P_ARGB}, + {ImagePixelFormat.FORMAT_48_BPP_RGB}, + {ImagePixelFormat.FORMAT_64_BPP_ARGB}, + {ImagePixelFormat.FORMAT_64_BPP_P_ARGB}, + }; + } + + @Test (groups = "SkipMono") + public void floydSteinbergDithering() throws Exception + { + //ExStart + //ExFor:ImageBinarizationMethod + //ExFor:ImageSaveOptions.ThresholdForFloydSteinbergDithering + //ExFor:ImageSaveOptions.TiffBinarizationMethod + //ExSummary:Shows how to set the TIFF binarization error threshold when using the Floyd-Steinberg method to render a TIFF image. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 1")); + builder.writeln("Hello world!"); + builder.insertImage(getImageDir() + "Logo.jpg"); + + // When we save the document as a TIFF, we can pass a SaveOptions object to + // adjust the dithering that Aspose.Words will apply when rendering this image. + // The default value of the "ThresholdForFloydSteinbergDithering" property is 128. + // Higher values tend to produce darker images. + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.TIFF); + { + options.setTiffCompression(TiffCompression.CCITT_3); + options.setTiffBinarizationMethod(ImageBinarizationMethod.FLOYD_STEINBERG_DITHERING); + options.setThresholdForFloydSteinbergDithering((byte) 240); + } + + doc.save(getArtifactsDir() + "ImageSaveOptions.FloydSteinbergDithering.tiff", options); + //ExEnd + + ArrayList imageFileNames = Directory.getFiles(getArtifactsDir(), "*.tiff") + .Where(item => item.Contains("ImageSaveOptions.FloydSteinbergDithering.") && item.EndsWith(".tiff")).ToList(); + Assert.assertEquals(1, imageFileNames.size()); + } + + @Test + public void editImage() throws Exception + { + //ExStart + //ExFor:ImageSaveOptions.HorizontalResolution + //ExFor:ImageSaveOptions.ImageBrightness + //ExFor:ImageSaveOptions.ImageContrast + //ExFor:ImageSaveOptions.SaveFormat + //ExFor:ImageSaveOptions.Scale + //ExFor:ImageSaveOptions.VerticalResolution + //ExSummary:Shows how to edit the image while Aspose.Words converts a document to one. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 1")); + builder.writeln("Hello world!"); + builder.insertImage(getImageDir() + "Logo.jpg"); + + // When we save the document as an image, we can pass a SaveOptions object to + // edit the image while the saving operation renders it. + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.PNG); + { + // We can adjust these properties to change the image's brightness and contrast. + // Both are on a 0-1 scale and are at 0.5 by default. + options.setImageBrightness(0.3f); + options.setImageContrast(0.7f); + + // We can adjust horizontal and vertical resolution with these properties. + // This will affect the dimensions of the image. + // The default value for these properties is 96.0, for a resolution of 96dpi. + options.setHorizontalResolution(72f); + options.setVerticalResolution(72f); + + // We can scale the image using this property. The default value is 1.0, for scaling of 100%. + // We can use this property to negate any changes in image dimensions that changing the resolution would cause. + options.setScale(96f / 72f); + } + + doc.save(getArtifactsDir() + "ImageSaveOptions.EditImage.png", options); + //ExEnd + + TestUtil.verifyImage(817, 1057, getArtifactsDir() + "ImageSaveOptions.EditImage.png"); + } + + @Test + public void jpegQuality() throws Exception + { + //ExStart + //ExFor:Document.Save(String, SaveOptions) + //ExFor:FixedPageSaveOptions.JpegQuality + //ExFor:ImageSaveOptions + //ExFor:ImageSaveOptions.#ctor + //ExFor:ImageSaveOptions.JpegQuality + //ExSummary:Shows how to configure compression while saving a document as a JPEG. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertImage(getImageDir() + "Logo.jpg"); + + // Create an "ImageSaveOptions" object which we can pass to the document's "Save" method + // to modify the way in which that method renders the document into an image. + ImageSaveOptions imageOptions = new ImageSaveOptions(SaveFormat.JPEG); + // Set the "JpegQuality" property to "10" to use stronger compression when rendering the document. + // This will reduce the file size of the document, but the image will display more prominent compression artifacts. + imageOptions.setJpegQuality(10); + doc.save(getArtifactsDir() + "ImageSaveOptions.JpegQuality.HighCompression.jpg", imageOptions); + + // Set the "JpegQuality" property to "100" to use weaker compression when rending the document. + // This will improve the quality of the image at the cost of an increased file size. + imageOptions.setJpegQuality(100); + doc.save(getArtifactsDir() + "ImageSaveOptions.JpegQuality.HighQuality.jpg", imageOptions); + //ExEnd + + Assert.assertTrue(new FileInfo(getArtifactsDir() + "ImageSaveOptions.JpegQuality.HighCompression.jpg").getLength() < 18000); + Assert.assertTrue(new FileInfo(getArtifactsDir() + "ImageSaveOptions.JpegQuality.HighQuality.jpg").getLength() < 75000); + } + + @Test (groups = "SkipMono", dataProvider = "tiffImageCompressionDataProvider") + public void tiffImageCompression(/*TiffCompression*/int tiffCompression) throws Exception + { + //ExStart + //ExFor:TiffCompression + //ExFor:ImageSaveOptions.TiffCompression + //ExSummary:Shows how to select the compression scheme to apply to a document that we convert into a TIFF image. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertImage(getImageDir() + "Logo.jpg"); + + // Create an "ImageSaveOptions" object which we can pass to the document's "Save" method + // to modify the way in which that method renders the document into an image. + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.TIFF); + // Set the "TiffCompression" property to "TiffCompression.None" to apply no compression while saving, + // which may result in a very large output file. + // Set the "TiffCompression" property to "TiffCompression.Rle" to apply RLE compression + // Set the "TiffCompression" property to "TiffCompression.Lzw" to apply LZW compression. + // Set the "TiffCompression" property to "TiffCompression.Ccitt3" to apply CCITT3 compression. + // Set the "TiffCompression" property to "TiffCompression.Ccitt4" to apply CCITT4 compression. + options.setTiffCompression(tiffCompression); + + doc.save(getArtifactsDir() + "ImageSaveOptions.TiffImageCompression.tiff", options); + //ExEnd + + long testedImageLength = new FileInfo(getArtifactsDir() + "ImageSaveOptions.TiffImageCompression.tiff").getLength(); + + switch (tiffCompression) + { + case TiffCompression.NONE: + Assert.assertTrue(testedImageLength < 3450000); + break; + case TiffCompression.RLE: + Assert.assertTrue(testedImageLength < 687000); + break; + case TiffCompression.LZW: + Assert.assertTrue(testedImageLength < 250000); + break; + case TiffCompression.CCITT_3: + Assert.assertTrue(testedImageLength < 8300); + break; + case TiffCompression.CCITT_4: + Assert.assertTrue(testedImageLength < 1700); + break; + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "tiffImageCompressionDataProvider") + public static Object[][] tiffImageCompressionDataProvider() throws Exception + { + return new Object[][] + { + {TiffCompression.NONE}, + {TiffCompression.RLE}, + {TiffCompression.LZW}, + {TiffCompression.CCITT_3}, + {TiffCompression.CCITT_4}, + }; + } + + @Test + public void resolution() throws Exception + { + //ExStart + //ExFor:ImageSaveOptions + //ExFor:ImageSaveOptions.Resolution + //ExSummary:Shows how to specify a resolution while rendering a document to PNG. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Times New Roman"); + builder.getFont().setSize(24.0); + builder.writeln("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + + builder.insertImage(getImageDir() + "Logo.jpg"); + + // Create an "ImageSaveOptions" object which we can pass to the document's "Save" method + // to modify the way in which that method renders the document into an image. + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.PNG); + + // Set the "Resolution" property to "72" to render the document in 72dpi. + options.setResolution(72f); + doc.save(getArtifactsDir() + "ImageSaveOptions.Resolution.72dpi.png", options); + + // Set the "Resolution" property to "300" to render the document in 300dpi. + options.setResolution(300f); + doc.save(getArtifactsDir() + "ImageSaveOptions.Resolution.300dpi.png", options); + //ExEnd + + TestUtil.verifyImage(612, 792, getArtifactsDir() + "ImageSaveOptions.Resolution.72dpi.png"); + TestUtil.verifyImage(2550, 3300, getArtifactsDir() + "ImageSaveOptions.Resolution.300dpi.png"); + } + + @Test + public void exportVariousPageRanges() throws Exception + { + //ExStart + //ExFor:PageSet.#ctor(PageRange[]) + //ExFor:PageRange + //ExFor:PageRange.#ctor(int, int) + //ExFor:ImageSaveOptions.PageSet + //ExSummary:Shows how to extract pages based on exact page ranges. + Document doc = new Document(getMyDir() + "Images.docx"); + + ImageSaveOptions imageOptions = new ImageSaveOptions(SaveFormat.TIFF); + PageSet pageSet = new PageSet(new PageRange(1, 1), new PageRange(2, 3), new PageRange(1, 3), + new PageRange(2, 4), new PageRange(1, 1)); + + imageOptions.setPageSet(pageSet); + doc.save(getArtifactsDir() + "ImageSaveOptions.ExportVariousPageRanges.tiff", imageOptions); + //ExEnd + } + + @Test + public void renderInkObject() throws Exception + { + //ExStart + //ExFor:SaveOptions.ImlRenderingMode + //ExFor:ImlRenderingMode + //ExSummary:Shows how to render Ink object. + Document doc = new Document(getMyDir() + "Ink object.docx"); + + // Set 'ImlRenderingMode.InkML' ignores fall-back shape of ink (InkML) object and renders InkML itself. + // If the rendering result is unsatisfactory, + // please use 'ImlRenderingMode.Fallback' to get a result similar to previous versions. + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.JPEG); + { + saveOptions.setImlRenderingMode(ImlRenderingMode.INK_ML); + } + + doc.save(getArtifactsDir() + "ImageSaveOptions.RenderInkObject.jpeg", saveOptions); + //ExEnd + } + + @Test + public void gridLayout() throws Exception + { + //ExStart:GridLayout + //GistId:70330eacdfc2e253f00a9adea8972975 + //ExFor:ImageSaveOptions.PageLayout + //ExFor:MultiPageLayout + //ExSummary:Shows how to save the document into JPG image with multi-page layout settings. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.JPEG); + // Set up a grid layout with: + // - 3 columns per row. + // - 10pts spacing between pages (horizontal and vertical). + options.setPageLayout(MultiPageLayout.grid(3, 10f, 10f)); + + // Alternative layouts: + // options.PageLayout = MultiPageLayout.Horizontal(10); + // options.PageLayout = MultiPageLayout.Vertical(10); + + // Customize the background and border. + options.getPageLayout().setBackColor(msColor.getLightGray()); + options.getPageLayout().setBorderColor(Color.BLUE); + options.getPageLayout().setBorderWidth(2f); + + doc.save(getArtifactsDir() + "ImageSaveOptions.GridLayout.jpg", options); + //ExEnd:GridLayout + } +} + diff --git a/Examples/ApiExamples/JavaPorting/ExInline.java b/Examples/ApiExamples/JavaPorting/ExInline.java new file mode 100644 index 00000000..19350d25 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExInline.java @@ -0,0 +1,90 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.Run; +import com.aspose.words.Paragraph; +import com.aspose.words.RunCollection; + + +@Test +class ExInline !Test class should be public in Java to run, please fix .Net source! extends ApiExampleBase +{ + @Test + public void inlineRevisions() throws Exception + { + //ExStart + //ExFor:Inline + //ExFor:Inline.IsDeleteRevision + //ExFor:Inline.IsFormatRevision + //ExFor:Inline.IsInsertRevision + //ExFor:Inline.IsMoveFromRevision + //ExFor:Inline.IsMoveToRevision + //ExFor:Inline.ParentParagraph + //ExFor:Paragraph.Runs + //ExFor:Revision.ParentNode + //ExFor:RunCollection + //ExFor:RunCollection.Item(Int32) + //ExFor:RunCollection.ToArray + //ExSummary:Shows how to determine the revision type of an inline node. + Document doc = new Document(getMyDir() + "Revision runs.docx"); + + // When we edit the document while the "Track Changes" option, found in via Review -> Tracking, + // is turned on in Microsoft Word, the changes we apply count as revisions. + // When editing a document using Aspose.Words, we can begin tracking revisions by + // invoking the document's "StartTrackRevisions" method and stop tracking by using the "StopTrackRevisions" method. + // We can either accept revisions to assimilate them into the document + // or reject them to change the proposed change effectively. + Assert.assertEquals(6, doc.getRevisions().getCount()); + + // The parent node of a revision is the run that the revision concerns. A Run is an Inline node. + Run run = (Run)doc.getRevisions().get(0).getParentNode(); + + Paragraph firstParagraph = run.getParentParagraph(); + RunCollection runs = firstParagraph.getRuns(); + + Assert.assertEquals(6, runs.toArray().length); + + // Below are five types of revisions that can flag an Inline node. + // 1 - An "insert" revision: + // This revision occurs when we insert text while tracking changes. + Assert.assertTrue(runs.get(2).isInsertRevision()); + + // 2 - A "format" revision: + // This revision occurs when we change the formatting of text while tracking changes. + Assert.assertTrue(runs.get(2).isFormatRevision()); + + // 3 - A "move from" revision: + // When we highlight text in Microsoft Word, and then drag it to a different place in the document + // while tracking changes, two revisions appear. + // The "move from" revision is a copy of the text originally before we moved it. + Assert.assertTrue(runs.get(4).isMoveFromRevision()); + + // 4 - A "move to" revision: + // The "move to" revision is the text that we moved in its new position in the document. + // "Move from" and "move to" revisions appear in pairs for every move revision we carry out. + // Accepting a move revision deletes the "move from" revision and its text, + // and keeps the text from the "move to" revision. + // Rejecting a move revision conversely keeps the "move from" revision and deletes the "move to" revision. + Assert.assertTrue(runs.get(1).isMoveToRevision()); + + // 5 - A "delete" revision: + // This revision occurs when we delete text while tracking changes. When we delete text like this, + // it will stay in the document as a revision until we either accept the revision, + // which will delete the text for good, or reject the revision, which will keep the text we deleted where it was. + Assert.assertTrue(runs.get(5).isDeleteRevision()); + //ExEnd + } +} + diff --git a/Examples/ApiExamples/JavaPorting/ExInlineStory.java b/Examples/ApiExamples/JavaPorting/ExInlineStory.java new file mode 100644 index 00000000..c34c1efb --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExInlineStory.java @@ -0,0 +1,726 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.FootnotePosition; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.FootnoteType; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.Footnote; +import com.aspose.words.NodeType; +import com.aspose.words.EndnotePosition; +import com.aspose.words.BreakType; +import com.aspose.words.NumberStyle; +import com.aspose.words.FootnoteNumberingRule; +import com.aspose.words.Comment; +import com.aspose.ms.System.DateTime; +import com.aspose.words.Paragraph; +import java.util.ArrayList; +import com.aspose.words.Table; +import com.aspose.ms.System.Drawing.msColor; +import java.awt.Color; +import com.aspose.words.StoryType; +import java.util.Date; +import com.aspose.words.SaveFormat; +import com.aspose.words.ShapeType; +import com.aspose.words.FootnoteSeparator; +import com.aspose.words.FootnoteSeparatorType; +import com.aspose.words.ParagraphAlignment; +import org.testng.annotations.DataProvider; + + +@Test +public class ExInlineStory extends ApiExampleBase +{ + @Test (dataProvider = "positionFootnoteDataProvider") + public void positionFootnote(/*FootnotePosition*/int footnotePosition) throws Exception + { + //ExStart + //ExFor:Document.FootnoteOptions + //ExFor:FootnoteOptions + //ExFor:FootnoteOptions.Position + //ExFor:FootnotePosition + //ExSummary:Shows how to select a different place where the document collects and displays its footnotes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // A footnote is a way to attach a reference or a side comment to text + // that does not interfere with the main body text's flow. + // Inserting a footnote adds a small superscript reference symbol + // at the main body text where we insert the footnote. + // Each footnote also creates an entry at the bottom of the page, consisting of a symbol + // that matches the reference symbol in the main body text. + // The reference text that we pass to the document builder's "InsertFootnote" method. + builder.write("Hello world!"); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote contents."); + + // We can use the "Position" property to determine where the document will place all its footnotes. + // If we set the value of the "Position" property to "FootnotePosition.BottomOfPage", + // every footnote will show up at the bottom of the page that contains its reference mark. This is the default value. + // If we set the value of the "Position" property to "FootnotePosition.BeneathText", + // every footnote will show up at the end of the page's text that contains its reference mark. + doc.getFootnoteOptions().setPosition(footnotePosition); + + doc.save(getArtifactsDir() + "InlineStory.PositionFootnote.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "InlineStory.PositionFootnote.docx"); + + Assert.assertEquals(footnotePosition, doc.getFootnoteOptions().getPosition()); + + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote contents.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 0, true)); + } + + //JAVA-added data provider for test method + @DataProvider(name = "positionFootnoteDataProvider") + public static Object[][] positionFootnoteDataProvider() throws Exception + { + return new Object[][] + { + {FootnotePosition.BENEATH_TEXT}, + {FootnotePosition.BOTTOM_OF_PAGE}, + }; + } + + @Test (dataProvider = "positionEndnoteDataProvider") + public void positionEndnote(/*EndnotePosition*/int endnotePosition) throws Exception + { + //ExStart + //ExFor:Document.EndnoteOptions + //ExFor:EndnoteOptions + //ExFor:EndnoteOptions.Position + //ExFor:EndnotePosition + //ExSummary:Shows how to select a different place where the document collects and displays its endnotes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // An endnote is a way to attach a reference or a side comment to text + // that does not interfere with the main body text's flow. + // Inserting an endnote adds a small superscript reference symbol + // at the main body text where we insert the endnote. + // Each endnote also creates an entry at the end of the document, consisting of a symbol + // that matches the reference symbol in the main body text. + // The reference text that we pass to the document builder's "InsertEndnote" method. + builder.write("Hello world!"); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote contents."); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.write("This is the second section."); + + // We can use the "Position" property to determine where the document will place all its endnotes. + // If we set the value of the "Position" property to "EndnotePosition.EndOfDocument", + // every footnote will show up in a collection at the end of the document. This is the default value. + // If we set the value of the "Position" property to "EndnotePosition.EndOfSection", + // every footnote will show up in a collection at the end of the section whose text contains the endnote's reference mark. + doc.getEndnoteOptions().setPosition(endnotePosition); + + doc.save(getArtifactsDir() + "InlineStory.PositionEndnote.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "InlineStory.PositionEndnote.docx"); + + Assert.assertEquals(endnotePosition, doc.getEndnoteOptions().getPosition()); + + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "Endnote contents.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 0, true)); + } + + //JAVA-added data provider for test method + @DataProvider(name = "positionEndnoteDataProvider") + public static Object[][] positionEndnoteDataProvider() throws Exception + { + return new Object[][] + { + {EndnotePosition.END_OF_DOCUMENT}, + {EndnotePosition.END_OF_SECTION}, + }; + } + + @Test + public void refMarkNumberStyle() throws Exception + { + //ExStart + //ExFor:Document.EndnoteOptions + //ExFor:EndnoteOptions + //ExFor:EndnoteOptions.NumberStyle + //ExFor:Document.FootnoteOptions + //ExFor:FootnoteOptions + //ExFor:FootnoteOptions.NumberStyle + //ExSummary:Shows how to change the number style of footnote/endnote reference marks. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Footnotes and endnotes are a way to attach a reference or a side comment to text + // that does not interfere with the main body text's flow. + // Inserting a footnote/endnote adds a small superscript reference symbol + // at the main body text where we insert the footnote/endnote. + // Each footnote/endnote also creates an entry, which consists of a symbol that matches the reference + // symbol in the main body text. The reference text that we pass to the document builder's "InsertEndnote" method. + // Footnote entries, by default, show up at the bottom of each page that contains + // their reference symbols, and endnotes show up at the end of the document. + builder.write("Text 1. "); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote 1."); + builder.write("Text 2. "); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote 2."); + builder.write("Text 3. "); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote 3.", "Custom footnote reference mark"); + + builder.insertParagraph(); + + builder.write("Text 1. "); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote 1."); + builder.write("Text 2. "); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote 2."); + builder.write("Text 3. "); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote 3.", "Custom endnote reference mark"); + + // By default, the reference symbol for each footnote and endnote is its index + // among all the document's footnotes/endnotes. Each document maintains separate counts + // for footnotes and for endnotes. By default, footnotes display their numbers using Arabic numerals, + // and endnotes display their numbers in lowercase Roman numerals. + Assert.assertEquals(NumberStyle.ARABIC, doc.getFootnoteOptions().getNumberStyle()); + Assert.assertEquals(NumberStyle.LOWERCASE_ROMAN, doc.getEndnoteOptions().getNumberStyle()); + + // We can use the "NumberStyle" property to apply custom numbering styles to footnotes and endnotes. + // This will not affect footnotes/endnotes with custom reference marks. + doc.getFootnoteOptions().setNumberStyle(NumberStyle.UPPERCASE_ROMAN); + doc.getEndnoteOptions().setNumberStyle(NumberStyle.UPPERCASE_LETTER); + + doc.save(getArtifactsDir() + "InlineStory.RefMarkNumberStyle.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "InlineStory.RefMarkNumberStyle.docx"); + + Assert.assertEquals(NumberStyle.UPPERCASE_ROMAN, doc.getFootnoteOptions().getNumberStyle()); + Assert.assertEquals(NumberStyle.UPPERCASE_LETTER, doc.getEndnoteOptions().getNumberStyle()); + + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote 1.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 0, true)); + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote 2.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 1, true)); + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, false, "Custom footnote reference mark", + "Custom footnote reference mark Footnote 3.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 2, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "Endnote 1.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 3, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "Endnote 2.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 4, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, false, "Custom endnote reference mark", + "Custom endnote reference mark Endnote 3.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 5, true)); + } + + @Test + public void numberingRule() throws Exception + { + //ExStart + //ExFor:Document.EndnoteOptions + //ExFor:EndnoteOptions + //ExFor:EndnoteOptions.RestartRule + //ExFor:FootnoteNumberingRule + //ExFor:Document.FootnoteOptions + //ExFor:FootnoteOptions + //ExFor:FootnoteOptions.RestartRule + //ExSummary:Shows how to restart footnote/endnote numbering at certain places in the document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Footnotes and endnotes are a way to attach a reference or a side comment to text + // that does not interfere with the main body text's flow. + // Inserting a footnote/endnote adds a small superscript reference symbol + // at the main body text where we insert the footnote/endnote. + // Each footnote/endnote also creates an entry, which consists of a symbol that matches the reference + // symbol in the main body text. The reference text that we pass to the document builder's "InsertEndnote" method. + // Footnote entries, by default, show up at the bottom of each page that contains + // their reference symbols, and endnotes show up at the end of the document. + builder.write("Text 1. "); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote 1."); + builder.write("Text 2. "); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote 2."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.write("Text 3. "); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote 3."); + builder.write("Text 4. "); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote 4."); + + builder.insertBreak(BreakType.PAGE_BREAK); + + builder.write("Text 1. "); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote 1."); + builder.write("Text 2. "); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote 2."); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.write("Text 3. "); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote 3."); + builder.write("Text 4. "); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote 4."); + + // By default, the reference symbol for each footnote and endnote is its index + // among all the document's footnotes/endnotes. Each document maintains separate counts + // for footnotes and endnotes and does not restart these counts at any point. + Assert.assertEquals(doc.getFootnoteOptions().getRestartRule(), FootnoteNumberingRule.DEFAULT); + Assert.assertEquals(FootnoteNumberingRule.DEFAULT, FootnoteNumberingRule.CONTINUOUS); + + // We can use the "RestartRule" property to get the document to restart + // the footnote/endnote counts at a new page or section. + doc.getFootnoteOptions().setRestartRule(FootnoteNumberingRule.RESTART_PAGE); + doc.getEndnoteOptions().setRestartRule(FootnoteNumberingRule.RESTART_SECTION); + + doc.save(getArtifactsDir() + "InlineStory.NumberingRule.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "InlineStory.NumberingRule.docx"); + + Assert.assertEquals(FootnoteNumberingRule.RESTART_PAGE, doc.getFootnoteOptions().getRestartRule()); + Assert.assertEquals(FootnoteNumberingRule.RESTART_SECTION, doc.getEndnoteOptions().getRestartRule()); + + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote 1.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 0, true)); + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote 2.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 1, true)); + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote 3.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 2, true)); + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote 4.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 3, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "Endnote 1.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 4, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "Endnote 2.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 5, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "Endnote 3.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 6, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "Endnote 4.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 7, true)); + } + + @Test + public void startNumber() throws Exception + { + //ExStart + //ExFor:Document.EndnoteOptions + //ExFor:EndnoteOptions + //ExFor:EndnoteOptions.StartNumber + //ExFor:Document.FootnoteOptions + //ExFor:FootnoteOptions + //ExFor:FootnoteOptions.StartNumber + //ExSummary:Shows how to set a number at which the document begins the footnote/endnote count. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Footnotes and endnotes are a way to attach a reference or a side comment to text + // that does not interfere with the main body text's flow. + // Inserting a footnote/endnote adds a small superscript reference symbol + // at the main body text where we insert the footnote/endnote. + // Each footnote/endnote also creates an entry, which consists of a symbol + // that matches the reference symbol in the main body text. + // The reference text that we pass to the document builder's "InsertEndnote" method. + // Footnote entries, by default, show up at the bottom of each page that contains + // their reference symbols, and endnotes show up at the end of the document. + builder.write("Text 1. "); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote 1."); + builder.write("Text 2. "); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote 2."); + builder.write("Text 3. "); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote 3."); + + builder.insertParagraph(); + + builder.write("Text 1. "); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote 1."); + builder.write("Text 2. "); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote 2."); + builder.write("Text 3. "); + builder.insertFootnote(FootnoteType.ENDNOTE, "Endnote 3."); + + // By default, the reference symbol for each footnote and endnote is its index + // among all the document's footnotes/endnotes. Each document maintains separate counts + // for footnotes and for endnotes, which both begin at 1. + Assert.assertEquals(1, doc.getFootnoteOptions().getStartNumber()); + Assert.assertEquals(1, doc.getEndnoteOptions().getStartNumber()); + + // We can use the "StartNumber" property to get the document to + // begin a footnote or endnote count at a different number. + doc.getEndnoteOptions().setNumberStyle(NumberStyle.ARABIC); + doc.getEndnoteOptions().setStartNumber(50); + + doc.save(getArtifactsDir() + "InlineStory.StartNumber.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "InlineStory.StartNumber.docx"); + + Assert.assertEquals(1, doc.getFootnoteOptions().getStartNumber()); + Assert.assertEquals(50, doc.getEndnoteOptions().getStartNumber()); + Assert.assertEquals(NumberStyle.ARABIC, doc.getFootnoteOptions().getNumberStyle()); + Assert.assertEquals(NumberStyle.ARABIC, doc.getEndnoteOptions().getNumberStyle()); + + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote 1.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 0, true)); + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote 2.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 1, true)); + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote 3.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 2, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "Endnote 1.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 3, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "Endnote 2.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 4, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "Endnote 3.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 5, true)); + } + + @Test + public void addFootnote() throws Exception + { + //ExStart + //ExFor:Footnote + //ExFor:Footnote.IsAuto + //ExFor:Footnote.ReferenceMark + //ExFor:InlineStory + //ExFor:InlineStory.Paragraphs + //ExFor:InlineStory.FirstParagraph + //ExFor:FootnoteType + //ExFor:Footnote.#ctor + //ExSummary:Shows how to insert and customize footnotes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Add text, and reference it with a footnote. This footnote will place a small superscript reference + // mark after the text that it references and create an entry below the main body text at the bottom of the page. + // This entry will contain the footnote's reference mark and the reference text, + // which we will pass to the document builder's "InsertFootnote" method. + builder.write("Main body text."); + Footnote footnote = builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote text."); + + // If this property is set to "true", then our footnote's reference mark + // will be its index among all the section's footnotes. + // This is the first footnote, so the reference mark will be "1". + Assert.assertTrue(footnote.isAuto()); + + // We can move the document builder inside the footnote to edit its reference text. + builder.moveTo(footnote.getFirstParagraph()); + builder.write(" More text added by a DocumentBuilder."); + builder.moveToDocumentEnd(); + + Assert.assertEquals("\u0002 Footnote text. More text added by a DocumentBuilder.", footnote.getText().trim()); + + builder.write(" More main body text."); + footnote = builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote text."); + + // We can set a custom reference mark which the footnote will use instead of its index number. + footnote.setReferenceMark("RefMark"); + + Assert.assertFalse(footnote.isAuto()); + + // A bookmark with the "IsAuto" flag set to true will still show its real index + // even if previous bookmarks display custom reference marks, so this bookmark's reference mark will be a "3". + builder.write(" More main body text."); + footnote = builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote text."); + + Assert.assertTrue(footnote.isAuto()); + + doc.save(getArtifactsDir() + "InlineStory.AddFootnote.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "InlineStory.AddFootnote.docx"); + + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote text. More text added by a DocumentBuilder.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 0, true)); + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, false, "RefMark", + "Footnote text.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 1, true)); + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote text.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 2, true)); + } + + @Test + public void footnoteEndnote() throws Exception + { + //ExStart + //ExFor:Footnote.FootnoteType + //ExSummary:Shows the difference between footnotes and endnotes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are two ways of attaching numbered references to the text. Both these references will add a + // small superscript reference mark at the location that we insert them. + // The reference mark, by default, is the index number of the reference among all the references in the document. + // Each reference will also create an entry, which will have the same reference mark as in the body text + // and reference text, which we will pass to the document builder's "InsertFootnote" method. + // 1 - A footnote, whose entry will appear on the same page as the text that it references: + builder.write("Footnote referenced main body text."); + Footnote footnote = builder.insertFootnote(FootnoteType.FOOTNOTE, + "Footnote text, will appear at the bottom of the page that contains the referenced text."); + + // 2 - An endnote, whose entry will appear at the end of the document: + builder.write("Endnote referenced main body text."); + Footnote endnote = builder.insertFootnote(FootnoteType.ENDNOTE, + "Endnote text, will appear at the very end of the document."); + + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + + Assert.assertEquals(FootnoteType.FOOTNOTE, footnote.getFootnoteType()); + Assert.assertEquals(FootnoteType.ENDNOTE, endnote.getFootnoteType()); + + doc.save(getArtifactsDir() + "InlineStory.FootnoteEndnote.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "InlineStory.FootnoteEndnote.docx"); + + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", + "Footnote text, will appear at the bottom of the page that contains the referenced text.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 0, true)); + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "Endnote text, will appear at the very end of the document.", (Footnote)doc.getChild(NodeType.FOOTNOTE, 1, true)); + } + + @Test + public void addComment() throws Exception + { + //ExStart + //ExFor:Comment + //ExFor:InlineStory + //ExFor:InlineStory.Paragraphs + //ExFor:InlineStory.FirstParagraph + //ExFor:Comment.#ctor(DocumentBase, String, String, DateTime) + //ExSummary:Shows how to add a comment to a paragraph. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.write("Hello world!"); + + Comment comment = new Comment(doc, "John Doe", "JD", DateTime.getToday()); + builder.getCurrentParagraph().appendChild(comment); + builder.moveTo(comment.appendChild(new Paragraph(doc))); + builder.write("Comment text."); + + Assert.assertEquals(DateTime.getToday(), comment.getDateTimeInternal()); + + // In Microsoft Word, we can right-click this comment in the document body to edit it, or reply to it. + doc.save(getArtifactsDir() + "InlineStory.AddComment.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "InlineStory.AddComment.docx"); + comment = (Comment)doc.getChild(NodeType.COMMENT, 0, true); + + Assert.assertEquals("Comment text.\r", comment.getText()); + Assert.assertEquals("John Doe", comment.getAuthor()); + Assert.assertEquals("JD", comment.getInitial()); + Assert.assertEquals(DateTime.getToday(), comment.getDateTimeInternal()); + } + + @Test + public void inlineStoryRevisions() throws Exception + { + //ExStart + //ExFor:InlineStory.IsDeleteRevision + //ExFor:InlineStory.IsInsertRevision + //ExFor:InlineStory.IsMoveFromRevision + //ExFor:InlineStory.IsMoveToRevision + //ExSummary:Shows how to view revision-related properties of InlineStory nodes. + Document doc = new Document(getMyDir() + "Revision footnotes.docx"); + + // When we edit the document while the "Track Changes" option, found in via Review -> Tracking, + // is turned on in Microsoft Word, the changes we apply count as revisions. + // When editing a document using Aspose.Words, we can begin tracking revisions by + // invoking the document's "StartTrackRevisions" method and stop tracking by using the "StopTrackRevisions" method. + // We can either accept revisions to assimilate them into the document + // or reject them to undo and discard the proposed change. + Assert.assertTrue(doc.hasRevisions()); + + ArrayList footnotes = doc.getChildNodes(NodeType.FOOTNOTE, true).Cast().ToList(); + + Assert.assertEquals(5, footnotes.size()); + + // Below are five types of revisions that can flag an InlineStory node. + // 1 - An "insert" revision: + // This revision occurs when we insert text while tracking changes. + Assert.assertTrue(footnotes.get(2).isInsertRevision()); + + // 2 - A "move from" revision: + // When we highlight text in Microsoft Word, and then drag it to a different place in the document + // while tracking changes, two revisions appear. + // The "move from" revision is a copy of the text originally before we moved it. + Assert.assertTrue(footnotes.get(4).isMoveFromRevision()); + + // 3 - A "move to" revision: + // The "move to" revision is the text that we moved in its new position in the document. + // "Move from" and "move to" revisions appear in pairs for every move revision we carry out. + // Accepting a move revision deletes the "move from" revision and its text, + // and keeps the text from the "move to" revision. + // Rejecting a move revision conversely keeps the "move from" revision and deletes the "move to" revision. + Assert.assertTrue(footnotes.get(1).isMoveToRevision()); + + // 4 - A "delete" revision: + // This revision occurs when we delete text while tracking changes. When we delete text like this, + // it will stay in the document as a revision until we either accept the revision, + // which will delete the text for good, or reject the revision, which will keep the text we deleted where it was. + Assert.assertTrue(footnotes.get(3).isDeleteRevision()); + //ExEnd + } + + @Test + public void insertInlineStoryNodes() throws Exception + { + //ExStart + //ExFor:Comment.StoryType + //ExFor:Footnote.StoryType + //ExFor:InlineStory.EnsureMinimum + //ExFor:InlineStory.Font + //ExFor:InlineStory.LastParagraph + //ExFor:InlineStory.ParentParagraph + //ExFor:InlineStory.StoryType + //ExFor:InlineStory.Tables + //ExSummary:Shows how to insert InlineStory nodes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + Footnote footnote = builder.insertFootnote(FootnoteType.FOOTNOTE, null); + + // Table nodes have an "EnsureMinimum()" method that makes sure the table has at least one cell. + Table table = new Table(doc); + table.ensureMinimum(); + + // We can place a table inside a footnote, which will make it appear at the referencing page's footer. + Assert.assertEquals(0, footnote.getTables().getCount()); + footnote.appendChild(table); + Assert.assertEquals(1, footnote.getTables().getCount()); + Assert.assertEquals(NodeType.TABLE, footnote.getLastChild().getNodeType()); + + // An InlineStory has an "EnsureMinimum()" method as well, but in this case, + // it makes sure the last child of the node is a paragraph, + // for us to be able to click and write text easily in Microsoft Word. + footnote.ensureMinimum(); + Assert.assertEquals(NodeType.PARAGRAPH, footnote.getLastChild().getNodeType()); + + // Edit the appearance of the anchor, which is the small superscript number + // in the main text that points to the footnote. + footnote.getFont().setName("Arial"); + footnote.getFont().setColor(msColor.getGreen()); + + // All inline story nodes have their respective story types. + Assert.assertEquals(StoryType.FOOTNOTES, footnote.getStoryType()); + + // A comment is another type of inline story. + Comment comment = (Comment)builder.getCurrentParagraph().appendChild(new Comment(doc, "John Doe", "J. D.", new Date)); + + // The parent paragraph of an inline story node will be the one from the main document body. + Assert.assertEquals(doc.getFirstSection().getBody().getFirstParagraph(), comment.getParentParagraph()); + + // However, the last paragraph is the one from the comment text contents, + // which will be outside the main document body in a speech bubble. + // A comment will not have any child nodes by default, + // so we can apply the EnsureMinimum() method to place a paragraph here as well. + Assert.assertNull(comment.getLastParagraph()); + comment.ensureMinimum(); + Assert.assertEquals(NodeType.PARAGRAPH, comment.getLastChild().getNodeType()); + + // Once we have a paragraph, we can move the builder to do it and write our comment. + builder.moveTo(comment.getLastParagraph()); + builder.write("My comment."); + + Assert.assertEquals(StoryType.COMMENTS, comment.getStoryType()); + + doc.save(getArtifactsDir() + "InlineStory.InsertInlineStoryNodes.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "InlineStory.InsertInlineStoryNodes.docx"); + + footnote = (Footnote)doc.getChild(NodeType.FOOTNOTE, 0, true); + + TestUtil.verifyFootnote(FootnoteType.FOOTNOTE, true, "", "", + (Footnote)doc.getChild(NodeType.FOOTNOTE, 0, true)); + Assert.assertEquals("Arial", footnote.getFont().getName()); + Assert.assertEquals(msColor.getGreen().getRGB(), footnote.getFont().getColor().getRGB()); + + comment = (Comment)doc.getChild(NodeType.COMMENT, 0, true); + + Assert.assertEquals("My comment.", comment.toString(SaveFormat.TEXT).trim()); + } + + @Test + public void deleteShapes() throws Exception + { + //ExStart + //ExFor:Story + //ExFor:Story.DeleteShapes + //ExFor:Story.StoryType + //ExFor:StoryType + //ExSummary:Shows how to remove all shapes from a node. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Use a DocumentBuilder to insert a shape. This is an inline shape, + // which has a parent Paragraph, which is a child node of the first section's Body. + builder.insertShape(ShapeType.CUBE, 100.0, 100.0); + + Assert.assertEquals(1, doc.getChildNodes(NodeType.SHAPE, true).getCount()); + + // We can delete all shapes from the child paragraphs of this Body. + Assert.assertEquals(StoryType.MAIN_TEXT, doc.getFirstSection().getBody().getStoryType()); + doc.getFirstSection().getBody().deleteShapes(); + + Assert.assertEquals(0, doc.getChildNodes(NodeType.SHAPE, true).getCount()); + //ExEnd + } + + @Test + public void updateActualReferenceMarks() throws Exception + { + //ExStart:UpdateActualReferenceMarks + //GistId:a775441ecb396eea917a2717cb9e8f8f + //ExFor:Document.UpdateActualReferenceMarks + //ExFor:Footnote.ActualReferenceMark + //ExSummary:Shows how to get actual footnote reference mark. + Document doc = new Document(getMyDir() + "Footnotes and endnotes.docx"); + + Footnote footnote = (Footnote)doc.getChild(NodeType.FOOTNOTE, 1, true); + doc.updateFields(); + doc.updateActualReferenceMarks(); + + Assert.assertEquals("1", footnote.getActualReferenceMark()); + //ExEnd:UpdateActualReferenceMarks + } + + @Test + public void endnoteSeparator() throws Exception + { + //ExStart:EndnoteSeparator + //GistId:e06aa7a168b57907a5598e823a22bf0a + //ExFor:DocumentBase.FootnoteSeparators + //ExFor:FootnoteSeparatorType + //ExSummary:Shows how to remove endnote separator. + Document doc = new Document(getMyDir() + "Footnotes and endnotes.docx"); + + FootnoteSeparator endnoteSeparator = doc.getFootnoteSeparators().getByFootnoteSeparatorType(FootnoteSeparatorType.ENDNOTE_SEPARATOR); + // Remove endnote separator. + endnoteSeparator.getFirstParagraph().getFirstChild().remove(); + //ExEnd:EndnoteSeparator + + doc.save(getArtifactsDir() + "InlineStory.EndnoteSeparator.docx"); + } + + @Test + public void footnoteSeparator() throws Exception + { + //ExStart:FootnoteSeparator + //GistId:e06aa7a168b57907a5598e823a22bf0a + //ExFor:DocumentBase.FootnoteSeparators + //ExFor:FootnoteSeparator + //ExFor:FootnoteSeparatorType + //ExFor:FootnoteSeparatorCollection + //ExFor:FootnoteSeparatorCollection.Item(FootnoteSeparatorType) + //ExSummary:Shows how to manage footnote separator format. + Document doc = new Document(getMyDir() + "Footnotes and endnotes.docx"); + + FootnoteSeparator footnoteSeparator = doc.getFootnoteSeparators().getByFootnoteSeparatorType(FootnoteSeparatorType.FOOTNOTE_SEPARATOR); + // Align footnote separator. + footnoteSeparator.getFirstParagraph().getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + //ExEnd:FootnoteSeparator + + doc.save(getArtifactsDir() + "InlineStory.FootnoteSeparator.docx"); + } +} + diff --git a/Examples/ApiExamples/JavaPorting/ExLayout.java b/Examples/ApiExamples/JavaPorting/ExLayout.java new file mode 100644 index 00000000..2b54173b --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExLayout.java @@ -0,0 +1,356 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.LayoutCollector; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.BreakType; +import com.aspose.words.NodeCollection; +import com.aspose.words.NodeType; +import com.aspose.words.Node; +import com.aspose.ms.System.msConsole; +import com.aspose.words.LayoutEnumerator; +import com.aspose.words.LayoutEntityType; +import com.aspose.ms.System.msString; +import com.aspose.ms.System.Drawing.RectangleF; +import com.aspose.words.IPageLayoutCallback; +import com.aspose.words.PageLayoutCallbackArgs; +import com.aspose.words.PageLayoutEvent; +import com.aspose.words.ImageSaveOptions; +import com.aspose.words.SaveFormat; +import com.aspose.words.PageSet; +import com.aspose.ms.System.IO.FileStream; +import com.aspose.ms.System.IO.FileMode; +import com.aspose.words.ContinuousSectionRestart; + + +@Test +class ExLayout !Test class should be public in Java to run, please fix .Net source! extends ApiExampleBase +{ + @Test + public void layoutCollector() throws Exception + { + //ExStart + //ExFor:LayoutCollector + //ExFor:LayoutCollector.#ctor(Document) + //ExFor:LayoutCollector.Clear + //ExFor:LayoutCollector.Document + //ExFor:LayoutCollector.GetEndPageIndex(Node) + //ExFor:LayoutCollector.GetEntity(Node) + //ExFor:LayoutCollector.GetNumPagesSpanned(Node) + //ExFor:LayoutCollector.GetStartPageIndex(Node) + //ExFor:LayoutEnumerator.Current + //ExSummary:Shows how to see the the ranges of pages that a node spans. + Document doc = new Document(); + LayoutCollector layoutCollector = new LayoutCollector(doc); + + // Call the "GetNumPagesSpanned" method to count how many pages the content of our document spans. + // Since the document is empty, that number of pages is currently zero. + Assert.assertEquals(doc, layoutCollector.getDocument()); + Assert.assertEquals(0, layoutCollector.getNumPagesSpanned(doc)); + + // Populate the document with 5 pages of content. + DocumentBuilder builder = new DocumentBuilder(doc); + builder.write("Section 1"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.insertBreak(BreakType.SECTION_BREAK_EVEN_PAGE); + builder.write("Section 2"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.insertBreak(BreakType.PAGE_BREAK); + + // Before the layout collector, we need to call the "UpdatePageLayout" method to give us + // an accurate figure for any layout-related metric, such as the page count. + Assert.assertEquals(0, layoutCollector.getNumPagesSpanned(doc)); + + layoutCollector.clear(); + doc.updatePageLayout(); + + Assert.assertEquals(5, layoutCollector.getNumPagesSpanned(doc)); + + // We can see the numbers of the start and end pages of any node and their overall page spans. + NodeCollection nodes = doc.getChildNodes(NodeType.ANY, true); + for (Node node : (Iterable) nodes) + { + System.out.println("-> NodeType.{node.NodeType}: "); + System.out.println("\tStarts on page {layoutCollector.GetStartPageIndex(node)}, ends on page {layoutCollector.GetEndPageIndex(node)}," + + $" spanning {layoutCollector.GetNumPagesSpanned(node)} pages."); + } + + // We can iterate over the layout entities using a LayoutEnumerator. + LayoutEnumerator layoutEnumerator = new LayoutEnumerator(doc); + + Assert.assertEquals(LayoutEntityType.PAGE, layoutEnumerator.getType()); + + // The LayoutEnumerator can traverse the collection of layout entities like a tree. + // We can also apply it to any node's corresponding layout entity. + layoutEnumerator.setCurrent(layoutCollector.getEntity(doc.getChild(NodeType.PARAGRAPH, 1, true))); + + Assert.assertEquals(LayoutEntityType.SPAN, layoutEnumerator.getType()); + Assert.assertEquals("¶", layoutEnumerator.getText()); + //ExEnd + } + + //ExStart + //ExFor:LayoutEntityType + //ExFor:LayoutEnumerator + //ExFor:LayoutEnumerator.#ctor(Document) + //ExFor:LayoutEnumerator.Document + //ExFor:LayoutEnumerator.Kind + //ExFor:LayoutEnumerator.MoveFirstChild + //ExFor:LayoutEnumerator.MoveLastChild + //ExFor:LayoutEnumerator.MoveNext + //ExFor:LayoutEnumerator.MoveNextLogical + //ExFor:LayoutEnumerator.MoveParent + //ExFor:LayoutEnumerator.MoveParent(LayoutEntityType) + //ExFor:LayoutEnumerator.MovePrevious + //ExFor:LayoutEnumerator.MovePreviousLogical + //ExFor:LayoutEnumerator.PageIndex + //ExFor:LayoutEnumerator.Rectangle + //ExFor:LayoutEnumerator.Reset + //ExFor:LayoutEnumerator.Text + //ExFor:LayoutEnumerator.Type + //ExSummary:Shows ways of traversing a document's layout entities. + @Test //ExSkip + public void layoutEnumerator() throws Exception + { + // Open a document that contains a variety of layout entities. + // Layout entities are pages, cells, rows, lines, and other objects included in the LayoutEntityType enum. + // Each layout entity has a rectangular space that it occupies in the document body. + Document doc = new Document(getMyDir() + "Layout entities.docx"); + + // Create an enumerator that can traverse these entities like a tree. + LayoutEnumerator layoutEnumerator = new LayoutEnumerator(doc); + + Assert.assertEquals(doc, layoutEnumerator.getDocument()); + + layoutEnumerator.moveParent(LayoutEntityType.PAGE); + + Assert.assertEquals(LayoutEntityType.PAGE, layoutEnumerator.getType()); + Assert.Throws(() => System.out.println(layoutEnumerator.getText())); + + // We can call this method to make sure that the enumerator will be at the first layout entity. + layoutEnumerator.reset(); + + // There are two orders that determine how the layout enumerator continues traversing layout entities + // when it encounters entities that span across multiple pages. + // 1 - In visual order: + // When moving through an entity's children that span multiple pages, + // page layout takes precedence, and we move to other child elements on this page and avoid the ones on the next. + System.out.println("Traversing from first to last, elements between pages separated:"); + traverseLayoutForward(layoutEnumerator, 1); + + // Our enumerator is now at the end of the collection. We can traverse the layout entities backwards to go back to the beginning. + System.out.println("Traversing from last to first, elements between pages separated:"); + traverseLayoutBackward(layoutEnumerator, 1); + + // 2 - In logical order: + // When moving through an entity's children that span multiple pages, + // the enumerator will move between pages to traverse all the child entities. + System.out.println("Traversing from first to last, elements between pages mixed:"); + traverseLayoutForwardLogical(layoutEnumerator, 1); + + System.out.println("Traversing from last to first, elements between pages mixed:"); + traverseLayoutBackwardLogical(layoutEnumerator, 1); + } + + /// + /// Enumerate through layoutEnumerator's layout entity collection front-to-back, + /// in a depth-first manner, and in the "Visual" order. + /// + private static void traverseLayoutForward(LayoutEnumerator layoutEnumerator, int depth) throws Exception + { + do + { + printCurrentEntity(layoutEnumerator, depth); + + if (layoutEnumerator.moveFirstChild()) + { + traverseLayoutForward(layoutEnumerator, depth + 1); + layoutEnumerator.moveParent(); + } + } while (layoutEnumerator.moveNext()); + } + + /// + /// Enumerate through layoutEnumerator's layout entity collection back-to-front, + /// in a depth-first manner, and in the "Visual" order. + /// + private static void traverseLayoutBackward(LayoutEnumerator layoutEnumerator, int depth) throws Exception + { + do + { + printCurrentEntity(layoutEnumerator, depth); + + if (layoutEnumerator.moveLastChild()) + { + traverseLayoutBackward(layoutEnumerator, depth + 1); + layoutEnumerator.moveParent(); + } + } while (layoutEnumerator.movePrevious()); + } + + /// + /// Enumerate through layoutEnumerator's layout entity collection front-to-back, + /// in a depth-first manner, and in the "Logical" order. + /// + private static void traverseLayoutForwardLogical(LayoutEnumerator layoutEnumerator, int depth) throws Exception + { + do + { + printCurrentEntity(layoutEnumerator, depth); + + if (layoutEnumerator.moveFirstChild()) + { + traverseLayoutForwardLogical(layoutEnumerator, depth + 1); + layoutEnumerator.moveParent(); + } + } while (layoutEnumerator.moveNextLogical()); + } + + /// + /// Enumerate through layoutEnumerator's layout entity collection back-to-front, + /// in a depth-first manner, and in the "Logical" order. + /// + private static void traverseLayoutBackwardLogical(LayoutEnumerator layoutEnumerator, int depth) throws Exception + { + do + { + printCurrentEntity(layoutEnumerator, depth); + + if (layoutEnumerator.moveLastChild()) + { + traverseLayoutBackwardLogical(layoutEnumerator, depth + 1); + layoutEnumerator.moveParent(); + } + } while (layoutEnumerator.movePreviousLogical()); + } + + /// + /// Print information about layoutEnumerator's current entity to the console, while indenting the text with tab characters + /// based on its depth relative to the root node that we provided in the constructor LayoutEnumerator instance. + /// The rectangle that we process at the end represents the area and location that the entity takes up in the document. + /// + private static void printCurrentEntity(LayoutEnumerator layoutEnumerator, int indent) throws Exception + { + String tabs = msString.newString('\t', indent); + + System.out.println(msString.equals(layoutEnumerator.getKind(), "") + ? $"{tabs}-> Entity type: {layoutEnumerator.Type}" + : $"{tabs}-> Entity type & kind: {layoutEnumerator.Type}, {layoutEnumerator.Kind}"); + + // Only spans can contain text. + if (layoutEnumerator.getType() == LayoutEntityType.SPAN) + System.out.println("{tabs} Span contents: \"{layoutEnumerator.Text}\""); + + RectangleF leRect = layoutEnumerator.getRectangleInternal(); + System.out.println("{tabs} Rectangle dimensions {leRect.Width}x{leRect.Height}, X={leRect.X} Y={leRect.Y}"); + System.out.println("{tabs} Page {layoutEnumerator.PageIndex}"); + } + //ExEnd + + //ExStart + //ExFor:IPageLayoutCallback + //ExFor:IPageLayoutCallback.Notify(PageLayoutCallbackArgs) + //ExFor:PageLayoutCallbackArgs + //ExFor:PageLayoutCallbackArgs.Event + //ExFor:PageLayoutCallbackArgs.Document + //ExFor:PageLayoutCallbackArgs.PageIndex + //ExFor:PageLayoutEvent + //ExFor:LayoutOptions.Callback + //ExSummary:Shows how to track layout changes with a layout callback. + @Test//ExSkip + public void pageLayoutCallback() throws Exception + { + Document doc = new Document(); + doc.getBuiltInDocumentProperties().setTitle("My Document"); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + doc.getLayoutOptions().setCallback(new RenderPageLayoutCallback()); + doc.updatePageLayout(); + + doc.save(getArtifactsDir() + "Layout.PageLayoutCallback.pdf"); + } + + /// + /// Notifies us when we save the document to a fixed page format + /// and renders a page that we perform a page reflow on to an image in the local file system. + /// + private static class RenderPageLayoutCallback implements IPageLayoutCallback + { + public void notify(PageLayoutCallbackArgs a) throws Exception + { + switch (a.getEvent()) + { + case PageLayoutEvent.PART_REFLOW_FINISHED: + notifyPartFinished(a); + break; + case PageLayoutEvent.CONVERSION_FINISHED: + notifyConversionFinished(a); + break; + } + } + + private void notifyPartFinished(PageLayoutCallbackArgs a) throws Exception + { + System.out.println("Part at page {a.PageIndex + 1} reflow."); + renderPage(a, a.getPageIndex()); + } + + private void notifyConversionFinished(PageLayoutCallbackArgs a) + { + System.out.println("Document \"{a.Document.BuiltInDocumentProperties.Title}\" converted to page format."); + } + + private void renderPage(PageLayoutCallbackArgs a, int pageIndex) throws Exception + { + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.PNG); { saveOptions.setPageSet(new PageSet(pageIndex)); } + + FileStream stream = + new FileStream(getArtifactsDir() + $"PageLayoutCallback.page-{pageIndex + 1} {++mNum}.png", + FileMode.CREATE); + try /*JAVA: was using*/ + { + a.getDocument().save(stream, saveOptions); + } + finally { if (stream != null) stream.close(); } + } + + private int mNum; + } + //ExEnd + + @Test + public void restartPageNumberingInContinuousSection() throws Exception + { + //ExStart + //ExFor:LayoutOptions.ContinuousSectionPageNumberingRestart + //ExFor:ContinuousSectionRestart + //ExSummary:Shows how to control page numbering in a continuous section. + Document doc = new Document(getMyDir() + "Continuous section page numbering.docx"); + + // By default Aspose.Words behavior matches the Microsoft Word 2019. + // If you need old Aspose.Words behavior, repetitive Microsoft Word 2016, use 'ContinuousSectionRestart.FromNewPageOnly'. + // Page numbering restarts only if there is no other content before the section on the page where the section starts, + // because of that the numbering will reset to 2 from the second page. + doc.getLayoutOptions().setContinuousSectionPageNumberingRestart(ContinuousSectionRestart.FROM_NEW_PAGE_ONLY); + doc.updatePageLayout(); + + doc.save(getArtifactsDir() + "Layout.RestartPageNumberingInContinuousSection.pdf"); + //ExEnd + } +} + diff --git a/Examples/ApiExamples/JavaPorting/ExLicense.java b/Examples/ApiExamples/JavaPorting/ExLicense.java new file mode 100644 index 00000000..ac711f61 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExLicense.java @@ -0,0 +1,72 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.ms.System.IO.Path; +import com.aspose.words.License; +import com.aspose.ms.System.IO.File; +import com.aspose.ms.System.IO.Stream; +import java.io.FileInputStream; + + +@Test +class ExLicense !Test class should be public in Java to run, please fix .Net source! extends ApiExampleBase +{ + @Test + public void licenseFromFileNoPath() throws Exception + { + //ExStart + //ExFor:License + //ExFor:License.#ctor + //ExFor:License.SetLicense(String) + //ExSummary:Shows how to initialize a license for Aspose.Words using a license file in the local file system. + + String testLicenseFileName = "Aspose.Total.NET.lic"; + + // Set the license for our Aspose.Words product by passing the local file system filename of a valid license file. + String licenseFileName = Path.combine(getLicenseDir(), testLicenseFileName); + + License license = new License(); + license.setLicense(licenseFileName); + + // Create a copy of our license file in the binaries folder of our application. + String licenseCopyFileName = Path.combine(getAssemblyDir(), testLicenseFileName); + File.copy(licenseFileName, licenseCopyFileName); + + // If we pass a file's name without a path, + // the SetLicense will search several local file system locations for this file. + // One of those locations will be the "bin" folder, which contains a copy of our license file. + license.setLicense(testLicenseFileName); + //ExEnd + + license.setLicense(""); + File.delete(licenseCopyFileName); + } + + @Test + public void licenseFromStream() throws Exception + { + //ExStart + //ExFor:License.SetLicense(Stream) + //ExSummary:Shows how to initialize a license for Aspose.Words from a stream. + String testLicenseFileName = "Aspose.Total.NET.lic"; + // Set the license for our Aspose.Words product by passing a stream for a valid license file in our local file system. + Stream myStream = new FileInputStream(Path.combine(getLicenseDir(), testLicenseFileName)); + try /*JAVA: was using*/ + { + License license = new License(); + license.setLicenseInternal(myStream); + } + finally { if (myStream != null) myStream.close(); } + //ExEnd + } +} + diff --git a/Examples/ApiExamples/JavaPorting/ExLists.java b/Examples/ApiExamples/JavaPorting/ExLists.java new file mode 100644 index 00000000..dd1f3be8 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExLists.java @@ -0,0 +1,1087 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.BreakType; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.NumberStyle; +import com.aspose.words.ListTemplate; +import com.aspose.words.List; +import com.aspose.words.StyleIdentifier; +import com.aspose.words.ListLevel; +import java.awt.Color; +import com.aspose.words.ListLevelAlignment; +import com.aspose.words.ListTrailingCharacter; +import com.aspose.words.Style; +import com.aspose.words.StyleType; +import com.aspose.words.NodeCollection; +import com.aspose.words.NodeType; +import com.aspose.words.Paragraph; +import com.aspose.ms.System.msConsole; +import com.aspose.words.ListCollection; +import com.aspose.words.SaveFormat; +import com.aspose.words.ListLabel; +import com.aspose.words.ParagraphCollection; + + +@Test +public class ExLists extends ApiExampleBase +{ + @Test + public void applyDefaultBulletsAndNumbers() throws Exception + { + //ExStart + //ExFor:DocumentBuilder.ListFormat + //ExFor:ListFormat.ApplyNumberDefault + //ExFor:ListFormat.ApplyBulletDefault + //ExFor:ListFormat.ListIndent + //ExFor:ListFormat.ListOutdent + //ExFor:ListFormat.RemoveNumbers + //ExFor:ListFormat.ListLevelNumber + //ExSummary:Shows how to create bulleted and numbered lists. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Aspose.Words main advantages are:"); + + // A list allows us to organize and decorate sets of paragraphs with prefix symbols and indents. + // We can create nested lists by increasing the indent level. + // We can begin and end a list by using a document builder's "ListFormat" property. + // Each paragraph that we add between a list's start and the end will become an item in the list. + // Below are two types of lists that we can create with a document builder. + // 1 - A bulleted list: + // This list will apply an indent and a bullet symbol ("•") before each paragraph. + builder.getListFormat().applyBulletDefault(); + builder.writeln("Great performance"); + builder.writeln("High reliability"); + builder.writeln("Quality code and working"); + builder.writeln("Wide variety of features"); + builder.writeln("Easy to understand API"); + + // End the bulleted list. + builder.getListFormat().removeNumbers(); + + builder.insertBreak(BreakType.PARAGRAPH_BREAK); + builder.writeln("Aspose.Words allows:"); + + // 2 - A numbered list: + // Numbered lists create a logical order for their paragraphs by numbering each item. + builder.getListFormat().applyNumberDefault(); + + // This paragraph is the first item. The first item of a numbered list will have a "1." as its list item symbol. + builder.writeln("Opening documents from different formats:"); + + Assert.assertEquals(0, builder.getListFormat().getListLevelNumber()); + + // Call the "ListIndent" method to increase the current list level, + // which will start a new self-contained list, with a deeper indent, at the current item of the first list level. + builder.getListFormat().listIndent(); + + Assert.assertEquals(1, builder.getListFormat().getListLevelNumber()); + + // These are the first three list items of the second list level, which will maintain a count + // independent of the count of the first list level. According to the current list format, + // they will have symbols of "a.", "b.", and "c.". + builder.writeln("DOC"); + builder.writeln("PDF"); + builder.writeln("HTML"); + + // Call the "ListOutdent" method to return to the previous list level. + builder.getListFormat().listOutdent(); + + Assert.assertEquals(0, builder.getListFormat().getListLevelNumber()); + + // These two paragraphs will continue the count of the first list level. + // These items will have symbols of "2.", and "3." + builder.writeln("Processing documents"); + builder.writeln("Saving documents in different formats:"); + + // If we increase the list level to a level that we have added items to previously, + // the nested list will be separate from the previous, and its numbering will start from the beginning. + // These list items will have symbols of "a.", "b.", "c.", "d.", and "e". + builder.getListFormat().listIndent(); + builder.writeln("DOC"); + builder.writeln("PDF"); + builder.writeln("HTML"); + builder.writeln("MHTML"); + builder.writeln("Plain text"); + + // Outdent the list level again. + builder.getListFormat().listOutdent(); + builder.writeln("Doing many other things!"); + + // End the numbered list. + builder.getListFormat().removeNumbers(); + + doc.save(getArtifactsDir() + "Lists.ApplyDefaultBulletsAndNumbers.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Lists.ApplyDefaultBulletsAndNumbers.docx"); + + TestUtil.verifyListLevel("\u0000.", 18.0d, NumberStyle.ARABIC, doc.getLists().get(1).getListLevels().get(0)); + TestUtil.verifyListLevel("\u0001.", 54.0d, NumberStyle.LOWERCASE_LETTER, doc.getLists().get(1).getListLevels().get(1)); + TestUtil.verifyListLevel("\uf0b7", 18.0d, NumberStyle.BULLET, doc.getLists().get(0).getListLevels().get(0)); + } + + @Test + public void specifyListLevel() throws Exception + { + //ExStart + //ExFor:ListCollection + //ExFor:List + //ExFor:ListFormat + //ExFor:ListFormat.IsListItem + //ExFor:ListFormat.ListLevelNumber + //ExFor:ListFormat.List + //ExFor:ListTemplate + //ExFor:DocumentBase.Lists + //ExFor:ListCollection.Add(ListTemplate) + //ExSummary:Shows how to work with list levels. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Assert.assertFalse(builder.getListFormat().isListItem()); + + // A list allows us to organize and decorate sets of paragraphs with prefix symbols and indents. + // We can create nested lists by increasing the indent level. + // We can begin and end a list by using a document builder's "ListFormat" property. + // Each paragraph that we add between a list's start and the end will become an item in the list. + // Below are two types of lists that we can create using a document builder. + // 1 - A numbered list: + // Numbered lists create a logical order for their paragraphs by numbering each item. + builder.getListFormat().setList(doc.getLists().add(ListTemplate.NUMBER_DEFAULT)); + + Assert.assertTrue(builder.getListFormat().isListItem()); + + // By setting the "ListLevelNumber" property, we can increase the list level + // to begin a self-contained sub-list at the current list item. + // The Microsoft Word list template called "NumberDefault" uses numbers to create list levels for the first list level. + // Deeper list levels use letters and lowercase Roman numerals. + for (int i = 0; i < 9; i++) + { + builder.getListFormat().setListLevelNumber(i); + builder.writeln("Level " + i); + } + + // 2 - A bulleted list: + // This list will apply an indent and a bullet symbol ("•") before each paragraph. + // Deeper levels of this list will use different symbols, such as "■" and "○". + builder.getListFormat().setList(doc.getLists().add(ListTemplate.BULLET_DEFAULT)); + + for (int i = 0; i < 9; i++) + { + builder.getListFormat().setListLevelNumber(i); + builder.writeln("Level " + i); + } + + // We can disable list formatting to not format any subsequent paragraphs as lists by un-setting the "List" flag. + builder.getListFormat().setList(null); + + Assert.assertFalse(builder.getListFormat().isListItem()); + + doc.save(getArtifactsDir() + "Lists.SpecifyListLevel.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Lists.SpecifyListLevel.docx"); + + TestUtil.verifyListLevel("\u0000.", 18.0d, NumberStyle.ARABIC, doc.getLists().get(0).getListLevels().get(0)); + } + + @Test + public void nestedLists() throws Exception + { + //ExStart + //ExFor:ListFormat.List + //ExFor:ParagraphFormat.ClearFormatting + //ExFor:ParagraphFormat.DropCapPosition + //ExFor:ParagraphFormat.IsListItem + //ExFor:Paragraph.IsListItem + //ExSummary:Shows how to nest a list inside another list. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // A list allows us to organize and decorate sets of paragraphs with prefix symbols and indents. + // We can create nested lists by increasing the indent level. + // We can begin and end a list by using a document builder's "ListFormat" property. + // Each paragraph that we add between a list's start and the end will become an item in the list. + // Create an outline list for the headings. + List outlineList = doc.getLists().add(ListTemplate.OUTLINE_NUMBERS); + builder.getListFormat().setList(outlineList); + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + builder.writeln("This is my Chapter 1"); + + // Create a numbered list. + List numberedList = doc.getLists().add(ListTemplate.NUMBER_DEFAULT); + builder.getListFormat().setList(numberedList); + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.NORMAL); + builder.writeln("Numbered list item 1."); + + // Every paragraph that comprises a list will have this flag. + Assert.assertTrue(builder.getCurrentParagraph().isListItem()); + Assert.assertTrue(builder.getParagraphFormat().isListItem()); + + // Create a bulleted list. + List bulletedList = doc.getLists().add(ListTemplate.BULLET_DEFAULT); + builder.getListFormat().setList(bulletedList); + builder.getParagraphFormat().setLeftIndent(72.0); + builder.writeln("Bulleted list item 1."); + builder.writeln("Bulleted list item 2."); + builder.getParagraphFormat().clearFormatting(); + + // Revert to the numbered list. + builder.getListFormat().setList(numberedList); + builder.writeln("Numbered list item 2."); + builder.writeln("Numbered list item 3."); + + // Revert to the outline list. + builder.getListFormat().setList(outlineList); + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + builder.writeln("This is my Chapter 2"); + + builder.getParagraphFormat().clearFormatting(); + + builder.getDocument().save(getArtifactsDir() + "Lists.NestedLists.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Lists.NestedLists.docx"); + + TestUtil.verifyListLevel("\u0000)", 0.0d, NumberStyle.ARABIC, doc.getLists().get(0).getListLevels().get(0)); + TestUtil.verifyListLevel("\u0000.", 18.0d, NumberStyle.ARABIC, doc.getLists().get(1).getListLevels().get(0)); + TestUtil.verifyListLevel("\uf0b7", 18.0d, NumberStyle.BULLET, doc.getLists().get(2).getListLevels().get(0)); + } + + @Test + public void createCustomList() throws Exception + { + //ExStart + //ExFor:List + //ExFor:List.ListLevels + //ExFor:ListFormat.ListLevel + //ExFor:ListLevelCollection + //ExFor:ListLevelCollection.Item + //ExFor:ListLevel + //ExFor:ListLevel.Alignment + //ExFor:ListLevel.Font + //ExFor:ListLevel.NumberStyle + //ExFor:ListLevel.StartAt + //ExFor:ListLevel.TrailingCharacter + //ExFor:ListLevelAlignment + //ExFor:NumberStyle + //ExFor:ListTrailingCharacter + //ExFor:ListLevel.NumberFormat + //ExFor:ListLevel.NumberPosition + //ExFor:ListLevel.TextPosition + //ExFor:ListLevel.TabPosition + //ExSummary:Shows how to apply custom list formatting to paragraphs when using DocumentBuilder. + Document doc = new Document(); + + // A list allows us to organize and decorate sets of paragraphs with prefix symbols and indents. + // We can create nested lists by increasing the indent level. + // We can begin and end a list by using a document builder's "ListFormat" property. + // Each paragraph that we add between a list's start and the end will become an item in the list. + // Create a list from a Microsoft Word template, and customize the first two of its list levels. + List docList = doc.getLists().add(ListTemplate.NUMBER_DEFAULT); + + ListLevel listLevel = docList.getListLevels().get(0); + listLevel.getFont().setColor(Color.RED); + listLevel.getFont().setSize(24.0); + listLevel.setNumberStyle(NumberStyle.ORDINAL_TEXT); + listLevel.setStartAt(21); + listLevel.setNumberFormat("\u0000"); + + listLevel.setNumberPosition(-36); + listLevel.setTextPosition(144.0); + listLevel.setTabPosition(144.0); + + listLevel = docList.getListLevels().get(1); + listLevel.setAlignment(ListLevelAlignment.RIGHT); + listLevel.setNumberStyle(NumberStyle.BULLET); + listLevel.getFont().setName("Wingdings"); + listLevel.getFont().setColor(Color.BLUE); + listLevel.getFont().setSize(24.0); + + // This NumberFormat value will create star-shaped bullet list symbols. + listLevel.setNumberFormat("\uf0af"); + listLevel.setTrailingCharacter(ListTrailingCharacter.SPACE); + listLevel.setNumberPosition(144.0); + + // Create paragraphs and apply both list levels of our custom list formatting to them. + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getListFormat().setList(docList); + builder.writeln("The quick brown fox..."); + builder.writeln("The quick brown fox..."); + + builder.getListFormat().listIndent(); + builder.writeln("jumped over the lazy dog."); + builder.writeln("jumped over the lazy dog."); + + builder.getListFormat().listOutdent(); + builder.writeln("The quick brown fox..."); + + builder.getListFormat().removeNumbers(); + + builder.getDocument().save(getArtifactsDir() + "Lists.CreateCustomList.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Lists.CreateCustomList.docx"); + + listLevel = doc.getLists().get(0).getListLevels().get(0); + + TestUtil.verifyListLevel("\u0000", -36.0d, NumberStyle.ORDINAL_TEXT, listLevel); + Assert.assertEquals(Color.RED.getRGB(), listLevel.getFont().getColor().getRGB()); + Assert.assertEquals(24.0d, listLevel.getFont().getSize()); + Assert.assertEquals(21, listLevel.getStartAt()); + + listLevel = doc.getLists().get(0).getListLevels().get(1); + + TestUtil.verifyListLevel("\uf0af", 144.0d, NumberStyle.BULLET, listLevel); + Assert.assertEquals(Color.BLUE.getRGB(), listLevel.getFont().getColor().getRGB()); + Assert.assertEquals(24.0d, listLevel.getFont().getSize()); + Assert.assertEquals(1, listLevel.getStartAt()); + Assert.assertEquals(ListTrailingCharacter.SPACE, listLevel.getTrailingCharacter()); + } + + @Test + public void restartNumberingUsingListCopy() throws Exception + { + //ExStart + //ExFor:List + //ExFor:ListCollection + //ExFor:ListCollection.Add(ListTemplate) + //ExFor:ListCollection.AddCopy(List) + //ExFor:ListLevel.StartAt + //ExFor:ListTemplate + //ExSummary:Shows how to restart numbering in a list by copying a list. + Document doc = new Document(); + + // A list allows us to organize and decorate sets of paragraphs with prefix symbols and indents. + // We can create nested lists by increasing the indent level. + // We can begin and end a list by using a document builder's "ListFormat" property. + // Each paragraph that we add between a list's start and the end will become an item in the list. + // Create a list from a Microsoft Word template, and customize its first list level. + List list1 = doc.getLists().add(ListTemplate.NUMBER_ARABIC_PARENTHESIS); + list1.getListLevels().get(0).getFont().setColor(Color.RED); + list1.getListLevels().get(0).setAlignment(ListLevelAlignment.RIGHT); + + // Apply our list to some paragraphs. + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("List 1 starts below:"); + builder.getListFormat().setList(list1); + builder.writeln("Item 1"); + builder.writeln("Item 2"); + builder.getListFormat().removeNumbers(); + + // We can add a copy of an existing list to the document's list collection + // to create a similar list without making changes to the original. + List list2 = doc.getLists().addCopy(list1); + list2.getListLevels().get(0).getFont().setColor(Color.BLUE); + list2.getListLevels().get(0).setStartAt(10); + + // Apply the second list to new paragraphs. + builder.writeln("List 2 starts below:"); + builder.getListFormat().setList(list2); + builder.writeln("Item 1"); + builder.writeln("Item 2"); + builder.getListFormat().removeNumbers(); + + doc.save(getArtifactsDir() + "Lists.RestartNumberingUsingListCopy.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Lists.RestartNumberingUsingListCopy.docx"); + + list1 = doc.getLists().get(0); + TestUtil.verifyListLevel("\u0000)", 18.0d, NumberStyle.ARABIC, list1.getListLevels().get(0)); + Assert.assertEquals(Color.RED.getRGB(), list1.getListLevels().get(0).getFont().getColor().getRGB()); + Assert.assertEquals(10.0d, list1.getListLevels().get(0).getFont().getSize()); + Assert.assertEquals(1, list1.getListLevels().get(0).getStartAt()); + + list2 = doc.getLists().get(1); + TestUtil.verifyListLevel("\u0000)", 18.0d, NumberStyle.ARABIC, list2.getListLevels().get(0)); + Assert.assertEquals(Color.BLUE.getRGB(), list2.getListLevels().get(0).getFont().getColor().getRGB()); + Assert.assertEquals(10.0d, list2.getListLevels().get(0).getFont().getSize()); + Assert.assertEquals(10, list2.getListLevels().get(0).getStartAt()); + } + + @Test + public void createAndUseListStyle() throws Exception + { + //ExStart + //ExFor:StyleCollection.Add(StyleType,String) + //ExFor:Style.List + //ExFor:StyleType + //ExFor:List.IsListStyleDefinition + //ExFor:List.IsListStyleReference + //ExFor:List.IsMultiLevel + //ExFor:List.Style + //ExFor:ListLevelCollection + //ExFor:ListLevelCollection.Count + //ExFor:ListLevelCollection.Item + //ExFor:ListCollection.Add(Style) + //ExSummary:Shows how to create a list style and use it in a document. + Document doc = new Document(); + + // A list allows us to organize and decorate sets of paragraphs with prefix symbols and indents. + // We can create nested lists by increasing the indent level. + // We can begin and end a list by using a document builder's "ListFormat" property. + // Each paragraph that we add between a list's start and the end will become an item in the list. + // We can contain an entire List object within a style. + Style listStyle = doc.getStyles().add(StyleType.LIST, "MyListStyle"); + + List list1 = listStyle.getList(); + + Assert.assertTrue(list1.isListStyleDefinition()); + Assert.assertFalse(list1.isListStyleReference()); + Assert.assertTrue(list1.isMultiLevel()); + Assert.assertEquals(listStyle, list1.getStyle()); + + // Change the appearance of all list levels in our list. + for (ListLevel level : list1.getListLevels()) + { + level.getFont().setName("Verdana"); + level.getFont().setColor(Color.BLUE); + level.getFont().setBold(true); + } + + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Using list style first time:"); + + // Create another list from a list within a style. + List list2 = doc.getLists().add(listStyle); + + Assert.assertFalse(list2.isListStyleDefinition()); + Assert.assertTrue(list2.isListStyleReference()); + Assert.assertEquals(listStyle, list2.getStyle()); + + // Add some list items that our list will format. + builder.getListFormat().setList(list2); + builder.writeln("Item 1"); + builder.writeln("Item 2"); + builder.getListFormat().removeNumbers(); + + builder.writeln("Using list style second time:"); + + // Create and apply another list based on the list style. + List list3 = doc.getLists().add(listStyle); + builder.getListFormat().setList(list3); + builder.writeln("Item 1"); + builder.writeln("Item 2"); + builder.getListFormat().removeNumbers(); + + builder.getDocument().save(getArtifactsDir() + "Lists.CreateAndUseListStyle.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Lists.CreateAndUseListStyle.docx"); + + list1 = doc.getLists().get(0); + + TestUtil.verifyListLevel("\u0000.", 18.0d, NumberStyle.ARABIC, list1.getListLevels().get(0)); + Assert.assertTrue(list1.isListStyleDefinition()); + Assert.assertFalse(list1.isListStyleReference()); + Assert.assertTrue(list1.isMultiLevel()); + Assert.assertEquals(Color.BLUE.getRGB(), list1.getListLevels().get(0).getFont().getColor().getRGB()); + Assert.assertEquals("Verdana", list1.getListLevels().get(0).getFont().getName()); + Assert.assertTrue(list1.getListLevels().get(0).getFont().getBold()); + + list2 = doc.getLists().get(1); + + TestUtil.verifyListLevel("\u0000.", 18.0d, NumberStyle.ARABIC, list2.getListLevels().get(0)); + Assert.assertFalse(list2.isListStyleDefinition()); + Assert.assertTrue(list2.isListStyleReference()); + Assert.assertTrue(list2.isMultiLevel()); + + list3 = doc.getLists().get(2); + + TestUtil.verifyListLevel("\u0000.", 18.0d, NumberStyle.ARABIC, list3.getListLevels().get(0)); + Assert.assertFalse(list3.isListStyleDefinition()); + Assert.assertTrue(list3.isListStyleReference()); + Assert.assertTrue(list3.isMultiLevel()); + } + + @Test + public void detectBulletedParagraphs() throws Exception + { + //ExStart + //ExFor:Paragraph.ListFormat + //ExFor:ListFormat.IsListItem + //ExFor:CompositeNode.GetText + //ExFor:List.ListId + //ExSummary:Shows how to output all paragraphs in a document that are list items. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getListFormat().applyNumberDefault(); + builder.writeln("Numbered list item 1"); + builder.writeln("Numbered list item 2"); + builder.writeln("Numbered list item 3"); + builder.getListFormat().removeNumbers(); + + builder.getListFormat().applyBulletDefault(); + builder.writeln("Bulleted list item 1"); + builder.writeln("Bulleted list item 2"); + builder.writeln("Bulleted list item 3"); + builder.getListFormat().removeNumbers(); + + NodeCollection paras = doc.getChildNodes(NodeType.PARAGRAPH, true); + + for (Paragraph para : paras.OfType().Where(p => p.ListFormat.IsListItem).ToList() !!Autoporter error: Undefined expression type ) + { + System.out.println("This paragraph belongs to list ID# {para.ListFormat.List.ListId}, number style \"{para.ListFormat.ListLevel.NumberStyle}\""); + System.out.println("\t\"{para.GetText().Trim()}\""); + } + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + paras = doc.getChildNodes(NodeType.PARAGRAPH, true); + + Assert.That(paras.Count(n => ((Paragraph)n).ListFormat.IsListItem), assertEquals(6, ); + } + + @Test + public void removeBulletsFromParagraphs() throws Exception + { + //ExStart + //ExFor:ListFormat.RemoveNumbers + //ExSummary:Shows how to remove list formatting from all paragraphs in the main text of a section. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getListFormat().applyNumberDefault(); + builder.writeln("Numbered list item 1"); + builder.writeln("Numbered list item 2"); + builder.writeln("Numbered list item 3"); + builder.getListFormat().removeNumbers(); + + NodeCollection paras = doc.getChildNodes(NodeType.PARAGRAPH, true); + Assert.That(paras.Count(n => ((Paragraph)n).ListFormat.IsListItem), assertEquals(3, ); + + for (Paragraph paragraph : (Iterable) paras) + paragraph.getListFormat().removeNumbers(); + + Assert.That(paras.Count(n => ((Paragraph)n).ListFormat.IsListItem), assertEquals(0, ); + //ExEnd + } + + @Test + public void applyExistingListToParagraphs() throws Exception + { + //ExStart + //ExFor:ListCollection.Item(Int32) + //ExSummary:Shows how to apply list formatting of an existing list to a collection of paragraphs. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Paragraph 1"); + builder.writeln("Paragraph 2"); + builder.write("Paragraph 3"); + + NodeCollection paras = doc.getChildNodes(NodeType.PARAGRAPH, true); + + Assert.That(paras.Count(n => ((Paragraph)n).ListFormat.IsListItem), assertEquals(0, ); + + doc.getLists().add(ListTemplate.NUMBER_DEFAULT); + List docList = doc.getLists().get(0); + + for (Paragraph paragraph : paras.OfType() !!Autoporter error: Undefined expression type ) + { + paragraph.getListFormat().setList(docList); + paragraph.getListFormat().setListLevelNumber(2); + } + + Assert.That(paras.Count(n => ((Paragraph)n).ListFormat.IsListItem), assertEquals(3, ); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + paras = doc.getChildNodes(NodeType.PARAGRAPH, true); + + Assert.That(paras.Count(n => ((Paragraph)n).ListFormat.IsListItem), assertEquals(3, ); + Assert.That(paras.Count(n => ((Paragraph)n).ListFormat.ListLevelNumber == 2), assertEquals(3, ); + } + + @Test + public void applyNewListToParagraphs() throws Exception + { + //ExStart + //ExFor:ListCollection.Add(ListTemplate) + //ExSummary:Shows how to create a list by applying a new list format to a collection of paragraphs. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Paragraph 1"); + builder.writeln("Paragraph 2"); + builder.write("Paragraph 3"); + + NodeCollection paras = doc.getChildNodes(NodeType.PARAGRAPH, true); + + Assert.That(paras.Count(n => ((Paragraph)n).ListFormat.IsListItem), assertEquals(0, ); + + List docList = doc.getLists().add(ListTemplate.NUMBER_UPPERCASE_LETTER_DOT); + + for (Paragraph paragraph : paras.OfType() !!Autoporter error: Undefined expression type ) + { + paragraph.getListFormat().setList(docList); + paragraph.getListFormat().setListLevelNumber(1); + } + + Assert.That(paras.Count(n => ((Paragraph)n).ListFormat.IsListItem), assertEquals(3, ); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + paras = doc.getChildNodes(NodeType.PARAGRAPH, true); + + Assert.That(paras.Count(n => ((Paragraph)n).ListFormat.IsListItem), assertEquals(3, ); + Assert.That(paras.Count(n => ((Paragraph)n).ListFormat.ListLevelNumber == 1), assertEquals(3, ); + } + + //ExStart + //ExFor:ListTemplate + //ExSummary:Shows how to create a document that contains all outline headings list templates. + @Test //ExSkip + public void outlineHeadingTemplates() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + List docList = doc.getLists().add(ListTemplate.OUTLINE_HEADINGS_ARTICLE_SECTION); + addOutlineHeadingParagraphs(builder, docList, "Aspose.Words Outline - \"Article Section\""); + + docList = doc.getLists().add(ListTemplate.OUTLINE_HEADINGS_LEGAL); + addOutlineHeadingParagraphs(builder, docList, "Aspose.Words Outline - \"Legal\""); + + builder.insertBreak(BreakType.PAGE_BREAK); + + docList = doc.getLists().add(ListTemplate.OUTLINE_HEADINGS_NUMBERS); + addOutlineHeadingParagraphs(builder, docList, "Aspose.Words Outline - \"Numbers\""); + + docList = doc.getLists().add(ListTemplate.OUTLINE_HEADINGS_CHAPTER); + addOutlineHeadingParagraphs(builder, docList, "Aspose.Words Outline - \"Chapters\""); + + doc.save(getArtifactsDir() + "Lists.OutlineHeadingTemplates.docx"); + testOutlineHeadingTemplates(new Document(getArtifactsDir() + "Lists.OutlineHeadingTemplates.docx")); //ExSkip + } + + private static void addOutlineHeadingParagraphs(DocumentBuilder builder, List docList, String title) + { + builder.getParagraphFormat().clearFormatting(); + builder.writeln(title); + + for (int i = 0; i < 9; i++) + { + builder.getListFormat().setList(docList); + builder.getListFormat().setListLevelNumber(i); + + String styleName = "Heading " + (i + 1); + builder.getParagraphFormat().setStyleName(styleName); + builder.writeln(styleName); + } + + builder.getListFormat().removeNumbers(); + } + //ExEnd + + private void testOutlineHeadingTemplates(Document doc) + { + List docList = doc.getLists().get(0); // Article section list template. + + TestUtil.verifyListLevel("Article \u0000.", 0.0d, NumberStyle.UPPERCASE_ROMAN, docList.getListLevels().get(0)); + TestUtil.verifyListLevel("Section \u0000.\u0001", 0.0d, NumberStyle.LEADING_ZERO, docList.getListLevels().get(1)); + TestUtil.verifyListLevel("(\u0002)", 14.4d, NumberStyle.LOWERCASE_LETTER, docList.getListLevels().get(2)); + TestUtil.verifyListLevel("(\u0003)", 36.0d, NumberStyle.LOWERCASE_ROMAN, docList.getListLevels().get(3)); + TestUtil.verifyListLevel("\u0004)", 28.8d, NumberStyle.ARABIC, docList.getListLevels().get(4)); + TestUtil.verifyListLevel("\u0005)", 36.0d, NumberStyle.LOWERCASE_LETTER, docList.getListLevels().get(5)); + TestUtil.verifyListLevel("\u0006)", 50.4d, NumberStyle.LOWERCASE_ROMAN, docList.getListLevels().get(6)); + TestUtil.verifyListLevel("\u0007.", 50.4d, NumberStyle.LOWERCASE_LETTER, docList.getListLevels().get(7)); + TestUtil.verifyListLevel("\b.", 72.0d, NumberStyle.LOWERCASE_ROMAN, docList.getListLevels().get(8)); + + docList = doc.getLists().get(1); // Legal list template. + + TestUtil.verifyListLevel("\u0000", 0.0d, NumberStyle.ARABIC, docList.getListLevels().get(0)); + TestUtil.verifyListLevel("\u0000.\u0001", 0.0d, NumberStyle.ARABIC, docList.getListLevels().get(1)); + TestUtil.verifyListLevel("\u0000.\u0001.\u0002", 0.0d, NumberStyle.ARABIC, docList.getListLevels().get(2)); + TestUtil.verifyListLevel("\u0000.\u0001.\u0002.\u0003", 0.0d, NumberStyle.ARABIC, docList.getListLevels().get(3)); + TestUtil.verifyListLevel("\u0000.\u0001.\u0002.\u0003.\u0004", 0.0d, NumberStyle.ARABIC, docList.getListLevels().get(4)); + TestUtil.verifyListLevel("\u0000.\u0001.\u0002.\u0003.\u0004.\u0005", 0.0d, NumberStyle.ARABIC, docList.getListLevels().get(5)); + TestUtil.verifyListLevel("\u0000.\u0001.\u0002.\u0003.\u0004.\u0005.\u0006", 0.0d, NumberStyle.ARABIC, docList.getListLevels().get(6)); + TestUtil.verifyListLevel("\u0000.\u0001.\u0002.\u0003.\u0004.\u0005.\u0006.\u0007", 0.0d, NumberStyle.ARABIC, docList.getListLevels().get(7)); + TestUtil.verifyListLevel("\u0000.\u0001.\u0002.\u0003.\u0004.\u0005.\u0006.\u0007.\b", 0.0d, NumberStyle.ARABIC, docList.getListLevels().get(8)); + + docList = doc.getLists().get(2); // Numbered list template. + + TestUtil.verifyListLevel("\u0000.", 0.0d, NumberStyle.UPPERCASE_ROMAN, docList.getListLevels().get(0)); + TestUtil.verifyListLevel("\u0001.", 36.0d, NumberStyle.UPPERCASE_LETTER, docList.getListLevels().get(1)); + TestUtil.verifyListLevel("\u0002.", 72.0d, NumberStyle.ARABIC, docList.getListLevels().get(2)); + TestUtil.verifyListLevel("\u0003)", 108.0d, NumberStyle.LOWERCASE_LETTER, docList.getListLevels().get(3)); + TestUtil.verifyListLevel("(\u0004)", 144.0d, NumberStyle.ARABIC, docList.getListLevels().get(4)); + TestUtil.verifyListLevel("(\u0005)", 180.0d, NumberStyle.LOWERCASE_LETTER, docList.getListLevels().get(5)); + TestUtil.verifyListLevel("(\u0006)", 216.0d, NumberStyle.LOWERCASE_ROMAN, docList.getListLevels().get(6)); + TestUtil.verifyListLevel("(\u0007)", 252.0d, NumberStyle.LOWERCASE_LETTER, docList.getListLevels().get(7)); + TestUtil.verifyListLevel("(\b)", 288.0d, NumberStyle.LOWERCASE_ROMAN, docList.getListLevels().get(8)); + + docList = doc.getLists().get(3); // Chapter list template. + + TestUtil.verifyListLevel("Chapter \u0000", 0.0d, NumberStyle.ARABIC, docList.getListLevels().get(0)); + TestUtil.verifyListLevel("", 0.0d, NumberStyle.NONE, docList.getListLevels().get(1)); + TestUtil.verifyListLevel("", 0.0d, NumberStyle.NONE, docList.getListLevels().get(2)); + TestUtil.verifyListLevel("", 0.0d, NumberStyle.NONE, docList.getListLevels().get(3)); + TestUtil.verifyListLevel("", 0.0d, NumberStyle.NONE, docList.getListLevels().get(4)); + TestUtil.verifyListLevel("", 0.0d, NumberStyle.NONE, docList.getListLevels().get(5)); + TestUtil.verifyListLevel("", 0.0d, NumberStyle.NONE, docList.getListLevels().get(6)); + TestUtil.verifyListLevel("", 0.0d, NumberStyle.NONE, docList.getListLevels().get(7)); + TestUtil.verifyListLevel("", 0.0d, NumberStyle.NONE, docList.getListLevels().get(8)); + } + + //ExStart + //ExFor:ListCollection + //ExFor:ListCollection.AddCopy(List) + //ExSummary:Shows how to create a document with a sample of all the lists from another document. + @Test //ExSkip + public void printOutAllLists() throws Exception + { + Document srcDoc = new Document(getMyDir() + "Rendering.docx"); + + Document dstDoc = new Document(); + DocumentBuilder builder = new DocumentBuilder(dstDoc); + + for (List srcList : srcDoc.getLists()) + { + List dstList = dstDoc.getLists().addCopy(srcList); + addListSample(builder, dstList); + } + + dstDoc.save(getArtifactsDir() + "Lists.PrintOutAllLists.docx"); + testPrintOutAllLists(srcDoc, new Document(getArtifactsDir() + "Lists.PrintOutAllLists.docx")); //ExSkip + } + + private static void addListSample(DocumentBuilder builder, List docList) + { + builder.writeln("Sample formatting of list with ListId:" + docList.getListId()); + builder.getListFormat().setList(docList); + for (int i = 0; i < docList.getListLevels().getCount(); i++) + { + builder.getListFormat().setListLevelNumber(i); + builder.writeln("Level " + i); + } + + builder.getListFormat().removeNumbers(); + builder.writeln(); + } + //ExEnd + + private void testPrintOutAllLists(Document listSourceDoc, Document outDoc) + { + for (List docList : outDoc.getLists()) + for (int i = 0; i < docList.getListLevels().getCount(); i++) + { + ListLevel expectedListLevel = listSourceDoc.getLists().First(l => l.ListId == docList.ListId).ListLevels[i]; + Assert.assertEquals(expectedListLevel.getNumberFormat(), docList.getListLevels().get(i).getNumberFormat()); + Assert.assertEquals(expectedListLevel.getNumberPosition(), docList.getListLevels().get(i).getNumberPosition()); + Assert.assertEquals(expectedListLevel.getNumberStyle(), docList.getListLevels().get(i).getNumberStyle()); + } + } + + @Test + public void listDocument() throws Exception + { + //ExStart + //ExFor:ListCollection.Document + //ExFor:ListCollection.Count + //ExFor:ListCollection.Item(Int32) + //ExFor:ListCollection.GetListByListId + //ExFor:List.Document + //ExFor:List.ListId + //ExSummary:Shows how to verify owner document properties of lists. + Document doc = new Document(); + + ListCollection lists = doc.getLists(); + Assert.assertEquals(doc, lists.getDocument()); + + List docList = lists.add(ListTemplate.BULLET_DEFAULT); + Assert.assertEquals(doc, docList.getDocument()); + + System.out.println("Current list count: " + lists.getCount()); + System.out.println("Is the first document list: " + (lists.get(0).equals(docList))); + System.out.println("ListId: " + docList.getListId()); + System.out.println("List is the same by ListId: " + (lists.getListByListId(1).equals(docList))); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + lists = doc.getLists(); + + Assert.assertEquals(doc, lists.getDocument()); + Assert.assertEquals(1, lists.getCount()); + Assert.assertEquals(1, lists.get(0).getListId()); + Assert.assertEquals(lists.get(0), lists.getListByListId(1)); + } + + @Test + public void createListRestartAfterHigher() throws Exception + { + //ExStart + //ExFor:ListLevel.NumberStyle + //ExFor:ListLevel.NumberFormat + //ExFor:ListLevel.IsLegal + //ExFor:ListLevel.RestartAfterLevel + //ExFor:ListLevel.LinkedStyle + //ExSummary:Shows advances ways of customizing list labels. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // A list allows us to organize and decorate sets of paragraphs with prefix symbols and indents. + // We can create nested lists by increasing the indent level. + // We can begin and end a list by using a document builder's "ListFormat" property. + // Each paragraph that we add between a list's start and the end will become an item in the list. + List docList = doc.getLists().add(ListTemplate.NUMBER_DEFAULT); + + // Level 1 labels will be formatted according to the "Heading 1" paragraph style and will have a prefix. + // These will look like "Appendix A", "Appendix B"... + docList.getListLevels().get(0).setNumberFormat("Appendix \u0000"); + docList.getListLevels().get(0).setNumberStyle(NumberStyle.UPPERCASE_LETTER); + docList.getListLevels().get(0).setLinkedStyle(doc.getStyles().get("Heading 1")); + + // Level 2 labels will display the current numbers of the first and the second list levels and have leading zeroes. + // If the first list level is at 1, then the list labels from these will look like "Section (1.01)", "Section (1.02)"... + docList.getListLevels().get(1).setNumberFormat("Section (\u0000.\u0001)"); + docList.getListLevels().get(1).setNumberStyle(NumberStyle.LEADING_ZERO); + + // Note that the higher-level uses UppercaseLetter numbering. + // We can set the "IsLegal" property to use Arabic numbers for the higher list levels. + docList.getListLevels().get(1).isLegal(true); + docList.getListLevels().get(1).setRestartAfterLevel(0); + + // Level 3 labels will be upper case Roman numerals with a prefix and a suffix and will restart at each List level 1 item. + // These list labels will look like "-I-", "-II-"... + docList.getListLevels().get(2).setNumberFormat("-\u0002-"); + docList.getListLevels().get(2).setNumberStyle(NumberStyle.UPPERCASE_ROMAN); + docList.getListLevels().get(2).setRestartAfterLevel(1); + + // Make labels of all list levels bold. + for (ListLevel level : docList.getListLevels()) + level.getFont().setBold(true); + + // Apply list formatting to the current paragraph. + builder.getListFormat().setList(docList); + + // Create list items that will display all three of our list levels. + for (int n = 0; n < 2; n++) + { + for (int i = 0; i < 3; i++) + { + builder.getListFormat().setListLevelNumber(i); + builder.writeln("Level " + i); + } + } + + builder.getListFormat().removeNumbers(); + + doc.save(getArtifactsDir() + "Lists.CreateListRestartAfterHigher.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Lists.CreateListRestartAfterHigher.docx"); + + ListLevel listLevel = doc.getLists().get(0).getListLevels().get(0); + + TestUtil.verifyListLevel("Appendix \u0000", 18.0d, NumberStyle.UPPERCASE_LETTER, listLevel); + Assert.assertFalse(listLevel.isLegal()); + Assert.assertEquals(-1, listLevel.getRestartAfterLevel()); + Assert.assertEquals("Heading 1", listLevel.getLinkedStyle().getName()); + + listLevel = doc.getLists().get(0).getListLevels().get(1); + + TestUtil.verifyListLevel("Section (\u0000.\u0001)", 54.0d, NumberStyle.LEADING_ZERO, listLevel); + Assert.assertTrue(listLevel.isLegal()); + Assert.assertEquals(0, listLevel.getRestartAfterLevel()); + Assert.assertNull(listLevel.getLinkedStyle()); + } + + @Test + public void getListLabels() throws Exception + { + //ExStart + //ExFor:Document.UpdateListLabels() + //ExFor:Node.ToString(SaveFormat) + //ExFor:ListLabel + //ExFor:Paragraph.ListLabel + //ExFor:ListLabel.LabelValue + //ExFor:ListLabel.LabelString + //ExSummary:Shows how to extract the list labels of all paragraphs that are list items. + Document doc = new Document(getMyDir() + "Rendering.docx"); + doc.updateListLabels(); + + NodeCollection paras = doc.getChildNodes(NodeType.PARAGRAPH, true); + + // Find if we have the paragraph list. In our document, our list uses plain Arabic numbers, + // which start at three and ends at six. + for (Paragraph paragraph : paras.OfType().Where(p => p.ListFormat.IsListItem).ToList() !!Autoporter error: Undefined expression type ) + { + System.out.println("List item paragraph #{paras.IndexOf(paragraph)}"); + + // This is the text we get when getting when we output this node to text format. + // This text output will omit list labels. Trim any paragraph formatting characters. + String paragraphText = paragraph.toString(SaveFormat.TEXT).trim(); + System.out.println("\tExported Text: {paragraphText}"); + + ListLabel label = paragraph.getListLabel(); + + // This gets the position of the paragraph in the current level of the list. If we have a list with multiple levels, + // this will tell us what position it is on that level. + System.out.println("\tNumerical Id: {label.LabelValue}"); + + // Combine them together to include the list label with the text in the output. + System.out.println("\tList label combined with text: {label.LabelString} {paragraphText}"); + } + //ExEnd + + Assert.That(paras.OfType().Count(p => p.ListFormat.IsListItem), assertEquals(10, ); + } + + @Test (groups = "IgnoreOnJenkins") + public void createPictureBullet() throws Exception + { + //ExStart + //ExFor:ListLevel.CreatePictureBullet + //ExFor:ListLevel.DeletePictureBullet + //ExSummary:Shows how to set a custom image icon for list item labels. + Document doc = new Document(); + + List docList = doc.getLists().add(ListTemplate.BULLET_CIRCLE); + + // Create a picture bullet for the current list level, and set an image from a local file system + // as the icon that the bullets for this list level will display. + docList.getListLevels().get(0).createPictureBullet(); + docList.getListLevels().get(0).getImageData().setImage(getImageDir() + "Logo icon.ico"); + + Assert.assertTrue(docList.getListLevels().get(0).getImageData().hasImage()); + + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getListFormat().setList(docList); + builder.writeln("Hello world!"); + builder.write("Hello again!"); + + doc.save(getArtifactsDir() + "Lists.CreatePictureBullet.docx"); + + docList.getListLevels().get(0).deletePictureBullet(); + + Assert.assertNull(docList.getListLevels().get(0).getImageData()); + //ExEnd + + doc = new Document(getArtifactsDir() + "Lists.CreatePictureBullet.docx"); + + Assert.assertTrue(doc.getLists().get(0).getListLevels().get(0).getImageData().hasImage()); + } + + @Test + public void getCustomNumberStyleFormat() throws Exception + { + //ExStart + //ExFor:ListLevel.CustomNumberStyleFormat + //ExFor:ListLevel.GetEffectiveValue(Int32, NumberStyle, String) + //ExSummary:Shows how to get the format for a list with the custom number style. + Document doc = new Document(getMyDir() + "List with leading zero.docx"); + + ListLevel listLevel = doc.getFirstSection().getBody().getParagraphs().get(0).getListFormat().getListLevel(); + + String customNumberStyleFormat = ""; + + if (listLevel.getNumberStyle() == NumberStyle.CUSTOM) + customNumberStyleFormat = listLevel.getCustomNumberStyleFormat(); + + Assert.assertEquals("001, 002, 003, ...", customNumberStyleFormat); + + // We can get value for the specified index of the list item. + Assert.assertEquals("iv", ListLevel.getEffectiveValue(4, NumberStyle.LOWERCASE_ROMAN, null)); + Assert.assertEquals("005", ListLevel.getEffectiveValue(5, NumberStyle.CUSTOM, customNumberStyleFormat)); + //ExEnd + + Assert.Throws( + () => ListLevel.getEffectiveValue(5, NumberStyle.LOWERCASE_ROMAN, customNumberStyleFormat)); + Assert.Throws(() => ListLevel.getEffectiveValue(5, NumberStyle.CUSTOM, null)); + Assert.Throws(() => ListLevel.getEffectiveValue(5, NumberStyle.CUSTOM, "....")); + } + + @Test + public void hasSameTemplate() throws Exception + { + //ExStart + //ExFor:List.HasSameTemplate(List) + //ExSummary:Shows how to define lists with the same ListDefId. + Document doc = new Document(getMyDir() + "Different lists.docx"); + + Assert.assertTrue(doc.getLists().get(0).hasSameTemplate(doc.getLists().get(1))); + Assert.assertFalse(doc.getLists().get(1).hasSameTemplate(doc.getLists().get(2))); + //ExEnd + } + + @Test + public void setCustomNumberStyleFormat() throws Exception + { + //ExStart:SetCustomNumberStyleFormat + //GistId:ac8ba4eb35f3fbb8066b48c999da63b0 + //ExFor:ListLevel.CustomNumberStyleFormat + //ExSummary:Shows how to set customer number style format. + Document doc = new Document(getMyDir() + "List with leading zero.docx"); + + doc.updateListLabels(); + + ParagraphCollection paras = doc.getFirstSection().getBody().getParagraphs(); + Assert.assertEquals("001.", paras.get(0).getListLabel().getLabelString()); + Assert.assertEquals("0001.", paras.get(1).getListLabel().getLabelString()); + Assert.assertEquals("0002.", paras.get(2).getListLabel().getLabelString()); + + paras.get(1).getListFormat().getListLevel().setCustomNumberStyleFormat("001, 002, 003, ..."); + + doc.updateListLabels(); + + Assert.assertEquals("001.", paras.get(0).getListLabel().getLabelString()); + Assert.assertEquals("001.", paras.get(1).getListLabel().getLabelString()); + Assert.assertEquals("002.", paras.get(2).getListLabel().getLabelString()); + //ExEnd:SetCustomNumberStyleFormat + } + + @Test + public void addSingleLevelList() throws Exception + { + //ExStart:AddSingleLevelList + //GistId:95fdae949cefbf2ce485acc95cccc495 + //ExFor:ListCollection.AddSingleLevelList(ListTemplate) + //ExSummary:Shows how to create a new single level list based on the predefined template. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + ListCollection listCollection = doc.getLists(); + + // Creates the bulleted list from BulletCircle template. + List bulletedList = listCollection.addSingleLevelList(ListTemplate.BULLET_CIRCLE); + + // Writes the bulleted list to the resulting document. + builder.writeln("Bulleted list starts below:"); + builder.getListFormat().setList(bulletedList); + builder.writeln("Item 1"); + builder.writeln("Item 2"); + builder.getListFormat().removeNumbers(); + + // Creates the numbered list from NumberUppercaseLetterDot template. + List numberedList = listCollection.addSingleLevelList(ListTemplate.NUMBER_UPPERCASE_LETTER_DOT); + + // Writes the numbered list to the resulting document. + builder.writeln("Numbered list starts below:"); + builder.getListFormat().setList(numberedList); + builder.writeln("Item 1"); + builder.writeln("Item 2"); + + doc.save(getArtifactsDir() + "Lists.AddSingleLevelList.docx"); + //ExEnd:AddSingleLevelList + } +} diff --git a/Examples/ApiExamples/JavaPorting/ExLoadOptions.java b/Examples/ApiExamples/JavaPorting/ExLoadOptions.java new file mode 100644 index 00000000..eae8d066 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExLoadOptions.java @@ -0,0 +1,464 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.LoadOptions; +import com.aspose.words.Document; +import com.aspose.words.IResourceLoadingCallback; +import com.aspose.words.ResourceLoadingAction; +import com.aspose.words.ResourceLoadingArgs; +import com.aspose.words.ResourceType; +import com.aspose.ms.System.msConsole; +import java.awt.image.BufferedImage; +import javax.imageio.ImageIO; +import org.testng.Assert; +import com.aspose.words.NodeType; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.ms.System.Text.Encoding; +import com.aspose.words.SaveFormat; +import com.aspose.words.FontSettings; +import com.aspose.words.MsWordVersion; +import java.util.ArrayList; +import com.aspose.words.WarningInfo; +import com.aspose.words.IWarningCallback; +import com.aspose.words.WarningType; +import com.aspose.words.WarningSource; +import com.aspose.ms.System.IO.Directory; +import com.aspose.words.EditingLanguage; +import com.aspose.words.Shape; +import com.aspose.words.ShapeType; +import com.aspose.words.ImageType; +import com.aspose.words.FileFormatInfo; +import com.aspose.words.FileFormatUtil; +import com.aspose.words.LoadFormat; +import com.aspose.words.IDocumentLoadingCallback; +import java.util.Date; +import com.aspose.ms.System.DateTime; +import com.aspose.words.DocumentLoadingArgs; +import com.aspose.words.DocumentRecoveryMode; +import org.testng.annotations.DataProvider; + + +@Test +public class ExLoadOptions extends ApiExampleBase +{ + //ExStart + //ExFor:LoadOptions.ResourceLoadingCallback + //ExSummary:Shows how to handle external resources when loading Html documents. + @Test //ExSkip + public void loadOptionsCallback() throws Exception + { + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setResourceLoadingCallback(new HtmlLinkedResourceLoadingCallback()); + + // When we load the document, our callback will handle linked resources such as CSS stylesheets and images. + Document doc = new Document(getMyDir() + "Images.html", loadOptions); + doc.save(getArtifactsDir() + "LoadOptions.LoadOptionsCallback.pdf"); + } + + /// + /// Prints the filenames of all external stylesheets and substitutes all images of a loaded html document. + /// + private static class HtmlLinkedResourceLoadingCallback implements IResourceLoadingCallback + { + public /*ResourceLoadingAction*/int resourceLoading(ResourceLoadingArgs args) + { + switch (args.getResourceType()) + { + case ResourceType.CSS_STYLE_SHEET: + System.out.println("External CSS Stylesheet found upon loading: {args.OriginalUri}"); + return ResourceLoadingAction.DEFAULT; + case ResourceType.IMAGE: + System.out.println("External Image found upon loading: {args.OriginalUri}"); + + final String NEW_IMAGE_FILENAME = "Logo.jpg"; + System.out.println("\tImage will be substituted with: {newImageFilename}"); + + BufferedImage newImage = ImageIO.read(getImageDir() + NEW_IMAGE_FILENAME); + + ImageConverter converter = new ImageConverter(); + byte[] imageBytes = (byte[])converter.ConvertTo(newImage, byte[].class); + args.setData(imageBytes); + + return ResourceLoadingAction.USER_PROVIDED; + } + + return ResourceLoadingAction.DEFAULT; + } + } + //ExEnd + + @Test (dataProvider = "convertShapeToOfficeMathDataProvider") + public void convertShapeToOfficeMath(boolean isConvertShapeToOfficeMath) throws Exception + { + //ExStart + //ExFor:LoadOptions.ConvertShapeToOfficeMath + //ExSummary:Shows how to convert EquationXML shapes to Office Math objects. + LoadOptions loadOptions = new LoadOptions(); + + // Use this flag to specify whether to convert the shapes with EquationXML attributes + // to Office Math objects and then load the document. + loadOptions.setConvertShapeToOfficeMath(isConvertShapeToOfficeMath); + + Document doc = new Document(getMyDir() + "Math shapes.docx", loadOptions); + + if (isConvertShapeToOfficeMath) + { + Assert.assertEquals(16, doc.getChildNodes(NodeType.SHAPE, true).getCount()); + Assert.assertEquals(34, doc.getChildNodes(NodeType.OFFICE_MATH, true).getCount()); + } + else + { + Assert.assertEquals(24, doc.getChildNodes(NodeType.SHAPE, true).getCount()); + Assert.assertEquals(0, doc.getChildNodes(NodeType.OFFICE_MATH, true).getCount()); + } + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "convertShapeToOfficeMathDataProvider") + public static Object[][] convertShapeToOfficeMathDataProvider() throws Exception + { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test + public void setEncoding() throws Exception + { + //ExStart + //ExFor:LoadOptions.Encoding + //ExSummary:Shows how to set the encoding with which to open a document. + LoadOptions loadOptions = new LoadOptions(); + { + loadOptions.setEncoding(Encoding.getASCII()); + } + + // Load the document while passing the LoadOptions object, then verify the document's contents. + Document doc = new Document(getMyDir() + "English text.txt", loadOptions); + + Assert.assertTrue(doc.toString(SaveFormat.TEXT).contains("This is a sample text in English.")); + //ExEnd + } + + @Test + public void fontSettings() throws Exception + { + //ExStart + //ExFor:LoadOptions.FontSettings + //ExSummary:Shows how to apply font substitution settings while loading a document. + // Create a FontSettings object that will substitute the "Times New Roman" font + // with the font "Arvo" from our "MyFonts" folder. + FontSettings fontSettings = new FontSettings(); + fontSettings.setFontsFolder(getFontsDir(), false); + fontSettings.getSubstitutionSettings().getTableSubstitution().addSubstitutes("Times New Roman", "Arvo"); + + // Set that FontSettings object as a property of a newly created LoadOptions object. + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setFontSettings(fontSettings); + + // Load the document, then render it as a PDF with the font substitution. + Document doc = new Document(getMyDir() + "Document.docx", loadOptions); + + doc.save(getArtifactsDir() + "LoadOptions.FontSettings.pdf"); + //ExEnd + } + + @Test + public void loadOptionsMswVersion() throws Exception + { + //ExStart + //ExFor:LoadOptions.MswVersion + //ExSummary:Shows how to emulate the loading procedure of a specific Microsoft Word version during document loading. + // By default, Aspose.Words load documents according to Microsoft Word 2019 specification. + LoadOptions loadOptions = new LoadOptions(); + + Assert.assertEquals(MsWordVersion.WORD_2019, loadOptions.getMswVersion()); + + // This document is missing the default paragraph formatting style. + // This default style will be regenerated when we load the document either with Microsoft Word or Aspose.Words. + loadOptions.setMswVersion(MsWordVersion.WORD_2007); + Document doc = new Document(getMyDir() + "Document.docx", loadOptions); + + // The style's line spacing will have this value when loaded by Microsoft Word 2007 specification. + Assert.assertEquals(12.95d, 0.01d, doc.getStyles().getDefaultParagraphFormat().getLineSpacing()); + //ExEnd + } + + //ExStart + //ExFor:LoadOptions.WarningCallback + //ExSummary:Shows how to print and store warnings that occur during document loading. + @Test //ExSkip + public void loadOptionsWarningCallback() throws Exception + { + // Create a new LoadOptions object and set its WarningCallback attribute + // as an instance of our IWarningCallback implementation. + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setWarningCallback(new DocumentLoadingWarningCallback()); + + // Our callback will print all warnings that come up during the load operation. + Document doc = new Document(getMyDir() + "Document.docx", loadOptions); + + ArrayList warnings = ((DocumentLoadingWarningCallback)loadOptions.getWarningCallback()).getWarnings(); + Assert.assertEquals(3, warnings.size()); + testLoadOptionsWarningCallback(warnings); //ExSkip + } + + /// + /// IWarningCallback that prints warnings and their details as they arise during document loading. + /// + private static class DocumentLoadingWarningCallback implements IWarningCallback + { + public void warning(WarningInfo info) + { + System.out.println("Warning: {info.WarningType}"); + System.out.println("\tSource: {info.Source}"); + System.out.println("\tDescription: {info.Description}"); + mWarnings.add(info); + } + + public ArrayList getWarnings() + { + return mWarnings; + } + + private /*final*/ ArrayList mWarnings = new ArrayList(); + } + //ExEnd + + private static void testLoadOptionsWarningCallback(ArrayList warnings) + { + Assert.assertEquals(WarningType.UNEXPECTED_CONTENT, warnings.get(0).getWarningType()); + Assert.assertEquals(WarningSource.DOCX, warnings.get(0).getSource()); + Assert.assertEquals("3F01", warnings.get(0).getDescription()); + + Assert.assertEquals(WarningType.MINOR_FORMATTING_LOSS, warnings.get(1).getWarningType()); + Assert.assertEquals(WarningSource.DOCX, warnings.get(1).getSource()); + Assert.assertEquals("Import of element 'shapedefaults' is not supported in Docx format by Aspose.Words.", warnings.get(1).getDescription()); + + Assert.assertEquals(WarningType.MINOR_FORMATTING_LOSS, warnings.get(2).getWarningType()); + Assert.assertEquals(WarningSource.DOCX, warnings.get(2).getSource()); + Assert.assertEquals("Import of element 'extraClrSchemeLst' is not supported in Docx format by Aspose.Words.", warnings.get(2).getDescription()); + } + + @Test + public void tempFolder() throws Exception + { + //ExStart + //ExFor:LoadOptions.TempFolder + //ExSummary:Shows how to use the hard drive instead of memory when loading a document. + // When we load a document, various elements are temporarily stored in memory as the save operation occurs. + // We can use this option to use a temporary folder in the local file system instead, + // which will reduce our application's memory overhead. + LoadOptions options = new LoadOptions(); + options.setTempFolder(getArtifactsDir() + "TempFiles"); + + // The specified temporary folder must exist in the local file system before the load operation. + Directory.createDirectory(options.getTempFolder()); + + Document doc = new Document(getMyDir() + "Document.docx", options); + + // The folder will persist with no residual contents from the load operation. + Assert.assertEquals(0, Directory.getFiles(options.getTempFolder()).length); + //ExEnd + } + + @Test + public void addEditingLanguage() throws Exception + { + //ExStart + //ExFor:LanguagePreferences + //ExFor:LanguagePreferences.AddEditingLanguage(EditingLanguage) + //ExFor:LoadOptions.LanguagePreferences + //ExFor:EditingLanguage + //ExSummary:Shows how to apply language preferences when loading a document. + LoadOptions loadOptions = new LoadOptions(); + loadOptions.getLanguagePreferences().addEditingLanguage(EditingLanguage.JAPANESE); + + Document doc = new Document(getMyDir() + "No default editing language.docx", loadOptions); + + int localeIdFarEast = doc.getStyles().getDefaultFont().getLocaleIdFarEast(); + System.out.println(localeIdFarEast == (int)EditingLanguage.JAPANESE + ? "The document either has no any FarEast language set in defaults or it was set to Japanese originally." + : "The document default FarEast language was set to another than Japanese language originally, so it is not overridden."); + //ExEnd + + Assert.assertEquals((int)EditingLanguage.JAPANESE, doc.getStyles().getDefaultFont().getLocaleIdFarEast()); + + doc = new Document(getMyDir() + "No default editing language.docx"); + + Assert.assertEquals((int)EditingLanguage.ENGLISH_US, doc.getStyles().getDefaultFont().getLocaleIdFarEast()); + } + + @Test + public void setEditingLanguageAsDefault() throws Exception + { + //ExStart + //ExFor:LanguagePreferences.DefaultEditingLanguage + //ExSummary:Shows how set a default language when loading a document. + LoadOptions loadOptions = new LoadOptions(); + loadOptions.getLanguagePreferences().setDefaultEditingLanguage(EditingLanguage.RUSSIAN); + + Document doc = new Document(getMyDir() + "No default editing language.docx", loadOptions); + + int localeId = doc.getStyles().getDefaultFont().getLocaleId(); + System.out.println(localeId == (int)EditingLanguage.RUSSIAN + ? "The document either has no any language set in defaults or it was set to Russian originally." + : "The document default language was set to another than Russian language originally, so it is not overridden."); + //ExEnd + + Assert.assertEquals((int)EditingLanguage.RUSSIAN, doc.getStyles().getDefaultFont().getLocaleId()); + + doc = new Document(getMyDir() + "No default editing language.docx"); + + Assert.assertEquals((int)EditingLanguage.ENGLISH_US, doc.getStyles().getDefaultFont().getLocaleId()); + } + + @Test + public void convertMetafilesToPng() throws Exception + { + //ExStart + //ExFor:LoadOptions.ConvertMetafilesToPng + //ExSummary:Shows how to convert WMF/EMF to PNG during loading document. + Document doc = new Document(); + + Shape shape = new Shape(doc, ShapeType.IMAGE); + shape.getImageData().setImage(getImageDir() + "Windows MetaFile.wmf"); + shape.setWidth(100.0); + shape.setHeight(100.0); + + doc.getFirstSection().getBody().getFirstParagraph().appendChild(shape); + + doc.save(getArtifactsDir() + "Image.CreateImageDirectly.docx"); + + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(1600, 1600, ImageType.WMF, shape); + + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setConvertMetafilesToPng(true); + + doc = new Document(getArtifactsDir() + "Image.CreateImageDirectly.docx", loadOptions); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(1666, 1666, ImageType.PNG, shape); + //ExEnd + } + + @Test + public void openChmFile() throws Exception + { + FileFormatInfo info = FileFormatUtil.detectFileFormat(getMyDir() + "HTML help.chm"); + Assert.assertEquals(info.getLoadFormat(), LoadFormat.CHM); + + LoadOptions loadOptions = new LoadOptions(); { loadOptions.setEncoding(Encoding.getEncoding("windows-1251")); } + + Document doc = new Document(getMyDir() + "HTML help.chm", loadOptions); + } + + //ExStart + //ExFor:LoadOptions.ProgressCallback + //ExFor:IDocumentLoadingCallback + //ExFor:IDocumentLoadingCallback.Notify + //ExFor:DocumentLoadingArgs + //ExFor:DocumentLoadingArgs.EstimatedProgress + //ExSummary:Shows how to notify the user if document loading exceeded expected loading time. + @Test//ExSkip + public void progressCallback() throws Exception + { + LoadingProgressCallback progressCallback = new LoadingProgressCallback(); + + LoadOptions loadOptions = new LoadOptions(); { loadOptions.setProgressCallback(progressCallback); } + + try + { + Document doc = new Document(getMyDir() + "Big document.docx", loadOptions); + } + catch (IllegalStateException exception) + { + System.out.println(exception.getMessage()); + + // Handle loading duration issue. + } + } + + /// + /// Cancel a document loading after the "MaxDuration" seconds. + /// + public static class LoadingProgressCallback implements IDocumentLoadingCallback + { + /// + /// Ctr. + /// + public LoadingProgressCallback() + { + mLoadingStartedAt = new Date; + } + + /// + /// Callback method which called during document loading. + /// + /// Loading arguments. + public void notify(DocumentLoadingArgs args) + { + DateTime canceledAt = new Date; + double ellapsedSeconds = (DateTime.subtract(canceledAt, mLoadingStartedAt)).getTotalSeconds(); + + if (ellapsedSeconds > MAX_DURATION) + throw new IllegalStateException($"EstimatedProgress = {args.EstimatedProgress}; CanceledAt = {canceledAt}"); + } + + /// + /// Date and time when document loading is started. + /// + private /*final*/ DateTime mLoadingStartedAt; + + /// + /// Maximum allowed duration in sec. + /// + private static final double MAX_DURATION = 0.5; + } + //ExEnd + + @Test + public void ignoreOleData() throws Exception + { + //ExStart + //ExFor:LoadOptions.IgnoreOleData + //ExSummary:Shows how to ingore OLE data while loading. + // Ignoring OLE data may reduce memory consumption and increase performance + // without data lost in a case when destination format does not support OLE objects. + LoadOptions loadOptions = new LoadOptions(); { loadOptions.setIgnoreOleData(true); } + Document doc = new Document(getMyDir() + "OLE objects.docx", loadOptions); + + doc.save(getArtifactsDir() + "LoadOptions.IgnoreOleData.docx"); + //ExEnd + } + + @Test + public void recoveryMode() throws Exception + { + //ExStart:RecoveryMode + //GistId:045648ef22da6b384ebcf0344717bfb5 + //ExFor:LoadOptions.RecoveryMode + //ExFor:DocumentRecoveryMode + //ExSummary:Shows how to try to recover a document if errors occurred during loading. + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setRecoveryMode(DocumentRecoveryMode.TRY_RECOVER); + + Document doc = new Document(getMyDir() + "Corrupted footnotes.docx", loadOptions); + //ExEnd:RecoveryMode + } +} + diff --git a/Examples/ApiExamples/JavaPorting/ExLowCode.java b/Examples/ApiExamples/JavaPorting/ExLowCode.java new file mode 100644 index 00000000..36ed3868 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExLowCode.java @@ -0,0 +1,2748 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import com.aspose.ms.java.collections.StringSwitchMap; +import org.testng.annotations.Test; +import com.aspose.words.Merger; +import com.aspose.words.OoxmlSaveOptions; +import com.aspose.words.MergeFormatMode; +import com.aspose.words.SaveFormat; +import com.aspose.words.LoadOptions; +import com.aspose.words.Document; +import com.aspose.words.MergerContext; +import com.aspose.ms.System.IO.FileStream; +import com.aspose.ms.System.IO.FileMode; +import com.aspose.ms.System.IO.FileAccess; +import com.aspose.words.DocumentBuilder; +import java.awt.Color; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.Converter; +import com.aspose.words.ConverterContext; +import com.aspose.words.ImageSaveOptions; +import java.util.ArrayList; +import com.aspose.ms.System.IO.Stream; +import com.aspose.words.PageSet; +import com.aspose.words.PdfSaveOptions; +import com.aspose.words.HtmlFixedSaveOptions; +import com.aspose.words.XpsSaveOptions; +import com.aspose.words.SaveOptions; +import java.io.FileInputStream; +import com.aspose.ms.System.IO.File; +import com.aspose.ms.System.IO.MemoryStream; +import com.aspose.ms.System.Text.RegularExpressions.Regex; +import com.aspose.ms.System.IO.Directory; +import com.aspose.ms.System.msConsole; +import com.aspose.words.Comparer; +import com.aspose.ms.System.DateTime; +import com.aspose.words.CompareOptions; +import com.aspose.words.ComparerContext; +import com.aspose.words.MailMerger; +import com.aspose.words.MailMergeOptions; +import com.aspose.words.MailMergerContext; +import com.aspose.words.net.System.Data.DataTable; +import com.aspose.words.net.System.Data.DataRow; +import com.aspose.words.net.System.Data.DataSet; +import com.aspose.words.FindReplaceOptions; +import com.aspose.words.Replacer; +import com.aspose.words.ReplacerContext; +import com.aspose.words.ReportBuilder; +import com.aspose.words.ReportBuilderOptions; +import com.aspose.words.ReportBuildOptions; +import com.aspose.words.ReportBuilderContext; +import com.aspose.ms.System.Collections.msDictionary; +import com.aspose.words.Splitter; +import com.aspose.words.SplitOptions; +import com.aspose.words.SplitCriteria; +import com.aspose.words.SplitterContext; +import com.aspose.words.Watermarker; +import com.aspose.words.TextWatermarkOptions; +import com.aspose.words.WatermarkerContext; +import com.aspose.words.ImageWatermarkOptions; +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import org.testng.annotations.DataProvider; + + +@Test +public class ExLowCode extends ApiExampleBase +{ + @Test + public void mergeDocuments() throws Exception + { + //ExStart + //ExFor:Merger.Merge(String, String[]) + //ExFor:Merger.Merge(String[], MergeFormatMode) + //ExFor:Merger.Merge(String[], LoadOptions[], MergeFormatMode) + //ExFor:Merger.Merge(String, String[], SaveOptions, MergeFormatMode) + //ExFor:Merger.Merge(String, String[], SaveFormat, MergeFormatMode) + //ExFor:Merger.Merge(String, String[], LoadOptions[], SaveOptions, MergeFormatMode) + //ExFor:LowCode.MergeFormatMode + //ExFor:LowCode.Merger + //ExSummary:Shows how to merge documents into a single output document. + //There is a several ways to merge documents: + String inputDoc1 = getMyDir() + "Big document.docx"; + String inputDoc2 = getMyDir() + "Tables.docx"; + + Merger.merge(getArtifactsDir() + "LowCode.MergeDocument.1.docx", new String[] { inputDoc1, inputDoc2 }); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setPassword("Aspose.Words"); } + Merger.merge(getArtifactsDir() + "LowCode.MergeDocument.2.docx", new String[] { inputDoc1, inputDoc2 }, saveOptions, MergeFormatMode.KEEP_SOURCE_FORMATTING); + + Merger.merge(getArtifactsDir() + "LowCode.MergeDocument.3.pdf", new String[] { inputDoc1, inputDoc2 }, SaveFormat.PDF, MergeFormatMode.KEEP_SOURCE_LAYOUT); + + LoadOptions firstLoadOptions = new LoadOptions(); { firstLoadOptions.setIgnoreOleData(true); } + LoadOptions secondLoadOptions = new LoadOptions(); { secondLoadOptions.setIgnoreOleData(false); } + Merger.merge(getArtifactsDir() + "LowCode.MergeDocument.4.docx", new String[] { inputDoc1, inputDoc2 }, new LoadOptions[] { firstLoadOptions, secondLoadOptions }, saveOptions, MergeFormatMode.KEEP_SOURCE_FORMATTING); + + Document doc = Merger.merge(new String[] { inputDoc1, inputDoc2 }, MergeFormatMode.MERGE_FORMATTING); + doc.save(getArtifactsDir() + "LowCode.MergeDocument.5.docx"); + + doc = Merger.merge(new String[] { inputDoc1, inputDoc2 }, new LoadOptions[] { firstLoadOptions, secondLoadOptions }, MergeFormatMode.MERGE_FORMATTING); + doc.save(getArtifactsDir() + "LowCode.MergeDocument.6.docx"); + //ExEnd + } + + @Test + public void mergeContextDocuments() throws Exception + { + //ExStart:MergeContextDocuments + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Processor + //ExFor:Processor.From(String, LoadOptions) + //ExFor:Processor.To(String, SaveOptions) + //ExFor:Processor.To(String, SaveFormat) + //ExFor:Processor.Execute + //ExFor:Merger.Create(MergerContext) + //ExFor:MergerContext + //ExSummary:Shows how to merge documents into a single output document using context. + //There is a several ways to merge documents: + String inputDoc1 = getMyDir() + "Big document.docx"; + String inputDoc2 = getMyDir() + "Tables.docx"; + + Merger.create(new MergerContext(); { .setMergeFormatMode(MergeFormatMode.KEEP_SOURCE_FORMATTING); }) + .from(inputDoc1) + .from(inputDoc2) + .to(getArtifactsDir() + "LowCode.MergeContextDocuments.1.docx") + .execute(); + + LoadOptions firstLoadOptions = new LoadOptions(); { firstLoadOptions.setIgnoreOleData(true); } + LoadOptions secondLoadOptions = new LoadOptions(); { secondLoadOptions.setIgnoreOleData(false); } + Merger.create(new MergerContext(); { .setMergeFormatMode(MergeFormatMode.KEEP_SOURCE_FORMATTING); }) + .from(inputDoc1, firstLoadOptions) + .from(inputDoc2, secondLoadOptions) + .to(getArtifactsDir() + "LowCode.MergeContextDocuments.2.docx", SaveFormat.DOCX) + .execute(); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setPassword("Aspose.Words"); } + Merger.create(new MergerContext(); { .setMergeFormatMode(MergeFormatMode.KEEP_SOURCE_FORMATTING); }) + .from(inputDoc1) + .from(inputDoc2) + .to(getArtifactsDir() + "LowCode.MergeContextDocuments.3.docx", saveOptions) + .execute(); + //ExEnd:MergeContextDocuments + } + + @Test + public void mergeStreamDocument() throws Exception + { + //ExStart + //ExFor:Merger.Merge(Stream[], MergeFormatMode) + //ExFor:Merger.Merge(Stream[], LoadOptions[], MergeFormatMode) + //ExFor:Merger.Merge(Stream, Stream[], SaveOptions, MergeFormatMode) + //ExFor:Merger.Merge(Stream, Stream[], LoadOptions[], SaveOptions, MergeFormatMode) + //ExFor:Merger.Merge(Stream, Stream[], SaveFormat) + //ExSummary:Shows how to merge documents from stream into a single output document. + //There is a several ways to merge documents from stream: + FileStream firstStreamIn = new FileStream(getMyDir() + "Big document.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + FileStream secondStreamIn = new FileStream(getMyDir() + "Tables.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setPassword("Aspose.Words"); } + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.MergeStreamDocument.1.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Merger.mergeInternal(streamOut, new FileStream[] { firstStreamIn, secondStreamIn }, saveOptions, MergeFormatMode.KEEP_SOURCE_FORMATTING); + } + finally { if (streamOut != null) streamOut.close(); } + + FileStream streamOut1 = new FileStream(getArtifactsDir() + "LowCode.MergeStreamDocument.2.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Merger.mergeInternal(streamOut1, new FileStream[] { firstStreamIn, secondStreamIn }, SaveFormat.DOCX); + } + finally { if (streamOut1 != null) streamOut1.close(); } + + LoadOptions firstLoadOptions = new LoadOptions(); { firstLoadOptions.setIgnoreOleData(true); } + LoadOptions secondLoadOptions = new LoadOptions(); { secondLoadOptions.setIgnoreOleData(false); } + FileStream streamOut2 = new FileStream(getArtifactsDir() + "LowCode.MergeStreamDocument.3.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Merger.mergeInternal(streamOut2, new FileStream[] { firstStreamIn, secondStreamIn }, new LoadOptions[] { firstLoadOptions, secondLoadOptions }, saveOptions, MergeFormatMode.KEEP_SOURCE_FORMATTING); + } + finally { if (streamOut2 != null) streamOut2.close(); } + + Document firstDoc = Merger.mergeInternal(new FileStream[] { firstStreamIn, secondStreamIn }, MergeFormatMode.MERGE_FORMATTING); + firstDoc.save(getArtifactsDir() + "LowCode.MergeStreamDocument.4.docx"); + + Document secondDoc = Merger.mergeInternal(new FileStream[] { firstStreamIn, secondStreamIn }, new LoadOptions[] { firstLoadOptions, secondLoadOptions }, MergeFormatMode.MERGE_FORMATTING); + secondDoc.save(getArtifactsDir() + "LowCode.MergeStreamDocument.5.docx"); + } + finally { if (secondStreamIn != null) secondStreamIn.close(); } + } + finally { if (firstStreamIn != null) firstStreamIn.close(); } + //ExEnd + } + + @Test + public void mergeStreamContextDocuments() throws Exception + { + //ExStart:MergeStreamContextDocuments + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Processor + //ExFor:Processor.From(Stream, LoadOptions) + //ExFor:Processor.To(Stream, SaveFormat) + //ExFor:Processor.To(Stream, SaveOptions) + //ExFor:Processor.Execute + //ExFor:Merger.Create(MergerContext) + //ExFor:MergerContext + //ExSummary:Shows how to merge documents from stream into a single output document using context. + //There is a several ways to merge documents: + String inputDoc1 = getMyDir() + "Big document.docx"; + String inputDoc2 = getMyDir() + "Tables.docx"; + + FileStream firstStreamIn = new FileStream(getMyDir() + "Big document.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + FileStream secondStreamIn = new FileStream(getMyDir() + "Tables.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setPassword("Aspose.Words"); } + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.MergeStreamContextDocuments.1.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Merger.create(new MergerContext(); { .setMergeFormatMode(MergeFormatMode.KEEP_SOURCE_FORMATTING); }) + .fromInternal(firstStreamIn) + .fromInternal(secondStreamIn) + .toInternal(streamOut, saveOptions) + .execute(); + } + finally { if (streamOut != null) streamOut.close(); } + + LoadOptions firstLoadOptions = new LoadOptions(); { firstLoadOptions.setIgnoreOleData(true); } + LoadOptions secondLoadOptions = new LoadOptions(); { secondLoadOptions.setIgnoreOleData(false); } + FileStream streamOut1 = new FileStream(getArtifactsDir() + "LowCode.MergeStreamContextDocuments.2.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Merger.create(new MergerContext(); { .setMergeFormatMode(MergeFormatMode.KEEP_SOURCE_FORMATTING); }) + .fromInternal(firstStreamIn, firstLoadOptions) + .fromInternal(secondStreamIn, secondLoadOptions) + .toInternal(streamOut1, SaveFormat.DOCX) + .execute(); + } + finally { if (streamOut1 != null) streamOut1.close(); } + } + finally { if (secondStreamIn != null) secondStreamIn.close(); } + } + finally { if (firstStreamIn != null) firstStreamIn.close(); } + //ExEnd:MergeStreamContextDocuments + } + + @Test + public void mergeDocumentInstances() throws Exception + { + //ExStart:MergeDocumentInstances + //GistId:e386727403c2341ce4018bca370a5b41 + //ExFor:Merger.Merge(Document[], MergeFormatMode) + //ExSummary:Shows how to merge input documents to a single document instance. + DocumentBuilder firstDoc = new DocumentBuilder(); + firstDoc.getFont().setSize(16.0); + firstDoc.getFont().setColor(Color.BLUE); + firstDoc.write("Hello first word!"); + + DocumentBuilder secondDoc = new DocumentBuilder(); + secondDoc.write("Hello second word!"); + + Document mergedDoc = Merger.merge(new Document[] { firstDoc.getDocument(), secondDoc.getDocument() }, MergeFormatMode.KEEP_SOURCE_LAYOUT); + Assert.assertEquals("Hello first word!\fHello second word!\f", mergedDoc.getText()); + //ExEnd:MergeDocumentInstances + } + + @Test + public void convert() throws Exception + { + //ExStart:Convert + //GistId:708ce40a68fac5003d46f6b4acfd5ff1 + //ExFor:Converter.Convert(String, String) + //ExFor:Converter.Convert(String, String, SaveFormat) + //ExFor:Converter.Convert(String, String, SaveOptions) + //ExFor:Converter.Convert(String, LoadOptions, String, SaveOptions) + //ExSummary:Shows how to convert documents with a single line of code. + String doc = getMyDir() + "Document.docx"; + + Converter.convert(doc, getArtifactsDir() + "LowCode.Convert.pdf"); + + Converter.convert(doc, getArtifactsDir() + "LowCode.Convert.SaveFormat.rtf", SaveFormat.RTF); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setPassword("Aspose.Words"); } + LoadOptions loadOptions = new LoadOptions(); { loadOptions.setIgnoreOleData(true); } + Converter.convert(doc, loadOptions, getArtifactsDir() + "LowCode.Convert.LoadOptions.docx", saveOptions); + + Converter.convert(doc, getArtifactsDir() + "LowCode.Convert.SaveOptions.docx", saveOptions); + //ExEnd:Convert + } + + @Test + public void convertContext() throws Exception + { + //ExStart:ConvertContext + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Processor + //ExFor:Processor.From(String, LoadOptions) + //ExFor:Processor.To(String, SaveOptions) + //ExFor:Processor.Execute + //ExFor:Converter.Create(ConverterContext) + //ExFor:ConverterContext + //ExSummary:Shows how to convert documents with a single line of code using context. + String doc = getMyDir() + "Big document.docx"; + + Converter.create(new ConverterContext()) + .from(doc) + .to(getArtifactsDir() + "LowCode.ConvertContext.1.pdf") + .execute(); + + Converter.create(new ConverterContext()) + .from(doc) + .to(getArtifactsDir() + "LowCode.ConvertContext.2.pdf", SaveFormat.RTF) + .execute(); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setPassword("Aspose.Words"); } + LoadOptions loadOptions = new LoadOptions(); { loadOptions.setIgnoreOleData(true); } + Converter.create(new ConverterContext()) + .from(doc, loadOptions) + .to(getArtifactsDir() + "LowCode.ConvertContext.3.docx", saveOptions) + .execute(); + + Converter.create(new ConverterContext()) + .from(doc) + .to(getArtifactsDir() + "LowCode.ConvertContext.4.png", new ImageSaveOptions(SaveFormat.PNG)) + .execute(); + //ExEnd:ConvertContext + } + + @Test + public void convertStream() throws Exception + { + //ExStart:ConvertStream + //GistId:708ce40a68fac5003d46f6b4acfd5ff1 + //ExFor:Converter.Convert(Stream, Stream, SaveFormat) + //ExFor:Converter.Convert(Stream, Stream, SaveOptions) + //ExFor:Converter.Convert(Stream, LoadOptions, Stream, SaveOptions) + //ExSummary:Shows how to convert documents with a single line of code (Stream). + FileStream streamIn = new FileStream(getMyDir() + "Big document.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.ConvertStream.1.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Converter.convertInternal(streamIn, streamOut, SaveFormat.DOCX); + } + finally { if (streamOut != null) streamOut.close(); } + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setPassword("Aspose.Words"); } + LoadOptions loadOptions = new LoadOptions(); { loadOptions.setIgnoreOleData(true); } + FileStream streamOut1 = new FileStream(getArtifactsDir() + "LowCode.ConvertStream.2.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Converter.convertInternal(streamIn, loadOptions, streamOut1, saveOptions); + } + finally { if (streamOut1 != null) streamOut1.close(); } + + FileStream streamOut2 = new FileStream(getArtifactsDir() + "LowCode.ConvertStream.3.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Converter.convertInternal(streamIn, streamOut2, saveOptions); + } + finally { if (streamOut2 != null) streamOut2.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:ConvertStream + } + + @Test + public void convertContextStream() throws Exception + { + //ExStart:ConvertContextStream + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Processor + //ExFor:Processor.From(Stream, LoadOptions) + //ExFor:Processor.To(Stream, SaveFormat) + //ExFor:Processor.To(Stream, SaveOptions) + //ExFor:Processor.Execute + //ExFor:Converter.Create(ConverterContext) + //ExFor:ConverterContext + //ExSummary:Shows how to convert documents from a stream with a single line of code using context. + String doc = getMyDir() + "Document.docx"; + FileStream streamIn = new FileStream(getMyDir() + "Big document.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.ConvertContextStream.1.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Converter.create(new ConverterContext()) + .fromInternal(streamIn) + .toInternal(streamOut, SaveFormat.RTF) + .execute(); + } + finally { if (streamOut != null) streamOut.close(); } + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setPassword("Aspose.Words"); } + LoadOptions loadOptions = new LoadOptions(); { loadOptions.setIgnoreOleData(true); } + FileStream streamOut1 = new FileStream(getArtifactsDir() + "LowCode.ConvertContextStream.2.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Converter.create(new ConverterContext()) + .fromInternal(streamIn, loadOptions) + .toInternal(streamOut1, saveOptions) + .execute(); + } + finally { if (streamOut1 != null) streamOut1.close(); } + + ArrayList pages = new ArrayList(); + Converter.create(new ConverterContext()) + .from(doc) + .to(pages, new ImageSaveOptions(SaveFormat.PNG)) + .execute(); + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:ConvertContextStream + } + + @Test + public void convertToImages() throws Exception + { + //ExStart:ConvertToImages + //GistId:708ce40a68fac5003d46f6b4acfd5ff1 + //ExFor:Converter.ConvertToImages(String, String) + //ExFor:Converter.ConvertToImages(String, String, SaveFormat) + //ExFor:Converter.ConvertToImages(String, String, ImageSaveOptions) + //ExFor:Converter.ConvertToImages(String, LoadOptions, String, ImageSaveOptions) + //ExSummary:Shows how to convert document to images. + String doc = getMyDir() + "Big document.docx"; + + Converter.convert(doc, getArtifactsDir() + "LowCode.ConvertToImages.1.png"); + + Converter.convert(doc, getArtifactsDir() + "LowCode.ConvertToImages.2.jpeg", SaveFormat.JPEG); + + LoadOptions loadOptions = new LoadOptions(); { loadOptions.setIgnoreOleData(false); } + ImageSaveOptions imageSaveOptions = new ImageSaveOptions(SaveFormat.PNG); + imageSaveOptions.setPageSet(new PageSet(1)); + Converter.convert(doc, loadOptions, getArtifactsDir() + "LowCode.ConvertToImages.3.png", imageSaveOptions); + + Converter.convert(doc, getArtifactsDir() + "LowCode.ConvertToImages.4.png", imageSaveOptions); + //ExEnd:ConvertToImages + } + + @Test + public void convertToImagesStream() throws Exception + { + //ExStart:ConvertToImagesStream + //GistId:708ce40a68fac5003d46f6b4acfd5ff1 + //ExFor:Converter.ConvertToImages(String, SaveFormat) + //ExFor:Converter.ConvertToImages(String, ImageSaveOptions) + //ExFor:Converter.ConvertToImages(Document, SaveFormat) + //ExFor:Converter.ConvertToImages(Document, ImageSaveOptions) + //ExSummary:Shows how to convert document to images stream. + String doc = getMyDir() + "Big document.docx"; + + Stream[] streams = Converter.convertToImagesInternal(doc, SaveFormat.PNG); + + ImageSaveOptions imageSaveOptions = new ImageSaveOptions(SaveFormat.PNG); + imageSaveOptions.setPageSet(new PageSet(1)); + streams = Converter.convertToImagesInternal(doc, imageSaveOptions); + + streams = Converter.convertToImagesInternal(new Document(doc), SaveFormat.PNG); + + streams = Converter.convertToImagesInternal(new Document(doc), imageSaveOptions); + //ExEnd:ConvertToImagesStream + } + + @Test + public void convertToImagesFromStream() throws Exception + { + //ExStart:ConvertToImagesFromStream + //GistId:708ce40a68fac5003d46f6b4acfd5ff1 + //ExFor:Converter.ConvertToImages(Stream, SaveFormat) + //ExFor:Converter.ConvertToImages(Stream, ImageSaveOptions) + //ExFor:Converter.ConvertToImages(Stream, LoadOptions, ImageSaveOptions) + //ExSummary:Shows how to convert document to images from stream. + FileStream streamIn = new FileStream(getMyDir() + "Big document.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + Stream[] streams = Converter.convertToImagesInternal(streamIn, SaveFormat.JPEG); + + ImageSaveOptions imageSaveOptions = new ImageSaveOptions(SaveFormat.PNG); + imageSaveOptions.setPageSet(new PageSet(1)); + streams = Converter.convertToImagesInternal(streamIn, imageSaveOptions); + + LoadOptions loadOptions = new LoadOptions(); { loadOptions.setIgnoreOleData(false); } + Converter.convertToImagesInternal(streamIn, loadOptions, imageSaveOptions); + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:ConvertToImagesFromStream + } + + @Test (dataProvider = "pdfRendererDataProvider") + public void pdfRenderer(String docName, String format) throws Exception + { + switch (gStringSwitchMap.of(format)) + { + case /*"PDF"*/0: + LoadOptions loadOptions = new LoadOptions(); { loadOptions.setPassword("{Asp0se}P@ssw0rd"); } + saveTo(docName, loadOptions, new PdfSaveOptions(), "pdf"); + assertResult("pdf"); + + break; + + case /*"HTML"*/1: + HtmlFixedSaveOptions htmlSaveOptions = new HtmlFixedSaveOptions(); + { + htmlSaveOptions.setPageSet(new PageSet(0)); + htmlSaveOptions.setPrettyFormat(true); + htmlSaveOptions.setExportEmbeddedFonts(true); + htmlSaveOptions.setExportEmbeddedCss(true); + } + saveTo(docName, new LoadOptions(), htmlSaveOptions, "html"); + assertResult("html"); + + break; + + case /*"XPS"*/2: + saveTo(docName, new LoadOptions(), new XpsSaveOptions(), "xps"); + assertResult("xps"); + + break; + + case /*"JPEG"*/3: + ImageSaveOptions jpegSaveOptions = new ImageSaveOptions(SaveFormat.JPEG); { jpegSaveOptions.setJpegQuality(10); } + saveTo(docName, new LoadOptions(), jpegSaveOptions, "jpeg"); + assertResult("jpeg"); + + break; + + case /*"PNG"*/4: + ImageSaveOptions pngSaveOptions = new ImageSaveOptions(SaveFormat.PNG); + { + pngSaveOptions.setPageSet(new PageSet(0, 1)); + pngSaveOptions.setJpegQuality(50); + } + saveTo(docName, new LoadOptions(), pngSaveOptions, "png"); + assertResult("png"); + + break; + + case /*"TIFF"*/5: + ImageSaveOptions tiffSaveOptions = new ImageSaveOptions(SaveFormat.TIFF); { tiffSaveOptions.setJpegQuality(100); } + saveTo(docName, new LoadOptions(), tiffSaveOptions, "tiff"); + assertResult("tiff"); + + break; + + case /*"BMP"*/6: + ImageSaveOptions bmpSaveOptions = new ImageSaveOptions(SaveFormat.BMP); + saveTo(docName, new LoadOptions(), bmpSaveOptions, "bmp"); + assertResult("bmp"); + + break; + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "pdfRendererDataProvider") + public static Object[][] pdfRendererDataProvider() throws Exception + { + return new Object[][] + { + {"Protected pdf document.pdf", "PDF"}, + {"Pdf Document.pdf", "HTML"}, + {"Pdf Document.pdf", "XPS"}, + {"Images.pdf", "JPEG"}, + {"Images.pdf", "PNG"}, + {"Images.pdf", "TIFF"}, + {"Images.pdf", "BMP"}, + }; + } + + private void saveTo(String docName, LoadOptions loadOptions, SaveOptions saveOptions, String fileExt) throws Exception + { + FileStream pdfDoc = new FileInputStream(getMyDir() + docName); + try /*JAVA: was using*/ + { + MemoryStream stream = new MemoryStream(); + IReadOnlyList imagesStream = new ArrayList(); + + if ("pdf".equals(fileExt)) + { + Converter.convertInternal(pdfDoc, loadOptions, stream, saveOptions); + } + else if ("html".equals(fileExt)) + { + Converter.convertInternal(pdfDoc, loadOptions, stream, saveOptions); + } + else if ("xps".equals(fileExt)) + { + Converter.convertInternal(pdfDoc, loadOptions, stream, saveOptions); + } + else if ("jpeg".equals(fileExt) || "png".equals(fileExt) || "tiff".equals(fileExt) || "bmp".equals(fileExt)) + { + imagesStream = Converter.convertToImagesInternal(pdfDoc, loadOptions, (ImageSaveOptions)saveOptions); + } + + stream.setPosition(0); + if (imagesStream.Count != 0) + { + for (int i = 0; i < imagesStream.Count; i++) + { + FileStream resultDoc = new FileStream(getArtifactsDir() + $"PdfRenderer_{i}.{fileExt}", FileMode.CREATE); + try /*JAVA: was using*/ + { + imagesStream.(i).copyTo(resultDoc); + } + finally { if (resultDoc != null) resultDoc.close(); } + } + } + else + { + FileStream resultDoc = new FileStream(getArtifactsDir() + $"PdfRenderer.{fileExt}", FileMode.CREATE); + try /*JAVA: was using*/ + { + stream.copyTo(resultDoc); + } + finally { if (resultDoc != null) resultDoc.close(); } + } + } + finally { if (pdfDoc != null) pdfDoc.close(); } + } + + private void assertResult(String fileExt) throws Exception + { + if ("jpeg".equals(fileExt) || "png".equals(fileExt) || "tiff".equals(fileExt) || "bmp".equals(fileExt)) + { + Regex reg = new Regex("PdfRenderer_*"); + + var images = Directory.getFiles(getArtifactsDir(), $"*.{fileExt}") + .Where(path => reg.IsMatch(path)) + .ToList(); + + if ("png".equals(fileExt)) + Assert.That(images.Count, assertEquals(2, ); + else if ("tiff".equals(fileExt)) + Assert.That(images.Count, assertEquals(1, ); + else + Assert.That(images.Count, assertEquals(5, ); + } + else + { + if ("xps".equals(fileExt)) + { + var doc = new XpsDocument(getArtifactsDir() + $"PdfRenderer.{fileExt}"); + AssertXpsText(doc); + } + else if ("pdf".equals(fileExt)) + { + Document doc = new Document(getArtifactsDir() + $"PdfRenderer.{fileExt}"); + String content = doc.getText(); + System.out.println(content); + Assert.assertTrue(content.contains("Heading 1.1.1.2")); + } + else + { + String content = File.readAllText(getArtifactsDir() + $"PdfRenderer.{fileExt}"); + System.out.println(content); + Assert.assertTrue(content.contains("Heading 1.1.1.2")); + } + } + } + + private static void assertXpsText(XpsDocument doc) + { + AssertXpsText(doc.SelectActivePage(1)); + } + + private static void assertXpsText(XpsElement element) + { + for (int i = 0; i < element.Count; i++) + AssertXpsText(element[i]); + if (element instanceof XpsGlyphs) + Assert.That(new String[] { "Heading 1", "Head", "ing 1" }.Any(c => ((XpsGlyphs)element).UnicodeString.Contains(c)), assertTrue(); + } + + @Test + public void compareDocuments() throws Exception + { + //ExStart:CompareDocuments + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Comparer.Compare(String, String, String, String, DateTime, CompareOptions) + //ExFor:Comparer.Compare(String, String, String, SaveFormat, String, DateTime, CompareOptions) + //ExSummary:Shows how to simple compare documents. + // There is a several ways to compare documents: + String firstDoc = getMyDir() + "Table column bookmarks.docx"; + String secondDoc = getMyDir() + "Table column bookmarks.doc"; + + Comparer.compareInternal(firstDoc, secondDoc, getArtifactsDir() + "LowCode.CompareDocuments.1.docx", "Author", new DateTime()); + Comparer.compareInternal(firstDoc, secondDoc, getArtifactsDir() + "LowCode.CompareDocuments.2.docx", SaveFormat.DOCX, "Author", new DateTime()); + + CompareOptions compareOptions = new CompareOptions(); + compareOptions.setIgnoreCaseChanges(true); + Comparer.compareInternal(firstDoc, secondDoc, getArtifactsDir() + "LowCode.CompareDocuments.3.docx", "Author", new DateTime(), compareOptions); + Comparer.compareInternal(firstDoc, secondDoc, getArtifactsDir() + "LowCode.CompareDocuments.4.docx", SaveFormat.DOCX, "Author", new DateTime(), compareOptions); + //ExEnd:CompareDocuments + } + + @Test + public void compareContextDocuments() throws Exception + { + //ExStart:CompareContextDocuments + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Comparer.Create(ComparerContext) + //ExFor:ComparerContext + //ExFor:ComparerContext.CompareOptions + //ExSummary:Shows how to simple compare documents using context. + // There is a several ways to compare documents: + String firstDoc = getMyDir() + "Table column bookmarks.docx"; + String secondDoc = getMyDir() + "Table column bookmarks.doc"; + + ComparerContext comparerContext = new ComparerContext(); + comparerContext.getCompareOptions().setIgnoreCaseChanges(true); + comparerContext.setAuthor("Author"); + comparerContext.setDateTimeInternal(new DateTime()); + + Comparer.create(comparerContext) + .from(firstDoc) + .from(secondDoc) + .to(getArtifactsDir() + "LowCode.CompareContextDocuments.docx") + .execute(); + //ExEnd:CompareContextDocuments + } + + @Test + public void compareStreamDocuments() throws Exception + { + //ExStart:CompareStreamDocuments + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Comparer.Compare(Stream, Stream, Stream, SaveFormat, String, DateTime, CompareOptions) + //ExSummary:Shows how to compare documents from the stream. + // There is a several ways to compare documents from the stream: + FileStream firstStreamIn = new FileStream(getMyDir() + "Table column bookmarks.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + FileStream secondStreamIn = new FileStream(getMyDir() + "Table column bookmarks.doc", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.CompareStreamDocuments.1.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Comparer.compareInternal(firstStreamIn, secondStreamIn, streamOut, SaveFormat.DOCX, "Author", new DateTime()); + } + finally { if (streamOut != null) streamOut.close(); } + + FileStream streamOut1 = new FileStream(getArtifactsDir() + "LowCode.CompareStreamDocuments.2.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + CompareOptions compareOptions = new CompareOptions(); + compareOptions.setIgnoreCaseChanges(true); + Comparer.compareInternal(firstStreamIn, secondStreamIn, streamOut1, SaveFormat.DOCX, "Author", new DateTime(), compareOptions); + } + finally { if (streamOut1 != null) streamOut1.close(); } + } + finally { if (secondStreamIn != null) secondStreamIn.close(); } + } + finally { if (firstStreamIn != null) firstStreamIn.close(); } + //ExEnd:CompareStreamDocuments + } + + @Test + public void compareContextStreamDocuments() throws Exception + { + //ExStart:CompareContextStreamDocuments + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Comparer.Create(ComparerContext) + //ExFor:ComparerContext + //ExFor:ComparerContext.CompareOptions + //ExSummary:Shows how to compare documents from the stream using context. + // There is a several ways to compare documents from the stream: + FileStream firstStreamIn = new FileStream(getMyDir() + "Table column bookmarks.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + FileStream secondStreamIn = new FileStream(getMyDir() + "Table column bookmarks.doc", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + ComparerContext comparerContext = new ComparerContext(); + comparerContext.getCompareOptions().setIgnoreCaseChanges(true); + comparerContext.setAuthor("Author"); + comparerContext.setDateTimeInternal(new DateTime()); + + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.CompareContextStreamDocuments.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Comparer.create(comparerContext) + .fromInternal(firstStreamIn) + .fromInternal(secondStreamIn) + .toInternal(streamOut, SaveFormat.DOCX) + .execute(); + } + finally { if (streamOut != null) streamOut.close(); } + } + finally { if (secondStreamIn != null) secondStreamIn.close(); } + } + finally { if (firstStreamIn != null) firstStreamIn.close(); } + //ExEnd:CompareContextStreamDocuments + } + + @Test + public void compareDocumentsToimages() throws Exception + { + //ExStart:CompareDocumentsToimages + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Comparer.CompareToImages(Stream, Stream, ImageSaveOptions, String, DateTime, CompareOptions) + //ExSummary:Shows how to compare documents and save results as images. + // There is a several ways to compare documents: + String firstDoc = getMyDir() + "Table column bookmarks.docx"; + String secondDoc = getMyDir() + "Table column bookmarks.doc"; + + Stream[] pages = Comparer.compareToImagesInternal(firstDoc, secondDoc, new ImageSaveOptions(SaveFormat.PNG), "Author", new DateTime()); + + FileStream firstStreamIn = new FileStream(firstDoc, FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + FileStream secondStreamIn = new FileStream(secondDoc, FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + CompareOptions compareOptions = new CompareOptions(); + compareOptions.setIgnoreCaseChanges(true); + pages = Comparer.compareToImagesInternal(firstStreamIn, secondStreamIn, new ImageSaveOptions(SaveFormat.PNG), "Author", new DateTime(), compareOptions); + } + finally { if (secondStreamIn != null) secondStreamIn.close(); } + } + finally { if (firstStreamIn != null) firstStreamIn.close(); } + //ExEnd:CompareDocumentsToimages + } + + @Test + public void mailMerge() throws Exception + { + //ExStart:MailMerge + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:MailMergeOptions + //ExFor:MailMergeOptions.TrimWhitespaces + //ExFor:MailMerger.Execute(String, String, String[], Object[]) + //ExFor:MailMerger.Execute(String, String, SaveFormat, String[], Object[], MailMergeOptions) + //ExSummary:Shows how to do mail merge operation for a single record. + // There is a several ways to do mail merge operation: + String doc = getMyDir() + "Mail merge.doc"; + + String[] fieldNames = new String[] { "FirstName", "Location", "SpecialCharsInName()" }; + String[] fieldValues = new String[] { "James Bond", "London", "Classified" }; + + MailMerger.execute(doc, getArtifactsDir() + "LowCode.MailMerge.1.docx", fieldNames, fieldValues); + MailMerger.execute(doc, getArtifactsDir() + "LowCode.MailMerge.2.docx", SaveFormat.DOCX, fieldNames, fieldValues); + MailMergeOptions mailMergeOptions = new MailMergeOptions(); + mailMergeOptions.setTrimWhitespaces(true); + MailMerger.execute(doc, getArtifactsDir() + "LowCode.MailMerge.3.docx", SaveFormat.DOCX, fieldNames, fieldValues, mailMergeOptions); + //ExEnd:MailMerge + } + + @Test + public void mailMergeContext() throws Exception + { + //ExStart:MailMergeContext + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:MailMerger.Create(MailMergerContext) + //ExFor:MailMergerContext + //ExFor:MailMergerContext.SetSimpleDataSource(String[], Object[]) + //ExFor:MailMergerContext.MailMergeOptions + //ExSummary:Shows how to do mail merge operation for a single record using context. + // There is a several ways to do mail merge operation: + String doc = getMyDir() + "Mail merge.doc"; + + String[] fieldNames = new String[] { "FirstName", "Location", "SpecialCharsInName()" }; + String[] fieldValues = new String[] { "James Bond", "London", "Classified" }; + + MailMergerContext mailMergerContext = new MailMergerContext(); + mailMergerContext.setSimpleDataSource(fieldNames, fieldValues); + mailMergerContext.getMailMergeOptions().setTrimWhitespaces(true); + + MailMerger.create(mailMergerContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.MailMergeContext.docx") + .execute(); + //ExEnd:MailMergeContext + } + + @Test + public void mailMergeToImages() throws Exception + { + //ExStart:MailMergeToImages + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:MailMerger.ExecuteToImages(String, ImageSaveOptions, String[], Object[], MailMergeOptions) + //ExSummary:Shows how to do mail merge operation for a single record and save result to images. + // There is a several ways to do mail merge operation: + String doc = getMyDir() + "Mail merge.doc"; + + String[] fieldNames = new String[] { "FirstName", "Location", "SpecialCharsInName()" }; + String[] fieldValues = new String[] { "James Bond", "London", "Classified" }; + + Stream[] images = MailMerger.executeToImagesInternal(doc, new ImageSaveOptions(SaveFormat.PNG), fieldNames, fieldValues); + MailMergeOptions mailMergeOptions = new MailMergeOptions(); + mailMergeOptions.setTrimWhitespaces(true); + images = MailMerger.executeToImagesInternal(doc, new ImageSaveOptions(SaveFormat.PNG), fieldNames, fieldValues, mailMergeOptions); + //ExEnd:MailMergeToImages + } + + @Test + public void mailMergeStream() throws Exception + { + //ExStart:MailMergeStream + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:MailMerger.Execute(Stream, Stream, SaveFormat, String[], Object[], MailMergeOptions) + //ExSummary:Shows how to do mail merge operation for a single record from the stream. + // There is a several ways to do mail merge operation using documents from the stream: + String[] fieldNames = new String[] { "FirstName", "Location", "SpecialCharsInName()" }; + String[] fieldValues = new String[] { "James Bond", "London", "Classified" }; + + FileStream streamIn = new FileStream(getMyDir() + "Mail merge.doc", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.MailMergeStream.1.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + MailMerger.executeInternal(streamIn, streamOut, SaveFormat.DOCX, fieldNames, fieldValues); + } + finally { if (streamOut != null) streamOut.close(); } + + FileStream streamOut1 = new FileStream(getArtifactsDir() + "LowCode.MailMergeStream.2.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + MailMergeOptions mailMergeOptions = new MailMergeOptions(); + mailMergeOptions.setTrimWhitespaces(true); + MailMerger.executeInternal(streamIn, streamOut1, SaveFormat.DOCX, fieldNames, fieldValues, mailMergeOptions); + } + finally { if (streamOut1 != null) streamOut1.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:MailMergeStream + } + + @Test + public void mailMergeContextStream() throws Exception + { + //ExStart:MailMergeContextStream + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:MailMerger.Create(MailMergerContext) + //ExFor:MailMergerContext + //ExFor:MailMergerContext.SetSimpleDataSource(String[], Object[]) + //ExFor:MailMergerContext.MailMergeOptions + //ExSummary:Shows how to do mail merge operation for a single record from the stream using context. + // There is a several ways to do mail merge operation using documents from the stream: + String[] fieldNames = new String[] { "FirstName", "Location", "SpecialCharsInName()" }; + String[] fieldValues = new String[] { "James Bond", "London", "Classified" }; + + FileStream streamIn = new FileStream(getMyDir() + "Mail merge.doc", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + MailMergerContext mailMergerContext = new MailMergerContext(); + mailMergerContext.setSimpleDataSource(fieldNames, fieldValues); + mailMergerContext.getMailMergeOptions().setTrimWhitespaces(true); + + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.MailMergeContextStream.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + MailMerger.create(mailMergerContext) + .fromInternal(streamIn) + .toInternal(streamOut, SaveFormat.DOCX) + .execute(); + } + finally { if (streamOut != null) streamOut.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:MailMergeContextStream + } + + @Test + public void mailMergeStreamToImages() throws Exception + { + //ExStart:MailMergeStreamToImages + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:MailMerger.ExecuteToImages(Stream, ImageSaveOptions, String[], Object[], MailMergeOptions) + //ExSummary:Shows how to do mail merge operation for a single record from the stream and save result to images. + // There is a several ways to do mail merge operation using documents from the stream: + String[] fieldNames = new String[] { "FirstName", "Location", "SpecialCharsInName()" }; + String[] fieldValues = new String[] { "James Bond", "London", "Classified" }; + + FileStream streamIn = new FileStream(getMyDir() + "Mail merge.doc", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + Stream[] images = MailMerger.executeToImagesInternal(streamIn, new ImageSaveOptions(SaveFormat.PNG), fieldNames, fieldValues); + + MailMergeOptions mailMergeOptions = new MailMergeOptions(); + mailMergeOptions.setTrimWhitespaces(true); + images = MailMerger.executeToImagesInternal(streamIn, new ImageSaveOptions(SaveFormat.PNG), fieldNames, fieldValues, mailMergeOptions); + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:MailMergeStreamToImages + } + + @Test + public void mailMergeDataRow() throws Exception + { + //ExStart:MailMergeDataRow + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:MailMerger.Execute(String, String, DataRow) + //ExFor:MailMerger.Execute(String, String, SaveFormat, DataRow, MailMergeOptions) + //ExSummary:Shows how to do mail merge operation from a DataRow. + // There is a several ways to do mail merge operation from a DataRow: + String doc = getMyDir() + "Mail merge.doc"; + + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + DataRow dataRow = dataTable.getRows().add(new String[] { "James Bond", "London", "Classified" }); + + MailMerger.execute(doc, getArtifactsDir() + "LowCode.MailMergeDataRow.1.docx", dataRow); + MailMerger.execute(doc, getArtifactsDir() + "LowCode.MailMergeDataRow.2.docx", SaveFormat.DOCX, dataRow); + MailMerger.execute(doc, getArtifactsDir() + "LowCode.MailMergeDataRow.3.docx", SaveFormat.DOCX, dataRow, new MailMergeOptions(); { .setTrimWhitespaces(true); }); + //ExEnd:MailMergeDataRow + } + + @Test + public void mailMergeContextDataRow() throws Exception + { + //ExStart:MailMergeContextDataRow + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:MailMerger.Create(MailMergerContext) + //ExFor:MailMergerContext + //ExFor:MailMergerContext.SetSimpleDataSource(DataRow) + //ExSummary:Shows how to do mail merge operation from a DataRow using context. + // There is a several ways to do mail merge operation from a DataRow: + String doc = getMyDir() + "Mail merge.doc"; + + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + DataRow dataRow = dataTable.getRows().add(new String[] { "James Bond", "London", "Classified" }); + + MailMergerContext mailMergerContext = new MailMergerContext(); + mailMergerContext.setSimpleDataSource(dataRow); + mailMergerContext.getMailMergeOptions().setTrimWhitespaces(true); + + MailMerger.create(mailMergerContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.MailMergeContextDataRow.docx") + .execute(); + //ExEnd:MailMergeContextDataRow + } + + @Test + public void mailMergeToImagesDataRow() throws Exception + { + //ExStart:MailMergeToImagesDataRow + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:MailMerger.ExecuteToImages(String, ImageSaveOptions, DataRow, MailMergeOptions) + //ExSummary:Shows how to do mail merge operation from a DataRow and save result to images. + // There is a several ways to do mail merge operation from a DataRow: + String doc = getMyDir() + "Mail merge.doc"; + + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + DataRow dataRow = dataTable.getRows().add(new String[] { "James Bond", "London", "Classified" }); + + Stream[] images = MailMerger.executeToImagesInternal(doc, new ImageSaveOptions(SaveFormat.PNG), dataRow); + images = MailMerger.executeToImagesInternal(doc, new ImageSaveOptions(SaveFormat.PNG), dataRow, new MailMergeOptions(); { images.setTrimWhitespaces(true); }); + //ExEnd:MailMergeToImagesDataRow + } + + @Test + public void mailMergeStreamDataRow() throws Exception + { + //ExStart:MailMergeStreamDataRow + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:MailMerger.Execute(Stream, Stream, SaveFormat, DataRow, MailMergeOptions) + //ExSummary:Shows how to do mail merge operation from a DataRow using documents from the stream. + // There is a several ways to do mail merge operation from a DataRow using documents from the stream: + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + DataRow dataRow = dataTable.getRows().add(new String[] { "James Bond", "London", "Classified" }); + + FileStream streamIn = new FileStream(getMyDir() + "Mail merge.doc", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.MailMergeStreamDataRow.1.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + MailMerger.executeInternal(streamIn, streamOut, SaveFormat.DOCX, dataRow); + } + finally { if (streamOut != null) streamOut.close(); } + + FileStream streamOut1 = new FileStream(getArtifactsDir() + "LowCode.MailMergeStreamDataRow.2.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + MailMerger.executeInternal(streamIn, streamOut1, SaveFormat.DOCX, dataRow, new MailMergeOptions(); { .setTrimWhitespaces(true); }); + } + finally { if (streamOut1 != null) streamOut1.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:MailMergeStreamDataRow + } + + @Test + public void mailMergeContextStreamDataRow() throws Exception + { + //ExStart:MailMergeContextStreamDataRow + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:MailMerger.Create(MailMergerContext) + //ExFor:MailMergerContext + //ExFor:MailMergerContext.SetSimpleDataSource(DataRow) + //ExSummary:Shows how to do mail merge operation from a DataRow using documents from the stream using context. + // There is a several ways to do mail merge operation from a DataRow using documents from the stream: + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + DataRow dataRow = dataTable.getRows().add(new String[] { "James Bond", "London", "Classified" }); + + FileStream streamIn = new FileStream(getMyDir() + "Mail merge.doc", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + MailMergerContext mailMergerContext = new MailMergerContext(); + mailMergerContext.setSimpleDataSource(dataRow); + mailMergerContext.getMailMergeOptions().setTrimWhitespaces(true); + + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.MailMergeContextStreamDataRow.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + MailMerger.create(mailMergerContext) + .fromInternal(streamIn) + .toInternal(streamOut, SaveFormat.DOCX) + .execute(); + } + finally { if (streamOut != null) streamOut.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:MailMergeContextStreamDataRow + } + + @Test + public void mailMergeStreamToImagesDataRow() throws Exception + { + //ExStart:MailMergeStreamToImagesDataRow + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:MailMerger.ExecuteToImages(Stream, ImageSaveOptions, DataRow, MailMergeOptions) + //ExSummary:Shows how to do mail merge operation from a DataRow using documents from the stream and save result to images. + // There is a several ways to do mail merge operation from a DataRow using documents from the stream: + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + DataRow dataRow = dataTable.getRows().add(new String[] { "James Bond", "London", "Classified" }); + + FileStream streamIn = new FileStream(getMyDir() + "Mail merge.doc", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + Stream[] images = MailMerger.executeToImagesInternal(streamIn, new ImageSaveOptions(SaveFormat.PNG), dataRow); + images = MailMerger.executeToImagesInternal(streamIn, new ImageSaveOptions(SaveFormat.PNG), dataRow, new MailMergeOptions(); { images.setTrimWhitespaces(true); }); + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:MailMergeStreamToImagesDataRow + } + + @Test + public void mailMergeDataTable() throws Exception + { + //ExStart:MailMergeDataTable + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:MailMerger.Execute(String, String, DataTable) + //ExFor:MailMerger.Execute(String, String, SaveFormat, DataTable, MailMergeOptions) + //ExSummary:Shows how to do mail merge operation from a DataTable. + // There is a several ways to do mail merge operation from a DataTable: + String doc = getMyDir() + "Mail merge.doc"; + + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + DataRow dataRow = dataTable.getRows().add(new String[] { "James Bond", "London", "Classified" }); + + MailMerger.execute(doc, getArtifactsDir() + "LowCode.MailMergeDataTable.1.docx", dataTable); + MailMerger.execute(doc, getArtifactsDir() + "LowCode.MailMergeDataTable.2.docx", SaveFormat.DOCX, dataTable); + MailMerger.execute(doc, getArtifactsDir() + "LowCode.MailMergeDataTable.3.docx", SaveFormat.DOCX, dataTable, new MailMergeOptions(); { .setTrimWhitespaces(true); }); + //ExEnd:MailMergeDataTable + } + + @Test + public void mailMergeContextDataTable() throws Exception + { + //ExStart:MailMergeContextDataTable + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:MailMerger.Create(MailMergerContext) + //ExFor:MailMergerContext + //ExFor:MailMergerContext.SetSimpleDataSource(DataTable) + //ExSummary:Shows how to do mail merge operation from a DataTable using context. + // There is a several ways to do mail merge operation from a DataTable: + String doc = getMyDir() + "Mail merge.doc"; + + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + DataRow dataRow = dataTable.getRows().add(new String[] { "James Bond", "London", "Classified" }); + + MailMergerContext mailMergerContext = new MailMergerContext(); + mailMergerContext.setSimpleDataSource(dataTable); + mailMergerContext.getMailMergeOptions().setTrimWhitespaces(true); + + MailMerger.create(mailMergerContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.MailMergeContextDataTable.docx") + .execute(); + //ExEnd:MailMergeContextDataTable + } + + @Test + public void mailMergeToImagesDataTable() throws Exception + { + //ExStart:MailMergeToImagesDataTable + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:MailMerger.ExecuteToImages(String, ImageSaveOptions, DataTable, MailMergeOptions) + //ExSummary:Shows how to do mail merge operation from a DataTable and save result to images. + // There is a several ways to do mail merge operation from a DataTable: + String doc = getMyDir() + "Mail merge.doc"; + + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + DataRow dataRow = dataTable.getRows().add(new String[] { "James Bond", "London", "Classified" }); + + Stream[] images = MailMerger.executeToImagesInternal(doc, new ImageSaveOptions(SaveFormat.PNG), dataTable); + images = MailMerger.executeToImagesInternal(doc, new ImageSaveOptions(SaveFormat.PNG), dataTable, new MailMergeOptions(); { images.setTrimWhitespaces(true); }); + //ExEnd:MailMergeToImagesDataTable + } + + @Test + public void mailMergeStreamDataTable() throws Exception + { + //ExStart:MailMergeStreamDataTable + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:MailMerger.Execute(Stream, Stream, SaveFormat, DataTable, MailMergeOptions) + //ExSummary:Shows how to do mail merge operation from a DataTable using documents from the stream. + // There is a several ways to do mail merge operation from a DataTable using documents from the stream: + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + DataRow dataRow = dataTable.getRows().add(new String[] { "James Bond", "London", "Classified" }); + + FileStream streamIn = new FileStream(getMyDir() + "Mail merge.doc", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.MailMergeDataTable.1.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + MailMerger.executeInternal(streamIn, streamOut, SaveFormat.DOCX, dataTable); + } + finally { if (streamOut != null) streamOut.close(); } + + FileStream streamOut1 = new FileStream(getArtifactsDir() + "LowCode.MailMergeDataTable.2.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + MailMerger.executeInternal(streamIn, streamOut1, SaveFormat.DOCX, dataTable, new MailMergeOptions(); { .setTrimWhitespaces(true); }); + } + finally { if (streamOut1 != null) streamOut1.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:MailMergeStreamDataTable + } + + @Test + public void mailMergeContextStreamDataTable() throws Exception + { + //ExStart:MailMergeContextStreamDataTable + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Processor + //ExFor:MailMerger.Create(MailMergerContext) + //ExFor:MailMergerContext + //ExFor:MailMergerContext.SetSimpleDataSource(DataTable) + //ExSummary:Shows how to do mail merge operation from a DataTable using documents from the stream using context. + // There is a several ways to do mail merge operation from a DataTable using documents from the stream: + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + DataRow dataRow = dataTable.getRows().add(new String[] { "James Bond", "London", "Classified" }); + + FileStream streamIn = new FileStream(getMyDir() + "Mail merge.doc", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + MailMergerContext mailMergerContext = new MailMergerContext(); + mailMergerContext.setSimpleDataSource(dataTable); + mailMergerContext.getMailMergeOptions().setTrimWhitespaces(true); + + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.MailMergeContextStreamDataTable.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + MailMerger.create(mailMergerContext) + .fromInternal(streamIn) + .toInternal(streamOut, SaveFormat.DOCX) + .execute(); + } + finally { if (streamOut != null) streamOut.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:MailMergeContextStreamDataTable + } + + @Test + public void mailMergeStreamToImagesDataTable() throws Exception + { + //ExStart:MailMergeStreamToImagesDataTable + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:MailMerger.ExecuteToImages(Stream, ImageSaveOptions, DataTable, MailMergeOptions) + //ExSummary:Shows how to do mail merge operation from a DataTable using documents from the stream and save to images. + // There is a several ways to do mail merge operation from a DataTable using documents from the stream and save result to images: + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("Location"); + dataTable.getColumns().add("SpecialCharsInName()"); + + DataRow dataRow = dataTable.getRows().add(new String[] { "James Bond", "London", "Classified" }); + + FileStream streamIn = new FileStream(getMyDir() + "Mail merge.doc", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + Stream[] images = MailMerger.executeToImagesInternal(streamIn, new ImageSaveOptions(SaveFormat.PNG), dataTable); + images = MailMerger.executeToImagesInternal(streamIn, new ImageSaveOptions(SaveFormat.PNG), dataTable, new MailMergeOptions(); { images.setTrimWhitespaces(true); }); + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:MailMergeStreamToImagesDataTable + } + + @Test + public void mailMergeWithRegionsDataTable() throws Exception + { + //ExStart:MailMergeWithRegionsDataTable + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:MailMerger.ExecuteWithRegions(String, String, DataTable) + //ExFor:MailMerger.ExecuteWithRegions(String, String, SaveFormat, DataTable, MailMergeOptions) + //ExSummary:Shows how to do mail merge with regions operation from a DataTable. + // There is a several ways to do mail merge with regions operation from a DataTable: + String doc = getMyDir() + "Mail merge with regions.docx"; + + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("LastName"); + dataTable.getRows().add(new Object[] { "John", "Doe" }); + dataTable.getRows().add(new Object[] { "", "" }); + dataTable.getRows().add(new Object[] { "Jane", "Doe" }); + + MailMerger.executeWithRegions(doc, getArtifactsDir() + "LowCode.MailMergeWithRegionsDataTable.1.docx", dataTable); + MailMerger.executeWithRegions(doc, getArtifactsDir() + "LowCode.MailMergeWithRegionsDataTable.2.docx", SaveFormat.DOCX, dataTable); + MailMerger.executeWithRegions(doc, getArtifactsDir() + "LowCode.MailMergeWithRegionsDataTable.3.docx", SaveFormat.DOCX, dataTable, new MailMergeOptions(); { .setTrimWhitespaces(true); }); + //ExEnd:MailMergeWithRegionsDataTable + } + + @Test + public void mailMergeContextWithRegionsDataTable() throws Exception + { + //ExStart:MailMergeContextWithRegionsDataTable + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:MailMerger.Create(MailMergerContext) + //ExFor:MailMergerContext + //ExFor:MailMergerContext.SetRegionsDataSource(DataTable) + //ExSummary:Shows how to do mail merge with regions operation from a DataTable using context. + // There is a several ways to do mail merge with regions operation from a DataTable: + String doc = getMyDir() + "Mail merge with regions.docx"; + + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("LastName"); + dataTable.getRows().add(new Object[] { "John", "Doe" }); + dataTable.getRows().add(new Object[] { "", "" }); + dataTable.getRows().add(new Object[] { "Jane", "Doe" }); + + MailMergerContext mailMergerContext = new MailMergerContext(); + mailMergerContext.setRegionsDataSource(dataTable); + mailMergerContext.getMailMergeOptions().setTrimWhitespaces(true); + + MailMerger.create(mailMergerContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.MailMergeContextWithRegionsDataTable.docx") + .execute(); + //ExEnd:MailMergeContextWithRegionsDataTable + } + + @Test + public void mailMergeWithRegionsToImagesDataTable() throws Exception + { + //ExStart:MailMergeWithRegionsToImagesDataTable + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:MailMerger.ExecuteWithRegionsToImages(String, ImageSaveOptions, DataTable, MailMergeOptions) + //ExSummary:Shows how to do mail merge with regions operation from a DataTable and save result to images. + // There is a several ways to do mail merge with regions operation from a DataTable: + String doc = getMyDir() + "Mail merge with regions.docx"; + + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("LastName"); + dataTable.getRows().add(new Object[] { "John", "Doe" }); + dataTable.getRows().add(new Object[] { "", "" }); + dataTable.getRows().add(new Object[] { "Jane", "Doe" }); + + Stream[] images = MailMerger.executeWithRegionsToImagesInternal(doc, new ImageSaveOptions(SaveFormat.PNG), dataTable); + images = MailMerger.executeWithRegionsToImagesInternal(doc, new ImageSaveOptions(SaveFormat.PNG), dataTable, new MailMergeOptions(); { images.setTrimWhitespaces(true); }); + //ExEnd:MailMergeWithRegionsToImagesDataTable + } + + @Test + public void mailMergeStreamWithRegionsDataTable() throws Exception + { + //ExStart:MailMergeStreamWithRegionsDataTable + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:MailMerger.ExecuteWithRegions(Stream, Stream, SaveFormat, DataTable, MailMergeOptions) + //ExSummary:Shows how to do mail merge with regions operation from a DataTable using documents from the stream. + // There is a several ways to do mail merge with regions operation from a DataTable using documents from the stream: + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("LastName"); + dataTable.getRows().add(new Object[] { "John", "Doe" }); + dataTable.getRows().add(new Object[] { "", "" }); + dataTable.getRows().add(new Object[] { "Jane", "Doe" }); + + FileStream streamIn = new FileStream(getMyDir() + "Mail merge.doc", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.MailMergeStreamWithRegionsDataTable.1.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + MailMerger.executeWithRegionsInternal(streamIn, streamOut, SaveFormat.DOCX, dataTable); + } + finally { if (streamOut != null) streamOut.close(); } + + FileStream streamOut1 = new FileStream(getArtifactsDir() + "LowCode.MailMergeStreamWithRegionsDataTable.2.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + MailMerger.executeWithRegionsInternal(streamIn, streamOut1, SaveFormat.DOCX, dataTable, new MailMergeOptions(); { .setTrimWhitespaces(true); }); + } + finally { if (streamOut1 != null) streamOut1.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:MailMergeStreamWithRegionsDataTable + } + + @Test + public void mailMergeContextStreamWithRegionsDataTable() throws Exception + { + //ExStart:MailMergeContextStreamWithRegionsDataTable + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:MailMerger.Create(MailMergerContext) + //ExFor:MailMergerContext + //ExFor:MailMergerContext.SetRegionsDataSource(DataTable) + //ExSummary:Shows how to do mail merge with regions operation from a DataTable using documents from the stream using context. + // There is a several ways to do mail merge with regions operation from a DataTable using documents from the stream: + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("LastName"); + dataTable.getRows().add(new Object[] { "John", "Doe" }); + dataTable.getRows().add(new Object[] { "", "" }); + dataTable.getRows().add(new Object[] { "Jane", "Doe" }); + + FileStream streamIn = new FileStream(getMyDir() + "Mail merge.doc", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + MailMergerContext mailMergerContext = new MailMergerContext(); + mailMergerContext.setRegionsDataSource(dataTable); + mailMergerContext.getMailMergeOptions().setTrimWhitespaces(true); + + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.MailMergeContextStreamWithRegionsDataTable.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + MailMerger.create(mailMergerContext) + .fromInternal(streamIn) + .toInternal(streamOut, SaveFormat.DOCX) + .execute(); + } + finally { if (streamOut != null) streamOut.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:MailMergeContextStreamWithRegionsDataTable + } + + @Test + public void mailMergeStreamWithRegionsToImagesDataTable() throws Exception + { + //ExStart:MailMergeStreamWithRegionsToImagesDataTable + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:MailMerger.ExecuteWithRegionsToImages(Stream, ImageSaveOptions, DataTable, MailMergeOptions) + //ExSummary:Shows how to do mail merge with regions operation from a DataTable using documents from the stream and save result to images. + // There is a several ways to do mail merge with regions operation from a DataTable using documents from the stream: + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("LastName"); + dataTable.getRows().add(new Object[] { "John", "Doe" }); + dataTable.getRows().add(new Object[] { "", "" }); + dataTable.getRows().add(new Object[] { "Jane", "Doe" }); + + FileStream streamIn = new FileStream(getMyDir() + "Mail merge.doc", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + Stream[] images = MailMerger.executeWithRegionsToImagesInternal(streamIn, new ImageSaveOptions(SaveFormat.PNG), dataTable); + images = MailMerger.executeWithRegionsToImagesInternal(streamIn, new ImageSaveOptions(SaveFormat.PNG), dataTable, new MailMergeOptions(); { images.setTrimWhitespaces(true); }); + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:MailMergeStreamWithRegionsToImagesDataTable + } + + @Test + public void mailMergeWithRegionsDataSet() throws Exception + { + //ExStart:MailMergeWithRegionsDataSet + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:MailMerger.ExecuteWithRegions(String, String, DataSet) + //ExFor:MailMerger.ExecuteWithRegions(String, String, SaveFormat, DataSet, MailMergeOptions) + //ExSummary:Shows how to do mail merge with regions operation from a DataSet. + // There is a several ways to do mail merge with regions operation from a DataSet: + String doc = getMyDir() + "Mail merge with regions data set.docx"; + + DataTable tableCustomers = new DataTable("Customers"); + tableCustomers.getColumns().add("CustomerID"); + tableCustomers.getColumns().add("CustomerName"); + tableCustomers.getRows().add(new Object[] { 1, "John Doe" }); + tableCustomers.getRows().add(new Object[] { 2, "Jane Doe" }); + + DataTable tableOrders = new DataTable("Orders"); + tableOrders.getColumns().add("CustomerID"); + tableOrders.getColumns().add("ItemName"); + tableOrders.getColumns().add("Quantity"); + tableOrders.getRows().add(new Object[] { 1, "Hawaiian", 2 }); + tableOrders.getRows().add(new Object[] { 2, "Pepperoni", 1 }); + tableOrders.getRows().add(new Object[] { 2, "Chicago", 1 }); + + DataSet dataSet = new DataSet(); + dataSet.getTables().add(tableCustomers); + dataSet.getTables().add(tableOrders); + dataSet.getRelations().add(tableCustomers.getColumns().get("CustomerID"), tableOrders.getColumns().get("CustomerID")); + + MailMerger.executeWithRegions(doc, getArtifactsDir() + "LowCode.MailMergeWithRegionsDataSet.1.docx", dataSet); + MailMerger.executeWithRegions(doc, getArtifactsDir() + "LowCode.MailMergeWithRegionsDataSet.2.docx", SaveFormat.DOCX, dataSet); + MailMerger.executeWithRegions(doc, getArtifactsDir() + "LowCode.MailMergeWithRegionsDataSet.3.docx", SaveFormat.DOCX, dataSet, new MailMergeOptions(); { .setTrimWhitespaces(true); }); + //ExEnd:MailMergeWithRegionsDataSet + } + + @Test + public void mailMergeContextWithRegionsDataSet() throws Exception + { + //ExStart:MailMergeContextWithRegionsDataSet + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:MailMerger.Create(MailMergerContext) + //ExFor:MailMergerContext + //ExFor:MailMergerContext.SetRegionsDataSource(DataSet) + //ExSummary:Shows how to do mail merge with regions operation from a DataSet using context. + // There is a several ways to do mail merge with regions operation from a DataSet: + String doc = getMyDir() + "Mail merge with regions data set.docx"; + + DataTable tableCustomers = new DataTable("Customers"); + tableCustomers.getColumns().add("CustomerID"); + tableCustomers.getColumns().add("CustomerName"); + tableCustomers.getRows().add(new Object[] { 1, "John Doe" }); + tableCustomers.getRows().add(new Object[] { 2, "Jane Doe" }); + + DataTable tableOrders = new DataTable("Orders"); + tableOrders.getColumns().add("CustomerID"); + tableOrders.getColumns().add("ItemName"); + tableOrders.getColumns().add("Quantity"); + tableOrders.getRows().add(new Object[] { 1, "Hawaiian", 2 }); + tableOrders.getRows().add(new Object[] { 2, "Pepperoni", 1 }); + tableOrders.getRows().add(new Object[] { 2, "Chicago", 1 }); + + DataSet dataSet = new DataSet(); + dataSet.getTables().add(tableCustomers); + dataSet.getTables().add(tableOrders); + dataSet.getRelations().add(tableCustomers.getColumns().get("CustomerID"), tableOrders.getColumns().get("CustomerID")); + + MailMergerContext mailMergerContext = new MailMergerContext(); + mailMergerContext.setRegionsDataSource(dataSet); + mailMergerContext.getMailMergeOptions().setTrimWhitespaces(true); + + MailMerger.create(mailMergerContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.MailMergeContextWithRegionsDataTable.docx") + .execute(); + //ExEnd:MailMergeContextWithRegionsDataSet + } + + @Test + public void mailMergeWithRegionsToImagesDataSet() throws Exception + { + //ExStart:MailMergeWithRegionsToImagesDataSet + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:MailMerger.ExecuteWithRegionsToImages(String, ImageSaveOptions, DataSet, MailMergeOptions) + //ExSummary:Shows how to do mail merge with regions operation from a DataSet and save result to images. + // There is a several ways to do mail merge with regions operation from a DataSet: + String doc = getMyDir() + "Mail merge with regions data set.docx"; + + DataTable tableCustomers = new DataTable("Customers"); + tableCustomers.getColumns().add("CustomerID"); + tableCustomers.getColumns().add("CustomerName"); + tableCustomers.getRows().add(new Object[] { 1, "John Doe" }); + tableCustomers.getRows().add(new Object[] { 2, "Jane Doe" }); + + DataTable tableOrders = new DataTable("Orders"); + tableOrders.getColumns().add("CustomerID"); + tableOrders.getColumns().add("ItemName"); + tableOrders.getColumns().add("Quantity"); + tableOrders.getRows().add(new Object[] { 1, "Hawaiian", 2 }); + tableOrders.getRows().add(new Object[] { 2, "Pepperoni", 1 }); + tableOrders.getRows().add(new Object[] { 2, "Chicago", 1 }); + + DataSet dataSet = new DataSet(); + dataSet.getTables().add(tableCustomers); + dataSet.getTables().add(tableOrders); + dataSet.getRelations().add(tableCustomers.getColumns().get("CustomerID"), tableOrders.getColumns().get("CustomerID")); + + Stream[] images = MailMerger.executeWithRegionsToImagesInternal(doc, new ImageSaveOptions(SaveFormat.PNG), dataSet); + images = MailMerger.executeWithRegionsToImagesInternal(doc, new ImageSaveOptions(SaveFormat.PNG), dataSet, new MailMergeOptions(); { images.setTrimWhitespaces(true); }); + //ExEnd:MailMergeWithRegionsToImagesDataSet + } + + @Test + public void mailMergeStreamWithRegionsDataSet() throws Exception + { + //ExStart:MailMergeStreamWithRegionsDataSet + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:MailMerger.ExecuteWithRegions(Stream, Stream, SaveFormat, DataSet, MailMergeOptions) + //ExSummary:Shows how to do mail merge with regions operation from a DataSet using documents from the stream. + // There is a several ways to do mail merge with regions operation from a DataSet using documents from the stream: + DataTable tableCustomers = new DataTable("Customers"); + tableCustomers.getColumns().add("CustomerID"); + tableCustomers.getColumns().add("CustomerName"); + tableCustomers.getRows().add(new Object[] { 1, "John Doe" }); + tableCustomers.getRows().add(new Object[] { 2, "Jane Doe" }); + + DataTable tableOrders = new DataTable("Orders"); + tableOrders.getColumns().add("CustomerID"); + tableOrders.getColumns().add("ItemName"); + tableOrders.getColumns().add("Quantity"); + tableOrders.getRows().add(new Object[] { 1, "Hawaiian", 2 }); + tableOrders.getRows().add(new Object[] { 2, "Pepperoni", 1 }); + tableOrders.getRows().add(new Object[] { 2, "Chicago", 1 }); + + DataSet dataSet = new DataSet(); + dataSet.getTables().add(tableCustomers); + dataSet.getTables().add(tableOrders); + dataSet.getRelations().add(tableCustomers.getColumns().get("CustomerID"), tableOrders.getColumns().get("CustomerID")); + + FileStream streamIn = new FileStream(getMyDir() + "Mail merge.doc", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.MailMergeStreamWithRegionsDataTable.1.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + MailMerger.executeWithRegionsInternal(streamIn, streamOut, SaveFormat.DOCX, dataSet); + } + finally { if (streamOut != null) streamOut.close(); } + + FileStream streamOut1 = new FileStream(getArtifactsDir() + "LowCode.MailMergeStreamWithRegionsDataTable.2.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + MailMerger.executeWithRegionsInternal(streamIn, streamOut1, SaveFormat.DOCX, dataSet, new MailMergeOptions(); { .setTrimWhitespaces(true); }); + } + finally { if (streamOut1 != null) streamOut1.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:MailMergeStreamWithRegionsDataSet + } + + @Test + public void mailMergeContextStreamWithRegionsDataSet() throws Exception + { + //ExStart:MailMergeContextStreamWithRegionsDataSet + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:MailMerger.Create(MailMergerContext) + //ExFor:MailMergerContext + //ExFor:MailMergerContext.SetRegionsDataSource(DataSet) + //ExSummary:Shows how to do mail merge with regions operation from a DataSet using documents from the stream using context. + // There is a several ways to do mail merge with regions operation from a DataSet using documents from the stream: + DataTable tableCustomers = new DataTable("Customers"); + tableCustomers.getColumns().add("CustomerID"); + tableCustomers.getColumns().add("CustomerName"); + tableCustomers.getRows().add(new Object[] { 1, "John Doe" }); + tableCustomers.getRows().add(new Object[] { 2, "Jane Doe" }); + + DataTable tableOrders = new DataTable("Orders"); + tableOrders.getColumns().add("CustomerID"); + tableOrders.getColumns().add("ItemName"); + tableOrders.getColumns().add("Quantity"); + tableOrders.getRows().add(new Object[] { 1, "Hawaiian", 2 }); + tableOrders.getRows().add(new Object[] { 2, "Pepperoni", 1 }); + tableOrders.getRows().add(new Object[] { 2, "Chicago", 1 }); + + DataSet dataSet = new DataSet(); + dataSet.getTables().add(tableCustomers); + dataSet.getTables().add(tableOrders); + dataSet.getRelations().add(tableCustomers.getColumns().get("CustomerID"), tableOrders.getColumns().get("CustomerID")); + + FileStream streamIn = new FileStream(getMyDir() + "Mail merge.doc", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + MailMergerContext mailMergerContext = new MailMergerContext(); + mailMergerContext.setRegionsDataSource(dataSet); + mailMergerContext.getMailMergeOptions().setTrimWhitespaces(true); + + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.MailMergeContextStreamWithRegionsDataSet.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + MailMerger.create(mailMergerContext) + .fromInternal(streamIn) + .toInternal(streamOut, SaveFormat.DOCX) + .execute(); + } + finally { if (streamOut != null) streamOut.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:MailMergeContextStreamWithRegionsDataSet + } + + @Test + public void mailMergeStreamWithRegionsToImagesDataSet() throws Exception + { + //ExStart:MailMergeStreamWithRegionsToImagesDataSet + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:MailMerger.ExecuteWithRegionsToImages(Stream, ImageSaveOptions, DataSet, MailMergeOptions) + //ExSummary:Shows how to do mail merge with regions operation from a DataSet using documents from the stream and save result to images. + // There is a several ways to do mail merge with regions operation from a DataSet using documents from the stream: + DataTable tableCustomers = new DataTable("Customers"); + tableCustomers.getColumns().add("CustomerID"); + tableCustomers.getColumns().add("CustomerName"); + tableCustomers.getRows().add(new Object[] { 1, "John Doe" }); + tableCustomers.getRows().add(new Object[] { 2, "Jane Doe" }); + + DataTable tableOrders = new DataTable("Orders"); + tableOrders.getColumns().add("CustomerID"); + tableOrders.getColumns().add("ItemName"); + tableOrders.getColumns().add("Quantity"); + tableOrders.getRows().add(new Object[] { 1, "Hawaiian", 2 }); + tableOrders.getRows().add(new Object[] { 2, "Pepperoni", 1 }); + tableOrders.getRows().add(new Object[] { 2, "Chicago", 1 }); + + DataSet dataSet = new DataSet(); + dataSet.getTables().add(tableCustomers); + dataSet.getTables().add(tableOrders); + dataSet.getRelations().add(tableCustomers.getColumns().get("CustomerID"), tableOrders.getColumns().get("CustomerID")); + + FileStream streamIn = new FileStream(getMyDir() + "Mail merge.doc", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + Stream[] images = MailMerger.executeWithRegionsToImagesInternal(streamIn, new ImageSaveOptions(SaveFormat.PNG), dataSet); + images = MailMerger.executeWithRegionsToImagesInternal(streamIn, new ImageSaveOptions(SaveFormat.PNG), dataSet, new MailMergeOptions(); { images.setTrimWhitespaces(true); }); + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:MailMergeStreamWithRegionsToImagesDataSet + } + + @Test + public void replace() throws Exception + { + //ExStart:Replace + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Replacer.Replace(String, String, String, String) + //ExFor:Replacer.Replace(String, String, SaveFormat, String, String, FindReplaceOptions) + //ExSummary:Shows how to replace string in the document. + // There is a several ways to replace string in the document: + String doc = getMyDir() + "Footer.docx"; + String pattern = "(C)2006 Aspose Pty Ltd."; + String replacement = "Copyright (C) 2024 by Aspose Pty Ltd."; + + FindReplaceOptions options = new FindReplaceOptions(); + options.setFindWholeWordsOnly(false); + Replacer.replace(doc, getArtifactsDir() + "LowCode.Replace.1.docx", pattern, replacement); + Replacer.replace(doc, getArtifactsDir() + "LowCode.Replace.2.docx", SaveFormat.DOCX, pattern, replacement); + Replacer.replace(doc, getArtifactsDir() + "LowCode.Replace.3.docx", SaveFormat.DOCX, pattern, replacement, options); + //ExEnd:Replace + } + + @Test + public void replaceContext() throws Exception + { + //ExStart:ReplaceContext + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Replacer.Create(ReplacerContext) + //ExFor:ReplacerContext + //ExFor:ReplacerContext.SetReplacement(String, String) + //ExFor:ReplacerContext.FindReplaceOptions + //ExSummary:Shows how to replace string in the document using context. + // There is a several ways to replace string in the document: + String doc = getMyDir() + "Footer.docx"; + String pattern = "(C)2006 Aspose Pty Ltd."; + String replacement = "Copyright (C) 2024 by Aspose Pty Ltd."; + + ReplacerContext replacerContext = new ReplacerContext(); + replacerContext.setReplacement(pattern, replacement); + replacerContext.getFindReplaceOptions().setFindWholeWordsOnly(false); + + Replacer.create(replacerContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.ReplaceContext.docx") + .execute(); + //ExEnd:ReplaceContext + } + + @Test + public void replaceToImages() throws Exception + { + //ExStart:ReplaceToImages + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Replacer.ReplaceToImages(String, ImageSaveOptions, String, String, FindReplaceOptions) + //ExSummary:Shows how to replace string in the document and save result to images. + // There is a several ways to replace string in the document: + String doc = getMyDir() + "Footer.docx"; + String pattern = "(C)2006 Aspose Pty Ltd."; + String replacement = "Copyright (C) 2024 by Aspose Pty Ltd."; + + Stream[] images = Replacer.replaceToImagesInternal(doc, new ImageSaveOptions(SaveFormat.PNG), pattern, replacement); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setFindWholeWordsOnly(false); + images = Replacer.replaceToImagesInternal(doc, new ImageSaveOptions(SaveFormat.PNG), pattern, replacement, options); + //ExEnd:ReplaceToImages + } + + @Test + public void replaceStream() throws Exception + { + //ExStart:ReplaceStream + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Replacer.Replace(Stream, Stream, SaveFormat, String, String, FindReplaceOptions) + //ExSummary:Shows how to replace string in the document using documents from the stream. + // There is a several ways to replace string in the document using documents from the stream: + String pattern = "(C)2006 Aspose Pty Ltd."; + String replacement = "Copyright (C) 2024 by Aspose Pty Ltd."; + + FileStream streamIn = new FileStream(getMyDir() + "Footer.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.ReplaceStream.1.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Replacer.replaceInternal(streamIn, streamOut, SaveFormat.DOCX, pattern, replacement); + } + finally { if (streamOut != null) streamOut.close(); } + + FileStream streamOut1 = new FileStream(getArtifactsDir() + "LowCode.ReplaceStream.2.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + FindReplaceOptions options = new FindReplaceOptions(); + options.setFindWholeWordsOnly(false); + Replacer.replaceInternal(streamIn, streamOut1, SaveFormat.DOCX, pattern, replacement, options); + } + finally { if (streamOut1 != null) streamOut1.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:ReplaceStream + } + + @Test + public void replaceContextStream() throws Exception + { + //ExStart:ReplaceContextStream + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Replacer.Create(ReplacerContext) + //ExFor:ReplacerContext + //ExFor:ReplacerContext.SetReplacement(String, String) + //ExFor:ReplacerContext.FindReplaceOptions + //ExSummary:Shows how to replace string in the document using documents from the stream using context. + // There is a several ways to replace string in the document using documents from the stream: + String pattern = "(C)2006 Aspose Pty Ltd."; + String replacement = "Copyright (C) 2024 by Aspose Pty Ltd."; + + FileStream streamIn = new FileStream(getMyDir() + "Footer.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + ReplacerContext replacerContext = new ReplacerContext(); + replacerContext.setReplacement(pattern, replacement); + replacerContext.getFindReplaceOptions().setFindWholeWordsOnly(false); + + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.ReplaceContextStream.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Replacer.create(replacerContext) + .fromInternal(streamIn) + .toInternal(streamOut, SaveFormat.DOCX) + .execute(); + } + finally { if (streamOut != null) streamOut.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:ReplaceContextStream + } + + @Test + public void replaceToImagesStream() throws Exception + { + //ExStart:ReplaceToImagesStream + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Replacer.ReplaceToImages(Stream, ImageSaveOptions, String, String, FindReplaceOptions) + //ExSummary:Shows how to replace string in the document using documents from the stream and save result to images. + // There is a several ways to replace string in the document using documents from the stream: + String pattern = "(C)2006 Aspose Pty Ltd."; + String replacement = "Copyright (C) 2024 by Aspose Pty Ltd."; + + FileStream streamIn = new FileStream(getMyDir() + "Footer.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + Stream[] images = Replacer.replaceToImagesInternal(streamIn, new ImageSaveOptions(SaveFormat.PNG), pattern, replacement); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setFindWholeWordsOnly(false); + images = Replacer.replaceToImagesInternal(streamIn, new ImageSaveOptions(SaveFormat.PNG), pattern, replacement, options); + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:ReplaceToImagesStream + } + + @Test + public void replaceRegex() throws Exception + { + //ExStart:ReplaceRegex + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Replacer.Replace(String, String, Regex, String) + //ExFor:Replacer.Replace(String, String, SaveFormat, Regex, String, FindReplaceOptions) + //ExSummary:Shows how to replace string with regex in the document. + // There is a several ways to replace string with regex in the document: + String doc = getMyDir() + "Footer.docx"; + Regex pattern = new Regex("gr(a|e)y"); + String replacement = "lavender"; + + Replacer.replaceInternal(doc, getArtifactsDir() + "LowCode.ReplaceRegex.1.docx", pattern, replacement); + Replacer.replaceInternal(doc, getArtifactsDir() + "LowCode.ReplaceRegex.2.docx", SaveFormat.DOCX, pattern, replacement); + Replacer.replaceInternal(doc, getArtifactsDir() + "LowCode.ReplaceRegex.3.docx", SaveFormat.DOCX, pattern, replacement, new FindReplaceOptions(); { .setFindWholeWordsOnly(false); }); + //ExEnd:ReplaceRegex + } + + @Test + public void replaceContextRegex() throws Exception + { + //ExStart:ReplaceContextRegex + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Replacer.Create(ReplacerContext) + //ExFor:ReplacerContext + //ExFor:ReplacerContext.SetReplacement(Regex, String) + //ExFor:ReplacerContext.FindReplaceOptions + //ExSummary:Shows how to replace string with regex in the document using context. + // There is a several ways to replace string with regex in the document: + String doc = getMyDir() + "Footer.docx"; + Regex pattern = new Regex("gr(a|e)y"); + String replacement = "lavender"; + + ReplacerContext replacerContext = new ReplacerContext(); + replacerContext.setReplacementInternal(pattern, replacement); + replacerContext.getFindReplaceOptions().setFindWholeWordsOnly(false); + + Replacer.create(replacerContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.ReplaceContextRegex.docx") + .execute(); + //ExEnd:ReplaceContextRegex + } + + @Test + public void replaceToImagesRegex() throws Exception + { + //ExStart:ReplaceToImagesRegex + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Replacer.ReplaceToImages(String, ImageSaveOptions, Regex, String, FindReplaceOptions) + //ExSummary:Shows how to replace string with regex in the document and save result to images. + // There is a several ways to replace string with regex in the document: + String doc = getMyDir() + "Footer.docx"; + Regex pattern = new Regex("gr(a|e)y"); + String replacement = "lavender"; + + Stream[] images = Replacer.replaceToImagesInternal(doc, new ImageSaveOptions(SaveFormat.PNG), pattern, replacement); + images = Replacer.replaceToImagesInternal(doc, new ImageSaveOptions(SaveFormat.PNG), pattern, replacement, new FindReplaceOptions(); { images.setFindWholeWordsOnly(false); }); + //ExEnd:ReplaceToImagesRegex + } + + @Test + public void replaceStreamRegex() throws Exception + { + //ExStart:ReplaceStreamRegex + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Replacer.Replace(Stream, Stream, SaveFormat, Regex, String, FindReplaceOptions) + //ExSummary:Shows how to replace string with regex in the document using documents from the stream. + // There is a several ways to replace string with regex in the document using documents from the stream: + Regex pattern = new Regex("gr(a|e)y"); + String replacement = "lavender"; + + FileStream streamIn = new FileStream(getMyDir() + "Replace regex.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.ReplaceStreamRegex.1.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Replacer.replaceInternal(streamIn, streamOut, SaveFormat.DOCX, pattern, replacement); + } + finally { if (streamOut != null) streamOut.close(); } + + FileStream streamOut1 = new FileStream(getArtifactsDir() + "LowCode.ReplaceStreamRegex.2.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Replacer.replaceInternal(streamIn, streamOut1, SaveFormat.DOCX, pattern, replacement, new FindReplaceOptions(); { .setFindWholeWordsOnly(false); }); + } + finally { if (streamOut1 != null) streamOut1.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:ReplaceStreamRegex + } + + @Test + public void replaceContextStreamRegex() throws Exception + { + //ExStart:ReplaceContextStreamRegex + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Replacer.Create(ReplacerContext) + //ExFor:ReplacerContext + //ExFor:ReplacerContext.SetReplacement(Regex, String) + //ExFor:ReplacerContext.FindReplaceOptions + //ExSummary:Shows how to replace string with regex in the document using documents from the stream using context. + // There is a several ways to replace string with regex in the document using documents from the stream: + Regex pattern = new Regex("gr(a|e)y"); + String replacement = "lavender"; + + FileStream streamIn = new FileStream(getMyDir() + "Replace regex.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + ReplacerContext replacerContext = new ReplacerContext(); + replacerContext.setReplacementInternal(pattern, replacement); + replacerContext.getFindReplaceOptions().setFindWholeWordsOnly(false); + + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.ReplaceContextStreamRegex.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Replacer.create(replacerContext) + .fromInternal(streamIn) + .toInternal(streamOut, SaveFormat.DOCX) + .execute(); + } + finally { if (streamOut != null) streamOut.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:ReplaceContextStreamRegex + } + + @Test + public void replaceToImagesStreamRegex() throws Exception + { + //ExStart:ReplaceToImagesStreamRegex + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Replacer.ReplaceToImages(Stream, ImageSaveOptions, Regex, String, FindReplaceOptions) + //ExSummary:Shows how to replace string with regex in the document using documents from the stream and save result to images. + // There is a several ways to replace string with regex in the document using documents from the stream: + Regex pattern = new Regex("gr(a|e)y"); + String replacement = "lavender"; + + FileStream streamIn = new FileStream(getMyDir() + "Replace regex.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + Stream[] images = Replacer.replaceToImagesInternal(streamIn, new ImageSaveOptions(SaveFormat.PNG), pattern, replacement); + images = Replacer.replaceToImagesInternal(streamIn, new ImageSaveOptions(SaveFormat.PNG), pattern, replacement, new FindReplaceOptions(); { images.setFindWholeWordsOnly(false); }); + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:ReplaceToImagesStreamRegex + } + + //ExStart:BuildReportData + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:ReportBuilderOptions + //ExFor:ReportBuilderOptions.Options + //ExFor:ReportBuilder.BuildReport(String, String, Object, ReportBuilderOptions) + //ExFor:ReportBuilder.BuildReport(String, String, SaveFormat, Object, ReportBuilderOptions) + //ExSummary:Shows how to populate document with data. + @Test //ExSkip + public void buildReportData() throws Exception + { + // There is a several ways to populate document with data: + String doc = getMyDir() + "Reporting engine template - If greedy.docx"; + + AsposeData obj = new AsposeData(); { obj.setList(new ArrayList()); { obj.getList().add("abc"); } } + + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportWithObject.1.docx", obj); + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportWithObject.2.docx", obj, new ReportBuilderOptions(); { .setOptions(ReportBuildOptions.ALLOW_MISSING_MEMBERS); }); + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportWithObject.3.docx", SaveFormat.DOCX, obj); + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportWithObject.4.docx", SaveFormat.DOCX, obj, new ReportBuilderOptions(); { .setOptions(ReportBuildOptions.ALLOW_MISSING_MEMBERS); }); + } + + public static class AsposeData + { + public ArrayList getList() { return mList; }; public void setList(ArrayList value) { mList = value; }; + + private ArrayList mList; + } + //ExEnd:BuildReportData + + @Test + public void buildReportDataStream() throws Exception + { + //ExStart:BuildReportDataStream + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:ReportBuilder.BuildReport(Stream, Stream, SaveFormat, Object, ReportBuilderOptions) + //ExFor:ReportBuilder.BuildReport(Stream, Stream, SaveFormat, Object[], String[], ReportBuilderOptions) + //ExSummary:Shows how to populate document with data using documents from the stream. + // There is a several ways to populate document with data using documents from the stream: + AsposeData obj = new AsposeData(); { obj.setList(new ArrayList()); { obj.getList().add("abc"); } } + + FileStream streamIn = new FileStream(getMyDir() + "Reporting engine template - If greedy.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.BuildReportDataStream.1.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + ReportBuilder.buildReportInternal(streamIn, streamOut, SaveFormat.DOCX, obj); + } + finally { if (streamOut != null) streamOut.close(); } + + FileStream streamOut1 = new FileStream(getArtifactsDir() + "LowCode.BuildReportDataStream.2.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + ReportBuilder.buildReportInternal(streamIn, streamOut1, SaveFormat.DOCX, obj, new ReportBuilderOptions(); { .setOptions(ReportBuildOptions.ALLOW_MISSING_MEMBERS); }); + } + finally { if (streamOut1 != null) streamOut1.close(); } + + MessageTestClass sender = new MessageTestClass("LINQ Reporting Engine", "Hello World"); + FileStream streamOut2 = new FileStream(getArtifactsDir() + "LowCode.BuildReportDataStream.3.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + ReportBuilder.buildReportInternal(streamIn, streamOut2, SaveFormat.DOCX, new Object[] { sender }, new String[] { "s" }, new ReportBuilderOptions(); { .setOptions(ReportBuildOptions.ALLOW_MISSING_MEMBERS); }); + } + finally { if (streamOut2 != null) streamOut2.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:BuildReportDataStream + } + + //ExStart:BuildReportDataSource + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:ReportBuilder.BuildReport(String, String, Object, String, ReportBuilderOptions) + //ExFor:ReportBuilder.BuildReport(String, String, SaveFormat, Object, String, ReportBuilderOptions) + //ExFor:ReportBuilder.BuildReport(String, String, Object[], String[], ReportBuilderOptions) + //ExFor:ReportBuilder.BuildReport(String, String, SaveFormat, Object[], String[], ReportBuilderOptions) + //ExFor:ReportBuilder.BuildReportToImages(String, ImageSaveOptions, Object[], String[], ReportBuilderOptions) + //ExFor:ReportBuilder.Create(ReportBuilderContext) + //ExFor:ReportBuilderContext + //ExFor:ReportBuilderContext.ReportBuilderOptions + //ExFor:ReportBuilderContext.DataSources + //ExSummary:Shows how to populate document with data sources. + @Test //ExSkip + public void buildReportDataSource() throws Exception + { + // There is a several ways to populate document with data sources: + String doc = getMyDir() + "Report building.docx"; + + MessageTestClass sender = new MessageTestClass("LINQ Reporting Engine", "Hello World"); + + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportDataSource.1.docx", sender, "s"); + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportDataSource.2.docx", new Object[] { sender }, new String[] { "s" }); + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportDataSource.3.docx", sender, "s", new ReportBuilderOptions(); { .setOptions(ReportBuildOptions.ALLOW_MISSING_MEMBERS); }); + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportDataSource.4.docx", SaveFormat.DOCX, sender, "s"); + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportDataSource.5.docx", SaveFormat.DOCX, new Object[] { sender }, new String[] { "s" }); + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportDataSource.6.docx", SaveFormat.DOCX, sender, "s", new ReportBuilderOptions(); { .setOptions(ReportBuildOptions.ALLOW_MISSING_MEMBERS); }); + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportDataSource.7.docx", SaveFormat.DOCX, new Object[] { sender }, new String[] { "s" }, new ReportBuilderOptions(); { .setOptions(ReportBuildOptions.ALLOW_MISSING_MEMBERS); }); + ReportBuilder.buildReport(doc, getArtifactsDir() + "LowCode.BuildReportDataSource.8.docx", new Object[] { sender }, new String[] { "s" }, new ReportBuilderOptions(); { .setOptions(ReportBuildOptions.ALLOW_MISSING_MEMBERS); }); + + Stream[] images = ReportBuilder.buildReportToImagesInternal(doc, new ImageSaveOptions(SaveFormat.PNG), new Object[] { sender }, new String[] { "s" }, new ReportBuilderOptions(); { images.setOptions(ReportBuildOptions.ALLOW_MISSING_MEMBERS); }); + + ReportBuilderContext reportBuilderContext = new ReportBuilderContext(); + reportBuilderContext.getReportBuilderOptions().setMissingMemberMessage("Missed members"); + msDictionary.add(reportBuilderContext.getDataSources(), sender, "s"); + + ReportBuilder.create(reportBuilderContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.BuildReportDataSource.9.docx") + .execute(); + } + + public static class MessageTestClass + { + public String getName() { return mName; }; public void setName(String value) { mName = value; }; + + private String mName; + public String getMessage() { return mMessage; }; public void setMessage(String value) { mMessage = value; }; + + private String mMessage; + + public MessageTestClass(String name, String message) + { + setName(name); + setMessage(message); + } + } + //ExEnd:BuildReportDataSource + + @Test + public void buildReportDataSourceStream() throws Exception + { + //ExStart:BuildReportDataSourceStream + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:ReportBuilder.BuildReport(Stream, Stream, SaveFormat, Object, String, ReportBuilderOptions) + //ExFor:ReportBuilder.BuildReportToImages(Stream, ImageSaveOptions, Object[], String[], ReportBuilderOptions) + //ExFor:ReportBuilder.Create(ReportBuilderContext) + //ExFor:ReportBuilderContext + //ExFor:ReportBuilderContext.ReportBuilderOptions + //ExFor:ReportBuilderContext.DataSources + //ExSummary:Shows how to populate document with data sources using documents from the stream. + // There is a several ways to populate document with data sources using documents from the stream: + MessageTestClass sender = new MessageTestClass("LINQ Reporting Engine", "Hello World"); + + FileStream streamIn = new FileStream(getMyDir() + "Report building.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.BuildReportDataSourceStream.1.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + ReportBuilder.buildReportInternal(streamIn, streamOut, SaveFormat.DOCX, new Object[] { sender }, new String[] { "s" }); + } + finally { if (streamOut != null) streamOut.close(); } + + FileStream streamOut1 = new FileStream(getArtifactsDir() + "LowCode.BuildReportDataSourceStream.2.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + ReportBuilder.buildReportInternal(streamIn, streamOut1, SaveFormat.DOCX, sender, "s"); + } + finally { if (streamOut1 != null) streamOut1.close(); } + + FileStream streamOut2 = new FileStream(getArtifactsDir() + "LowCode.BuildReportDataSourceStream.3.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + ReportBuilder.buildReportInternal(streamIn, streamOut2, SaveFormat.DOCX, sender, "s", new ReportBuilderOptions(); { .setOptions(ReportBuildOptions.ALLOW_MISSING_MEMBERS); }); + } + finally { if (streamOut2 != null) streamOut2.close(); } + + Stream[] images = ReportBuilder.buildReportToImagesInternal(streamIn, new ImageSaveOptions(SaveFormat.PNG), new Object[] { sender }, new String[] { "s" }, new ReportBuilderOptions(); { images.setOptions(ReportBuildOptions.ALLOW_MISSING_MEMBERS); }); + + ReportBuilderContext reportBuilderContext = new ReportBuilderContext(); + reportBuilderContext.getReportBuilderOptions().setMissingMemberMessage("Missed members"); + msDictionary.add(reportBuilderContext.getDataSources(), sender, "s"); + + FileStream streamOut3 = new FileStream(getArtifactsDir() + "LowCode.BuildReportDataSourceStream.4.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + ReportBuilder.create(reportBuilderContext) + .fromInternal(streamIn) + .toInternal(streamOut3, SaveFormat.DOCX) + .execute(); + } + finally { if (streamOut3 != null) streamOut3.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:BuildReportDataSourceStream + } + + @Test + public void removeBlankPages() throws Exception + { + //ExStart:RemoveBlankPages + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Splitter.RemoveBlankPages(String, String) + //ExFor:Splitter.RemoveBlankPages(String, String, SaveFormat) + //ExSummary:Shows how to remove empty pages from the document. + // There is a several ways to remove empty pages from the document: + String doc = getMyDir() + "Blank pages.docx"; + + Splitter.removeBlankPages(doc, getArtifactsDir() + "LowCode.RemoveBlankPages.1.docx"); + Splitter.removeBlankPages(doc, getArtifactsDir() + "LowCode.RemoveBlankPages.2.docx", SaveFormat.DOCX); + //ExEnd:RemoveBlankPages + } + + @Test + public void removeBlankPagesStream() throws Exception + { + //ExStart:RemoveBlankPagesStream + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Splitter.RemoveBlankPages(Stream, Stream, SaveFormat) + //ExSummary:Shows how to remove empty pages from the document from the stream. + FileStream streamIn = new FileStream(getMyDir() + "Blank pages.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.RemoveBlankPagesStream.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Splitter.removeBlankPagesInternal(streamIn, streamOut, SaveFormat.DOCX); + } + finally { if (streamOut != null) streamOut.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:RemoveBlankPagesStream + } + + @Test + public void extractPages() throws Exception + { + //ExStart:ExtractPages + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Splitter.ExtractPages(String, String, int, int) + //ExFor:Splitter.ExtractPages(String, String, SaveFormat, int, int) + //ExSummary:Shows how to extract pages from the document. + // There is a several ways to extract pages from the document: + String doc = getMyDir() + "Big document.docx"; + + Splitter.extractPages(doc, getArtifactsDir() + "LowCode.ExtractPages.1.docx", 0, 2); + Splitter.extractPages(doc, getArtifactsDir() + "LowCode.ExtractPages.2.docx", SaveFormat.DOCX, 0, 2); + //ExEnd:ExtractPages + } + + @Test + public void extractPagesStream() throws Exception + { + //ExStart:ExtractPagesStream + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Splitter.ExtractPages(Stream, Stream, SaveFormat, int, int) + //ExSummary:Shows how to extract pages from the document from the stream. + FileStream streamIn = new FileStream(getMyDir() + "Big document.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.ExtractPagesStream.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Splitter.extractPagesInternal(streamIn, streamOut, SaveFormat.DOCX, 0, 2); + } + finally { if (streamOut != null) streamOut.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:ExtractPagesStream + } + + @Test + public void splitDocument() throws Exception + { + //ExStart:SplitDocument + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:SplitCriteria + //ExFor:SplitOptions.SplitCriteria + //ExFor:Splitter.Split(String, String, SplitOptions) + //ExFor:Splitter.Split(String, String, SaveFormat, SplitOptions) + //ExSummary:Shows how to split document by pages. + String doc = getMyDir() + "Big document.docx"; + + SplitOptions options = new SplitOptions(); + options.setSplitCriteria(SplitCriteria.PAGE); + Splitter.split(doc, getArtifactsDir() + "LowCode.SplitDocument.1.docx", options); + Splitter.split(doc, getArtifactsDir() + "LowCode.SplitDocument.2.docx", SaveFormat.DOCX, options); + //ExEnd:SplitDocument + } + + @Test + public void splitContextDocument() throws Exception + { + //ExStart:SplitContextDocument + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Splitter.Create(SplitterContext) + //ExFor:SplitterContext + //ExFor:SplitterContext.SplitOptions + //ExSummary:Shows how to split document by pages using context. + String doc = getMyDir() + "Big document.docx"; + + SplitterContext splitterContext = new SplitterContext(); + splitterContext.getSplitOptions().setSplitCriteria(SplitCriteria.PAGE); + + Splitter.create(splitterContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.SplitContextDocument.docx") + .execute(); + //ExEnd:SplitContextDocument + } + + @Test + public void splitDocumentStream() throws Exception + { + //ExStart:SplitDocumentStream + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Splitter.Split(Stream, SaveFormat, SplitOptions) + //ExSummary:Shows how to split document from the stream by pages. + FileStream streamIn = new FileStream(getMyDir() + "Big document.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + SplitOptions options = new SplitOptions(); + options.setSplitCriteria(SplitCriteria.PAGE); + Stream[] stream = Splitter.splitInternal(streamIn, SaveFormat.DOCX, options); + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:SplitDocumentStream + } + + @Test + public void splitContextDocumentStream() throws Exception + { + //ExStart:SplitContextDocumentStream + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Splitter.Create(SplitterContext) + //ExFor:SplitterContext + //ExFor:SplitterContext.SplitOptions + //ExSummary:Shows how to split document from the stream by pages using context. + FileStream streamIn = new FileStream(getMyDir() + "Big document.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + SplitterContext splitterContext = new SplitterContext(); + splitterContext.getSplitOptions().setSplitCriteria(SplitCriteria.PAGE); + + ArrayList pages = new ArrayList(); + Splitter.create(splitterContext) + .fromInternal(streamIn) + .to(pages, SaveFormat.DOCX) + .execute(); + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:SplitContextDocumentStream + } + + @Test + public void watermarkText() throws Exception + { + //ExStart:WatermarkText + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Watermarker.SetText(String, String, String) + //ExFor:Watermarker.SetText(String, String, String, TextWatermarkOptions) + //ExFor:Watermarker.SetText(String, String, SaveFormat, String, TextWatermarkOptions) + //ExSummary:Shows how to insert watermark text to the document. + String doc = getMyDir() + "Big document.docx"; + String watermarkText = "This is a watermark"; + + Watermarker.setText(doc, getArtifactsDir() + "LowCode.WatermarkText.1.docx", watermarkText); + Watermarker.setText(doc, getArtifactsDir() + "LowCode.WatermarkText.2.docx", SaveFormat.DOCX, watermarkText); + TextWatermarkOptions watermarkOptions = new TextWatermarkOptions(); + watermarkOptions.setColor(Color.RED); + Watermarker.setText(doc, getArtifactsDir() + "LowCode.WatermarkText.3.docx", watermarkText, watermarkOptions); + Watermarker.setText(doc, getArtifactsDir() + "LowCode.WatermarkText.4.docx", SaveFormat.DOCX, watermarkText, watermarkOptions); + //ExEnd:WatermarkText + } + + @Test + public void watermarkContextText() throws Exception + { + //ExStart:WatermarkContextText + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Watermarker.Create(WatermarkerContext) + //ExFor:WatermarkerContext + //ExFor:WatermarkerContext.TextWatermark + //ExFor:WatermarkerContext.TextWatermarkOptions + //ExSummary:Shows how to insert watermark text to the document using context. + String doc = getMyDir() + "Big document.docx"; + String watermarkText = "This is a watermark"; + + WatermarkerContext watermarkerContext = new WatermarkerContext(); + watermarkerContext.setTextWatermark(watermarkText); + + watermarkerContext.getTextWatermarkOptions().setColor(Color.RED); + + Watermarker.create(watermarkerContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.WatermarkContextText.docx") + .execute(); + //ExEnd:WatermarkContextText + } + + @Test + public void watermarkTextStream() throws Exception + { + //ExStart:WatermarkTextStream + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Watermarker.SetText(Stream, Stream, SaveFormat, String, TextWatermarkOptions) + //ExSummary:Shows how to insert watermark text to the document from the stream. + String watermarkText = "This is a watermark"; + + FileStream streamIn = new FileStream(getMyDir() + "Document.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.WatermarkTextStream.1.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Watermarker.setTextInternal(streamIn, streamOut, SaveFormat.DOCX, watermarkText); + } + finally { if (streamOut != null) streamOut.close(); } + + FileStream streamOut1 = new FileStream(getArtifactsDir() + "LowCode.WatermarkTextStream.2.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + TextWatermarkOptions options = new TextWatermarkOptions(); + options.setColor(Color.RED); + Watermarker.setTextInternal(streamIn, streamOut1, SaveFormat.DOCX, watermarkText, options); + } + finally { if (streamOut1 != null) streamOut1.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:WatermarkTextStream + } + + @Test + public void watermarkContextTextStream() throws Exception + { + //ExStart:WatermarkContextTextStream + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Watermarker.Create(WatermarkerContext) + //ExFor:WatermarkerContext + //ExFor:WatermarkerContext.TextWatermark + //ExFor:WatermarkerContext.TextWatermarkOptions + //ExSummary:Shows how to insert watermark text to the document from the stream using context. + String watermarkText = "This is a watermark"; + + FileStream streamIn = new FileStream(getMyDir() + "Document.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + WatermarkerContext watermarkerContext = new WatermarkerContext(); + watermarkerContext.setTextWatermark(watermarkText); + + watermarkerContext.getTextWatermarkOptions().setColor(Color.RED); + + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.WatermarkContextTextStream.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Watermarker.create(watermarkerContext) + .fromInternal(streamIn) + .toInternal(streamOut, SaveFormat.DOCX) + .execute(); + } + finally { if (streamOut != null) streamOut.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:WatermarkContextTextStream + } + + @Test + public void watermarkImage() throws Exception + { + //ExStart:WatermarkImage + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Watermarker.SetImage(String, String, String) + //ExFor:Watermarker.SetImage(String, String, String, ImageWatermarkOptions) + //ExFor:Watermarker.SetImage(String, String, SaveFormat, String, ImageWatermarkOptions) + //ExSummary:Shows how to insert watermark image to the document. + String doc = getMyDir() + "Document.docx"; + String watermarkImage = getImageDir() + "Logo.jpg"; + + Watermarker.setImage(doc, getArtifactsDir() + "LowCode.SetWatermarkImage.1.docx", watermarkImage); + Watermarker.setImage(doc, getArtifactsDir() + "LowCode.SetWatermarkText.2.docx", SaveFormat.DOCX, watermarkImage); + + ImageWatermarkOptions options = new ImageWatermarkOptions(); + options.setScale(50.0); + Watermarker.setImage(doc, getArtifactsDir() + "LowCode.SetWatermarkText.3.docx", watermarkImage, options); + Watermarker.setImage(doc, getArtifactsDir() + "LowCode.SetWatermarkText.4.docx", SaveFormat.DOCX, watermarkImage, options); + //ExEnd:WatermarkImage + } + + @Test + public void watermarkContextImage() throws Exception + { + //ExStart:WatermarkContextImage + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Watermarker.Create(WatermarkerContext) + //ExFor:WatermarkerContext + //ExFor:WatermarkerContext.ImageWatermark + //ExFor:WatermarkerContext.ImageWatermarkOptions + //ExSummary:Shows how to insert watermark image to the document using context. + String doc = getMyDir() + "Document.docx"; + String watermarkImage = getImageDir() + "Logo.jpg"; + + + WatermarkerContext watermarkerContext = new WatermarkerContext(); + watermarkerContext.setImageWatermark(File.readAllBytes(watermarkImage)); + + watermarkerContext.getImageWatermarkOptions().setScale(50.0); + + Watermarker.create(watermarkerContext) + .from(doc) + .to(getArtifactsDir() + "LowCode.WatermarkContextImage.docx") + .execute(); + //ExEnd:WatermarkContextImage + } + + @Test + public void watermarkImageStream() throws Exception + { + //ExStart:WatermarkImageStream + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Watermarker.SetImage(Stream, Stream, SaveFormat, Image, ImageWatermarkOptions) + //ExSummary:Shows how to insert watermark image to the document from a stream. + FileStream streamIn = new FileStream(getMyDir() + "Document.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.SetWatermarkText.1.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Watermarker.setImageInternal(streamIn, streamOut, SaveFormat.DOCX, ImageIO.read(getImageDir() + "Logo.jpg")); + } + finally { if (streamOut != null) streamOut.close(); } + + FileStream streamOut1 = new FileStream(getArtifactsDir() + "LowCode.SetWatermarkText.2.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Watermarker.setImageInternal(streamIn, streamOut1, SaveFormat.DOCX, ImageIO.read(getImageDir() + "Logo.jpg"), new ImageWatermarkOptions(); { .setScale(50.0); }); + } + finally { if (streamOut1 != null) streamOut1.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:WatermarkImageStream + } + + @Test + public void watermarkContextImageStream() throws Exception + { + //ExStart:WatermarkContextImageStream + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Watermarker.Create(WatermarkerContext) + //ExFor:WatermarkerContext + //ExFor:WatermarkerContext.ImageWatermark + //ExFor:WatermarkerContext.ImageWatermarkOptions + //ExSummary:Shows how to insert watermark image to the document from a stream using context. + String watermarkImage = getImageDir() + "Logo.jpg"; + + FileStream streamIn = new FileStream(getMyDir() + "Document.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + WatermarkerContext watermarkerContext = new WatermarkerContext(); + watermarkerContext.setImageWatermark(File.readAllBytes(watermarkImage)); + + watermarkerContext.getImageWatermarkOptions().setScale(50.0); + + FileStream streamOut = new FileStream(getArtifactsDir() + "LowCode.WatermarkContextImageStream.docx", FileMode.CREATE, FileAccess.READ_WRITE); + try /*JAVA: was using*/ + { + Watermarker.create(watermarkerContext) + .fromInternal(streamIn) + .toInternal(streamOut, SaveFormat.DOCX) + .execute(); + } + finally { if (streamOut != null) streamOut.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:WatermarkContextImageStream + } + + @Test + public void watermarkTextToImages() throws Exception + { + //ExStart:WatermarkTextToImages + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Watermarker.SetWatermarkToImages(String, ImageSaveOptions, String, TextWatermarkOptions) + //ExSummary:Shows how to insert watermark text to the document and save result to images. + String doc = getMyDir() + "Big document.docx"; + String watermarkText = "This is a watermark"; + + Stream[] images = Watermarker.setWatermarkToImagesInternal(doc, new ImageSaveOptions(SaveFormat.PNG), watermarkText); + + TextWatermarkOptions watermarkOptions = new TextWatermarkOptions(); + watermarkOptions.setColor(Color.RED); + images = Watermarker.setWatermarkToImagesInternal(doc, new ImageSaveOptions(SaveFormat.PNG), watermarkText, watermarkOptions); + //ExEnd:WatermarkTextToImages + } + + @Test + public void watermarkTextToImagesStream() throws Exception + { + //ExStart:WatermarkTextToImagesStream + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Watermarker.SetWatermarkToImages(Stream, ImageSaveOptions, String, TextWatermarkOptions) + //ExSummary:Shows how to insert watermark text to the document from the stream and save result to images. + String watermarkText = "This is a watermark"; + + FileStream streamIn = new FileStream(getMyDir() + "Document.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + Stream[] images = Watermarker.setWatermarkToImagesInternal(streamIn, new ImageSaveOptions(SaveFormat.PNG), watermarkText); + + TextWatermarkOptions watermarkOptions = new TextWatermarkOptions(); + watermarkOptions.setColor(Color.RED); + images = Watermarker.setWatermarkToImagesInternal(streamIn, new ImageSaveOptions(SaveFormat.PNG), watermarkText, watermarkOptions); + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:WatermarkTextToImagesStream + } + + @Test + public void watermarkImageToImages() throws Exception + { + //ExStart:WatermarkImageToImages + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Watermarker.SetWatermarkToImages(String, ImageSaveOptions, Byte[], ImageWatermarkOptions) + //ExSummary:Shows how to insert watermark image to the document and save result to images. + String doc = getMyDir() + "Document.docx"; + String watermarkImage = getImageDir() + "Logo.jpg"; + + Watermarker.setWatermarkToImagesInternal(doc, new ImageSaveOptions(SaveFormat.PNG), File.readAllBytes(watermarkImage)); + + ImageWatermarkOptions options = new ImageWatermarkOptions(); + options.setScale(50.0); + Watermarker.setWatermarkToImagesInternal(doc, new ImageSaveOptions(SaveFormat.PNG), File.readAllBytes(watermarkImage), options); + //ExEnd:WatermarkImageToImages + } + + @Test + public void watermarkImageToImagesStream() throws Exception + { + //ExStart:WatermarkImageToImagesStream + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:Watermarker.SetWatermarkToImages(Stream, ImageSaveOptions, Stream, ImageWatermarkOptions) + //ExSummary:Shows how to insert watermark image to the document from a stream and save result to images. + String watermarkImage = getImageDir() + "Logo.jpg"; + + FileStream streamIn = new FileStream(getMyDir() + "Document.docx", FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + FileStream imageStream = new FileStream(watermarkImage, FileMode.OPEN, FileAccess.READ); + try /*JAVA: was using*/ + { + Watermarker.setWatermarkToImagesInternal(streamIn, new ImageSaveOptions(SaveFormat.PNG), imageStream); + Watermarker.setWatermarkToImagesInternal(streamIn, new ImageSaveOptions(SaveFormat.PNG), imageStream, new ImageWatermarkOptions(); { .setScale(50.0); }); + } + finally { if (imageStream != null) imageStream.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + //ExEnd:WatermarkImageToImagesStream + } + + //JAVA-added for string switch emulation + private static final StringSwitchMap gStringSwitchMap = new StringSwitchMap + ( + "PDF", + "HTML", + "XPS", + "JPEG", + "PNG", + "TIFF", + "BMP" + ); + +} + diff --git a/Examples/ApiExamples/JavaPorting/ExMailMerge.java b/Examples/ApiExamples/JavaPorting/ExMailMerge.java new file mode 100644 index 00000000..db83b934 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExMailMerge.java @@ -0,0 +1,2058 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import org.testng.Assert; +import com.aspose.words.ContentDisposition; +import com.aspose.ms.System.msConsole; +import com.aspose.words.net.System.Data.DataTable; +import com.aspose.words.net.System.Data.DataView; +import com.aspose.words.net.System.Data.DataSet; +import com.aspose.ms.NUnit.Framework.msAssert; +import java.util.ArrayList; +import com.aspose.words.MailMergeRegionInfo; +import com.aspose.words.FieldQuote; +import com.aspose.words.FieldType; +import com.aspose.words.MailMergeCleanupOptions; +import com.aspose.words.FieldMergeField; +import com.aspose.words.MappedDataFieldCollection; +import java.util.Iterator; +import java.util.Map; +import com.aspose.words.FieldAddressBlock; +import com.aspose.words.FieldGreetingLine; +import com.aspose.words.Field; +import com.aspose.words.IMailMergeCallback; +import com.aspose.words.net.System.Data.DataRow; +import com.aspose.words.FieldIf; +import com.aspose.words.SectionStart; +import com.aspose.words.Section; +import com.aspose.ms.System.IO.File; +import com.aspose.words.MailMergeSettings; +import com.aspose.words.MailMergeMainDocumentType; +import com.aspose.words.MailMergeCheckErrors; +import com.aspose.words.MailMergeDataType; +import com.aspose.words.MailMergeDestination; +import com.aspose.words.Odso; +import com.aspose.words.OdsoDataSourceType; +import com.aspose.words.NodeType; +import com.aspose.words.OdsoFieldMapDataCollection; +import com.aspose.words.OdsoFieldMapData; +import com.aspose.words.OdsoFieldMappingType; +import com.aspose.words.OdsoRecipientDataCollection; +import com.aspose.words.OdsoRecipientData; +import com.aspose.ms.System.Globalization.msCultureInfo; +import com.aspose.ms.System.Threading.CurrentThread; +import com.aspose.ms.System.DateTime; +import com.aspose.words.FieldUpdateCultureSource; +import com.aspose.words.HtmlInsertOptions; +import com.aspose.words.MustacheTag; +import org.testng.annotations.DataProvider; + + +@Test +public class ExMailMerge extends ApiExampleBase +{ + @Test + public void executeArray() throws Exception + { + HttpResponse response = null; + + //ExStart + //ExFor:MailMerge.Execute(String[], Object[]) + //ExFor:ContentDisposition + //ExFor:Document.Save(HttpResponse,String,ContentDisposition,SaveOptions) + //ExSummary:Shows how to perform a mail merge, and then save the document to the client browser. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField(" MERGEFIELD FullName "); + builder.insertParagraph(); + builder.insertField(" MERGEFIELD Company "); + builder.insertParagraph(); + builder.insertField(" MERGEFIELD Address "); + builder.insertParagraph(); + builder.insertField(" MERGEFIELD City "); + + doc.getMailMerge().execute(new String[] { "FullName", "Company", "Address", "City" }, + new Object[] { "James Bond", "MI5 Headquarters", "Milbank", "London" }); + + // Send the document to the client browser. + //Thrown because HttpResponse is null in the test. + Assert.Throws(() => doc.Save(response, "Artifacts/MailMerge.ExecuteArray.docx", ContentDisposition.INLINE, null)); + + // We will need to close this response manually to ensure that we do not add any superfluous content to the document after saving. + Assert.Throws(() => response.End()); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + + TestUtil.mailMergeMatchesArray(new String[] { new String[] { "James Bond", "MI5 Headquarters", "Milbank", "London" } }, doc, true); + } + + @Test (groups = "IgnoreOnJenkins") + public void executeDataReader() throws Exception + { + //ExStart + //ExFor:MailMerge.Execute(IDataReader) + //ExSummary:Shows how to run a mail merge using data from a data reader. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Product:\t"); + builder.insertField(" MERGEFIELD ProductName"); + builder.write("\nSupplier:\t"); + builder.insertField(" MERGEFIELD CompanyName"); + builder.writeln(); + builder.insertField(" MERGEFIELD QuantityPerUnit"); + builder.write(" for $"); + builder.insertField(" MERGEFIELD UnitPrice"); + + // Create a connection string that points to the "Northwind" database file + // in our local file system, open a connection, and set up an SQL query. + String connectionString = "Provider = Microsoft.ACE.OLEDB.12.0; Data Source=" + getDatabaseDir() + "Northwind.accdb"; + String query = + "SELECT Products.ProductName, Suppliers.CompanyName, Products.QuantityPerUnit, Products.UnitPrice\n FROM Products \n INNER JOIN Suppliers \n ON Products.SupplierID = Suppliers.SupplierID"; + + OleDbConnection connection = new OleDbConnection(connectionString); + try /*JAVA: was using*/ + { + // Create an SQL command that will source data for our mail merge. + // The names of the table's columns that this SELECT statement will return + // will need to correspond to the merge fields we placed above. + OleDbCommand command = new OleDbCommand(query, connection); + command.CommandText = query; + try + { + connection.Open(); + OleDbDataReader reader = command.ExecuteReader(); + try /*JAVA: was using*/ + { + // Take the data from the reader and use it in the mail merge. + doc.getMailMerge().execute(reader); + } + finally { if (reader != null) reader.close(); } + } + catch (Exception ex) + { + System.out.println(ex.getMessage()); + } + } + finally { if (connection != null) connection.close(); } + + doc.save(getArtifactsDir() + "MailMerge.ExecuteDataReader.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "MailMerge.ExecuteDataReader.docx"); + + TestUtil.mailMergeMatchesQueryResult(getDatabaseDir() + "Northwind.accdb", query, doc, true); + } + + //ExStart + //ExFor:MailMerge.ExecuteADO(Object) + //ExSummary:Shows how to run a mail merge with data from an ADO dataset. + @Test (enabled = false, description = "Run only under x86") //ExSkip + public void executeADO() throws Exception + { + Document doc = createSourceDocADOMailMerge(); + + // To work with ADO DataSets, we will need to add a reference to the Microsoft ActiveX Data Objects library, + // which is included in the .NET distribution and stored in "adodb.dll". + Interop.ADODB.Connection connection = new Interop.ADODB.Connection(); + + // Create a connection string that points to the "Northwind" database file + // in our local file system and open a connection. + String connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + getDatabaseDir() + "Northwind.accdb"; + connection.Open(connectionString); + + // Populate our DataSet by running an SQL command on our database. + // The names of the columns in the result table will need to correspond + // to the values of the MERGEFIELDS that will accommodate our data. + final String COMMAND = "SELECT ProductName, QuantityPerUnit, UnitPrice FROM Products"; + + Interop.ADODB.Recordset recordset = new Interop.ADODB.Recordset(); + recordset.Open(COMMAND, connection); + + // Execute the mail merge and save the document. + doc.getMailMerge().ExecuteADO(recordset); + doc.save(getArtifactsDir() + "MailMerge.ExecuteADO.docx"); + TestUtil.mailMergeMatchesQueryResult(getDatabaseDir() + "Northwind.accdb", COMMAND, doc, true); //ExSkip + } + + /// + /// Create a blank document and populate it with MERGEFIELDS that will accept data when a mail merge is executed. + /// + private static Document createSourceDocADOMailMerge() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Product:\t"); + builder.insertField(" MERGEFIELD ProductName"); + builder.writeln(); + builder.insertField(" MERGEFIELD QuantityPerUnit"); + builder.write(" for $"); + builder.insertField(" MERGEFIELD UnitPrice"); + + return doc; + } + //ExEnd + + //ExStart + //ExFor:MailMerge.ExecuteWithRegionsADO(Object,String) + //ExSummary:Shows how to run a mail merge with multiple regions, compiled with data from an ADO dataset. + @Test (enabled = false, description = "Run only under x86") //ExSkip + public void executeWithRegionsADO() throws Exception + { + Document doc = createSourceDocADOMailMergeWithRegions(); + + // To work with ADO DataSets, we will need to add a reference to the Microsoft ActiveX Data Objects library, + // which is included in the .NET distribution and stored in "adodb.dll". + Interop.ADODB.Connection connection = new Interop.ADODB.Connection(); + + // Create a connection string that points to the "Northwind" database file + // in our local file system and open a connection. + String connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + getDatabaseDir() + "Northwind.accdb"; + connection.Open(connectionString); + + // Populate our DataSet by running an SQL command on our database. + // The names of the columns in the result table will need to correspond + // to the values of the MERGEFIELDS that will accommodate our data. + String command = "SELECT FirstName, LastName, City FROM Employees"; + + Interop.ADODB.Recordset recordset = new Interop.ADODB.Recordset(); + recordset.Open(command, connection); + + // Run a mail merge on just the first region, filling its MERGEFIELDS with data from the record set. + doc.getMailMerge().ExecuteWithRegionsADO(recordset, "MergeRegion1"); + + // Close the record set and reopen it with data from another SQL query. + command = "SELECT * FROM Customers"; + + recordset.Close(); + recordset.Open(command, connection); + + // Run a second mail merge on the second region and save the document. + doc.getMailMerge().ExecuteWithRegionsADO(recordset, "MergeRegion2"); + + doc.save(getArtifactsDir() + "MailMerge.ExecuteWithRegionsADO.docx"); + + TestUtil.mailMergeMatchesQueryResultMultiple(getDatabaseDir() + "Northwind.accdb", new String[] { "SELECT FirstName, LastName, City FROM Employees", "SELECT ContactName, Address, City FROM Customers" }, new Document(getArtifactsDir() + "MailMerge.ExecuteWithRegionsADO.docx"), false); //ExSkip + } + + /// + /// Create a document with two mail merge regions. + /// + private static Document createSourceDocADOMailMergeWithRegions() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("\tEmployees: "); + builder.insertField(" MERGEFIELD TableStart:MergeRegion1"); + builder.insertField(" MERGEFIELD FirstName"); + builder.write(", "); + builder.insertField(" MERGEFIELD LastName"); + builder.write(", "); + builder.insertField(" MERGEFIELD City"); + builder.insertField(" MERGEFIELD TableEnd:MergeRegion1"); + builder.insertParagraph(); + + builder.writeln("\tCustomers: "); + builder.insertField(" MERGEFIELD TableStart:MergeRegion2"); + builder.insertField(" MERGEFIELD ContactName"); + builder.write(", "); + builder.insertField(" MERGEFIELD Address"); + builder.write(", "); + builder.insertField(" MERGEFIELD City"); + builder.insertField(" MERGEFIELD TableEnd:MergeRegion2"); + + return doc; + } + //ExEnd + + //ExStart + //ExFor:Document + //ExFor:MailMerge + //ExFor:MailMerge.Execute(DataTable) + //ExFor:MailMerge.Execute(DataRow) + //ExFor:Document.MailMerge + //ExSummary:Shows how to execute a mail merge with data from a DataTable. + @Test //ExSkip + public void executeDataTable() throws Exception + { + DataTable table = new DataTable("Test"); + table.getColumns().add("CustomerName"); + table.getColumns().add("Address"); + table.getRows().add(new Object[] { "Thomas Hardy", "120 Hanover Sq., London" }); + table.getRows().add(new Object[] { "Paolo Accorti", "Via Monte Bianco 34, Torino" }); + + // Below are two ways of using a DataTable as the data source for a mail merge. + // 1 - Use the entire table for the mail merge to create one output mail merge document for every row in the table: + Document doc = createSourceDocExecuteDataTable(); + + doc.getMailMerge().execute(table); + + doc.save(getArtifactsDir() + "MailMerge.ExecuteDataTable.WholeTable.docx"); + + // 2 - Use one row of the table to create one output mail merge document: + doc = createSourceDocExecuteDataTable(); + + doc.getMailMerge().execute(table.getRows().get(1)); + + doc.save(getArtifactsDir() + "MailMerge.ExecuteDataTable.OneRow.docx"); + testADODataTable(new Document(getArtifactsDir() + "MailMerge.ExecuteDataTable.WholeTable.docx"), new Document(getArtifactsDir() + "MailMerge.ExecuteDataTable.OneRow.docx"), table); //ExSkip + } + + /// + /// Creates a mail merge source document. + /// + private static Document createSourceDocExecuteDataTable() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField(" MERGEFIELD CustomerName "); + builder.insertParagraph(); + builder.insertField(" MERGEFIELD Address "); + + return doc; + } + //ExEnd + + private void testADODataTable(Document docWholeTable, Document docOneRow, DataTable table) + { + TestUtil.mailMergeMatchesDataTable(table, docWholeTable, true); + + DataTable rowAsTable = new DataTable(); + rowAsTable.importRow(table.getRows().get(1)); + + TestUtil.mailMergeMatchesDataTable(rowAsTable, docOneRow, true); + } + + @Test + public void executeDataView() throws Exception + { + //ExStart + //ExFor:MailMerge.Execute(DataView) + //ExSummary:Shows how to edit mail merge data with a DataView. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.write("Congratulations "); + builder.insertField(" MERGEFIELD Name"); + builder.write(" for passing with a grade of "); + builder.insertField(" MERGEFIELD Grade"); + + // Create a data table that our mail merge will source data from. + DataTable table = new DataTable("ExamResults"); + table.getColumns().add("Name"); + table.getColumns().add("Grade"); + table.getRows().add(new Object[] { "John Doe", "67" }); + table.getRows().add(new Object[] { "Jane Doe", "81" }); + table.getRows().add(new Object[] { "John Cardholder", "47" }); + table.getRows().add(new Object[] { "Joe Bloggs", "75" }); + + // We can use a data view to alter the mail merge data without making changes to the data table itself. + DataView view = new DataView(table); + view.setSort("Grade DESC"); + view.setRowFilter("Grade >= 50"); + + // Our data view sorts the entries in descending order along the "Grade" column + // and filters out rows with values of less than 50 on that column. + // Three out of the four rows fit those criteria so that the output document will contain three merge documents. + doc.getMailMerge().execute(view); + + doc.save(getArtifactsDir() + "MailMerge.ExecuteDataView.docx"); + //ExEnd + + TestUtil.mailMergeMatchesDataTable(view.toTable(), new Document(getArtifactsDir() + "MailMerge.ExecuteDataView.docx"), true); + } + + //ExStart + //ExFor:MailMerge.ExecuteWithRegions(DataSet) + //ExSummary:Shows how to execute a nested mail merge with two merge regions and two data tables. + @Test//ExSkip + public void executeWithRegionsNested() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Normally, MERGEFIELDs contain the name of a column of a mail merge data source. + // Instead, we can use "TableStart:" and "TableEnd:" prefixes to begin/end a mail merge region. + // Each region will belong to a table with a name that matches the string immediately after the prefix's colon. + builder.insertField(" MERGEFIELD TableStart:Customers"); + + // This MERGEFIELD is inside the mail merge region of the "Customers" table. + // When we execute the mail merge, this field will receive data from rows in a data source named "Customers". + builder.write("Orders for "); + builder.insertField(" MERGEFIELD CustomerName"); + builder.write(":"); + + // Create column headers for a table that will contain values from a second inner region. + builder.startTable(); + builder.insertCell(); + builder.write("Item"); + builder.insertCell(); + builder.write("Quantity"); + builder.endRow(); + + // Create a second mail merge region inside the outer region for a table named "Orders". + // The "Orders" table has a many-to-one relationship with the "Customers" table on the "CustomerID" column. + builder.insertCell(); + builder.insertField(" MERGEFIELD TableStart:Orders"); + builder.insertField(" MERGEFIELD ItemName"); + builder.insertCell(); + builder.insertField(" MERGEFIELD Quantity"); + + // End the inner region, and then end the outer region. The opening and closing of a mail merge region must + // happen on the same row of a table. + builder.insertField(" MERGEFIELD TableEnd:Orders"); + builder.endTable(); + + builder.insertField(" MERGEFIELD TableEnd:Customers"); + + // Create a dataset that contains the two tables with the required names and relationships. + // Each merge document for each row of the "Customers" table of the outer merge region will perform its mail merge on the "Orders" table. + // Each merge document will display all rows of the latter table whose "CustomerID" column values match the current "Customers" table row. + DataSet customersAndOrders = createDataSet(); + doc.getMailMerge().executeWithRegions(customersAndOrders); + + doc.save(getArtifactsDir() + "MailMerge.ExecuteWithRegionsNested.docx"); + TestUtil.mailMergeMatchesDataSet(customersAndOrders, new Document(getArtifactsDir() + "MailMerge.ExecuteWithRegionsNested.docx"), false); //ExSkip + } + + /// + /// Generates a data set that has two data tables named "Customers" and "Orders", with a one-to-many relationship on the "CustomerID" column. + /// + private static DataSet createDataSet() + { + DataTable tableCustomers = new DataTable("Customers"); + tableCustomers.getColumns().add("CustomerID"); + tableCustomers.getColumns().add("CustomerName"); + tableCustomers.getRows().add(new Object[] { 1, "John Doe" }); + tableCustomers.getRows().add(new Object[] { 2, "Jane Doe" }); + + DataTable tableOrders = new DataTable("Orders"); + tableOrders.getColumns().add("CustomerID"); + tableOrders.getColumns().add("ItemName"); + tableOrders.getColumns().add("Quantity"); + tableOrders.getRows().add(new Object[] { 1, "Hawaiian", 2 }); + tableOrders.getRows().add(new Object[] { 2, "Pepperoni", 1 }); + tableOrders.getRows().add(new Object[] { 2, "Chicago", 1 }); + + DataSet dataSet = new DataSet(); + dataSet.getTables().add(tableCustomers); + dataSet.getTables().add(tableOrders); + dataSet.getRelations().add(tableCustomers.getColumns().get("CustomerID"), tableOrders.getColumns().get("CustomerID")); + + return dataSet; + } + //ExEnd + + @Test + public void executeWithRegionsConcurrent() throws Exception + { + //ExStart + //ExFor:MailMerge.ExecuteWithRegions(DataTable) + //ExFor:MailMerge.ExecuteWithRegions(DataView) + //ExSummary:Shows how to use regions to execute two separate mail merges in one document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // If we want to perform two consecutive mail merges on one document while taking data from two tables + // related to each other in any way, we can separate the mail merges with regions. + // Normally, MERGEFIELDs contain the name of a column of a mail merge data source. + // Instead, we can use "TableStart:" and "TableEnd:" prefixes to begin/end a mail merge region. + // Each region will belong to a table with a name that matches the string immediately after the prefix's colon. + // These regions are separate for unrelated data, while they can be nested for hierarchical data. + builder.writeln("\tCities: "); + builder.insertField(" MERGEFIELD TableStart:Cities"); + builder.insertField(" MERGEFIELD Name"); + builder.insertField(" MERGEFIELD TableEnd:Cities"); + builder.insertParagraph(); + + // Both MERGEFIELDs refer to the same column name, but values for each will come from different data tables. + builder.writeln("\tFruit: "); + builder.insertField(" MERGEFIELD TableStart:Fruit"); + builder.insertField(" MERGEFIELD Name"); + builder.insertField(" MERGEFIELD TableEnd:Fruit"); + + // Create two unrelated data tables. + DataTable tableCities = new DataTable("Cities"); + tableCities.getColumns().add("Name"); + tableCities.getRows().add(new Object[] { "Washington" }); + tableCities.getRows().add(new Object[] { "London" }); + tableCities.getRows().add(new Object[] { "New York" }); + + DataTable tableFruit = new DataTable("Fruit"); + tableFruit.getColumns().add("Name"); + tableFruit.getRows().add(new Object[] { "Cherry" }); + tableFruit.getRows().add(new Object[] { "Apple" }); + tableFruit.getRows().add(new Object[] { "Watermelon" }); + tableFruit.getRows().add(new Object[] { "Banana" }); + + // We will need to run one mail merge per table. The first mail merge will populate the MERGEFIELDs + // in the "Cities" range while leaving the fields the "Fruit" range unfilled. + doc.getMailMerge().executeWithRegions(tableCities); + + // Run a second merge for the "Fruit" table, while using a data view + // to sort the rows in ascending order on the "Name" column before the merge. + DataView dv = new DataView(tableFruit); + dv.setSort("Name ASC"); + doc.getMailMerge().executeWithRegions(dv); + + doc.save(getArtifactsDir() + "MailMerge.ExecuteWithRegionsConcurrent.docx"); + //ExEnd + + DataSet dataSet = new DataSet(); + + dataSet.getTables().add(tableCities); + dataSet.getTables().add(tableFruit); + + TestUtil.mailMergeMatchesDataSet(dataSet, new Document(getArtifactsDir() + "MailMerge.ExecuteWithRegionsConcurrent.docx"), false); + } + + @Test + public void mailMergeRegionInfo() throws Exception + { + //ExStart + //ExFor:MailMerge.GetFieldNamesForRegion(String) + //ExFor:MailMerge.GetFieldNamesForRegion(String,Int32) + //ExFor:MailMerge.GetRegionsByName(String) + //ExFor:MailMerge.RegionEndTag + //ExFor:MailMerge.RegionStartTag + //ExFor:MailMergeRegionInfo.ParentRegion + //ExSummary:Shows how to create, list, and read mail merge regions. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // "TableStart" and "TableEnd" tags, which go inside MERGEFIELDs, + // denote the strings that signify the starts and ends of mail merge regions. + Assert.assertEquals("TableStart", doc.getMailMerge().getRegionStartTag()); + Assert.assertEquals("TableEnd", doc.getMailMerge().getRegionEndTag()); + + // Use these tags to start and end a mail merge region named "MailMergeRegion1", + // which will contain MERGEFIELDs for two columns. + builder.insertField(" MERGEFIELD TableStart:MailMergeRegion1"); + builder.insertField(" MERGEFIELD Column1"); + builder.write(", "); + builder.insertField(" MERGEFIELD Column2"); + builder.insertField(" MERGEFIELD TableEnd:MailMergeRegion1"); + + // We can keep track of merge regions and their columns by looking at these collections. + ArrayList regions = doc.getMailMerge().getRegionsByName("MailMergeRegion1"); + + Assert.assertEquals(1, regions.size()); + Assert.assertEquals("MailMergeRegion1", regions.get(0).getName()); + + String[] mergeFieldNames = doc.getMailMerge().getFieldNamesForRegion("MailMergeRegion1"); + + Assert.assertEquals("Column1", mergeFieldNames[0]); + Assert.assertEquals("Column2", mergeFieldNames[1]); + + // Insert a region with the same name inside the existing region, which will make it a parent. + // Now a "Column2" field will be inside a new region. + builder.moveToField(regions.get(0).getFields().get(1), false); + builder.insertField(" MERGEFIELD TableStart:MailMergeRegion1"); + builder.moveToField(regions.get(0).getFields().get(1), true); + builder.insertField(" MERGEFIELD TableEnd:MailMergeRegion1"); + + // If we look up the name of duplicate regions using the "GetRegionsByName" method, + // it will return all such regions in a collection. + regions = doc.getMailMerge().getRegionsByName("MailMergeRegion1"); + + Assert.assertEquals(2, regions.size()); + // Check that the second region now has a parent region. + Assert.assertEquals("MailMergeRegion1", regions.get(1).getParentRegion().getName()); + + mergeFieldNames = doc.getMailMerge().getFieldNamesForRegion("MailMergeRegion1", 1); + + Assert.assertEquals("Column2", mergeFieldNames[0]); + //ExEnd + } + + //ExStart + //ExFor:MailMerge.MergeDuplicateRegions + //ExSummary:Shows how to work with duplicate mail merge regions. + @Test (dataProvider = "mergeDuplicateRegionsDataProvider") //ExSkip + public void mergeDuplicateRegions(boolean mergeDuplicateRegions) throws Exception + { + Document doc = createSourceDocMergeDuplicateRegions(); + DataTable dataTable = createSourceTableMergeDuplicateRegions(); + + // If we set the "MergeDuplicateRegions" property to "false", the mail merge will affect the first region, + // while the MERGEFIELDs of the second one will be left in the pre-merge state. + // To get both regions merged like that, + // we would have to execute the mail merge twice on a table of the same name. + // If we set the "MergeDuplicateRegions" property to "true", the mail merge will affect both regions. + doc.getMailMerge().setMergeDuplicateRegions(mergeDuplicateRegions); + + doc.getMailMerge().executeWithRegions(dataTable); + doc.save(getArtifactsDir() + "MailMerge.MergeDuplicateRegions.docx"); + testMergeDuplicateRegions(dataTable, doc, mergeDuplicateRegions); //ExSkip + } + + //JAVA-added data provider for test method + @DataProvider(name = "mergeDuplicateRegionsDataProvider") + public static Object[][] mergeDuplicateRegionsDataProvider() throws Exception + { + return new Object[][] + { + {true}, + {false}, + }; + } + + /// + /// Returns a document that contains two duplicate mail merge regions (sharing the same name in the "TableStart/End" tags). + /// + private static Document createSourceDocMergeDuplicateRegions() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField(" MERGEFIELD TableStart:MergeRegion"); + builder.insertField(" MERGEFIELD Column1"); + builder.insertField(" MERGEFIELD TableEnd:MergeRegion"); + builder.insertParagraph(); + + builder.insertField(" MERGEFIELD TableStart:MergeRegion"); + builder.insertField(" MERGEFIELD Column2"); + builder.insertField(" MERGEFIELD TableEnd:MergeRegion"); + + return doc; + } + + /// + /// Creates a data table with one row and two columns. + /// + private static DataTable createSourceTableMergeDuplicateRegions() + { + DataTable dataTable = new DataTable("MergeRegion"); + dataTable.getColumns().add("Column1"); + dataTable.getColumns().add("Column2"); + dataTable.getRows().add(new Object[] { "Value 1", "Value 2" }); + + return dataTable; + } + //ExEnd + + private void testMergeDuplicateRegions(DataTable dataTable, Document doc, boolean isMergeDuplicateRegions) + { + if (isMergeDuplicateRegions) + TestUtil.mailMergeMatchesDataTable(dataTable, doc, true); + else + { + dataTable.getColumns().remove("Column2"); + TestUtil.mailMergeMatchesDataTable(dataTable, doc, true); + } + } + + //ExStart + //ExFor:MailMerge.PreserveUnusedTags + //ExFor:MailMerge.UseNonMergeFields + //ExSummary:Shows how to preserve the appearance of alternative mail merge tags that go unused during a mail merge. + @Test (dataProvider = "preserveUnusedTagsDataProvider") //ExSkip + public void preserveUnusedTags(boolean preserveUnusedTags) throws Exception + { + Document doc = createSourceDocWithAlternativeMergeFields(); + DataTable dataTable = createSourceTablePreserveUnusedTags(); + + // By default, a mail merge places data from each row of a table into MERGEFIELDs, which name columns in that table. + // Our document has no such fields, but it does have plaintext tags enclosed by curly braces. + // If we set the "PreserveUnusedTags" flag to "true", we could treat these tags as MERGEFIELDs + // to allow our mail merge to insert data from the data source at those tags. + // If we set the "PreserveUnusedTags" flag to "false", + // the mail merge will convert these tags to MERGEFIELDs and leave them unfilled. + doc.getMailMerge().setPreserveUnusedTags(preserveUnusedTags); + doc.getMailMerge().execute(dataTable); + + doc.save(getArtifactsDir() + "MailMerge.PreserveUnusedTags.docx"); + + // Our document has a tag for a column named "Column2", which does not exist in the table. + // If we set the "PreserveUnusedTags" flag to "false", then the mail merge will convert this tag into a MERGEFIELD. + Assert.assertEquals(doc.getText().contains("{{ Column2 }}"), preserveUnusedTags); + + if (preserveUnusedTags) + Assert.That(doc.getRange().getFields().Count(f => f.Type == FieldType.FieldMergeField), assertEquals(0, ); + else + Assert.That(doc.getRange().getFields().Count(f => f.Type == FieldType.FieldMergeField), assertEquals(1, ); + TestUtil.mailMergeMatchesDataTable(dataTable, doc, true); //ExSkip + } + + //JAVA-added data provider for test method + @DataProvider(name = "preserveUnusedTagsDataProvider") + public static Object[][] preserveUnusedTagsDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + /// + /// Create a document and add two plaintext tags that may act as MERGEFIELDs during a mail merge. + /// + private static Document createSourceDocWithAlternativeMergeFields() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("{{ Column1 }}"); + builder.writeln("{{ Column2 }}"); + + // Our tags will register as destinations for mail merge data only if we set this to true. + doc.getMailMerge().setUseNonMergeFields(true); + + return doc; + } + + /// + /// Create a simple data table with one column. + /// + private static DataTable createSourceTablePreserveUnusedTags() + { + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("Column1"); + dataTable.getRows().add(new Object[] { "Value1" }); + + return dataTable; + } + //ExEnd + + //ExStart + //ExFor:MailMerge.MergeWholeDocument + //ExSummary:Shows the relationship between mail merges with regions, and field updating. + @Test (dataProvider = "mergeWholeDocumentDataProvider") //ExSkip + public void mergeWholeDocument(boolean mergeWholeDocument) throws Exception + { + Document doc = createSourceDocMergeWholeDocument(); + DataTable dataTable = createSourceTableMergeWholeDocument(); + + // If we set the "MergeWholeDocument" flag to "true", + // the mail merge with regions will update every field in the document. + // If we set the "MergeWholeDocument" flag to "false", the mail merge will only update fields + // within the mail merge region whose name matches the name of the data source table. + doc.getMailMerge().setMergeWholeDocument(mergeWholeDocument); + doc.getMailMerge().executeWithRegions(dataTable); + + // The mail merge will only update the QUOTE field outside of the mail merge region + // if we set the "MergeWholeDocument" flag to "true". + doc.save(getArtifactsDir() + "MailMerge.MergeWholeDocument.docx"); + + Assert.assertTrue(doc.getText().contains("This QUOTE field is inside the \"MyTable\" merge region.")); + Assert.assertEquals(mergeWholeDocument, doc.getText().contains("This QUOTE field is outside of the \"MyTable\" merge region.")); + TestUtil.mailMergeMatchesDataTable(dataTable, doc, true); //ExSkip + } + + //JAVA-added data provider for test method + @DataProvider(name = "mergeWholeDocumentDataProvider") + public static Object[][] mergeWholeDocumentDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + /// + /// Create a document with a mail merge region that belongs to a data source named "MyTable". + /// Insert one QUOTE field inside this region, and one more outside it. + /// + private static Document createSourceDocMergeWholeDocument() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + FieldQuote field = (FieldQuote)builder.insertField(FieldType.FIELD_QUOTE, true); + field.setText("This QUOTE field is outside of the \"MyTable\" merge region."); + + builder.insertParagraph(); + builder.insertField(" MERGEFIELD TableStart:MyTable"); + + field = (FieldQuote)builder.insertField(FieldType.FIELD_QUOTE, true); + field.setText("This QUOTE field is inside the \"MyTable\" merge region."); + builder.insertParagraph(); + + builder.insertField(" MERGEFIELD MyColumn"); + builder.insertField(" MERGEFIELD TableEnd:MyTable"); + + return doc; + } + + /// + /// Create a data table that will be used in a mail merge. + /// + private static DataTable createSourceTableMergeWholeDocument() + { + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("MyColumn"); + dataTable.getRows().add(new Object[] { "MyValue" }); + + return dataTable; + } + //ExEnd + + //ExStart + //ExFor:MailMerge.UseWholeParagraphAsRegion + //ExSummary:Shows the relationship between mail merge regions and paragraphs. + @Test (dataProvider = "useWholeParagraphAsRegionDataProvider") //ExSkip + public void useWholeParagraphAsRegion(boolean useWholeParagraphAsRegion) throws Exception + { + Document doc = createSourceDocWithNestedMergeRegions(); + DataTable dataTable = createSourceTableDataTableForOneRegion(); + + // By default, a paragraph can belong to no more than one mail merge region. + // The contents of our document do not meet these criteria. + // If we set the "UseWholeParagraphAsRegion" flag to "true", + // running a mail merge on this document will throw an exception. + // If we set the "UseWholeParagraphAsRegion" flag to "false", + // we will be able to execute a mail merge on this document. + doc.getMailMerge().setUseWholeParagraphAsRegion(useWholeParagraphAsRegion); + + if (useWholeParagraphAsRegion) + Assert.Throws(() => doc.getMailMerge().executeWithRegions(dataTable)); + else + doc.getMailMerge().executeWithRegions(dataTable); + + // The mail merge populates our first region while leaving the second region unused + // since it is the region that breaks the rule. + doc.save(getArtifactsDir() + "MailMerge.UseWholeParagraphAsRegion.docx"); + if (!useWholeParagraphAsRegion) //ExSkip + TestUtil.mailMergeMatchesDataTable(dataTable, new Document(getArtifactsDir() + "MailMerge.UseWholeParagraphAsRegion.docx"), true); //ExSkip + } + + //JAVA-added data provider for test method + @DataProvider(name = "useWholeParagraphAsRegionDataProvider") + public static Object[][] useWholeParagraphAsRegionDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + /// + /// Create a document with two mail merge regions sharing one paragraph. + /// + private static Document createSourceDocWithNestedMergeRegions() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Region 1: "); + builder.insertField(" MERGEFIELD TableStart:MyTable"); + builder.insertField(" MERGEFIELD Column1"); + builder.write(", "); + builder.insertField(" MERGEFIELD Column2"); + builder.insertField(" MERGEFIELD TableEnd:MyTable"); + + builder.write(", Region 2: "); + builder.insertField(" MERGEFIELD TableStart:MyOtherTable"); + builder.insertField(" MERGEFIELD TableEnd:MyOtherTable"); + + return doc; + } + + /// + /// Create a data table that can populate one region during a mail merge. + /// + private static DataTable createSourceTableDataTableForOneRegion() + { + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("Column1"); + dataTable.getColumns().add("Column2"); + dataTable.getRows().add(new Object[] { "Value 1", "Value 2" }); + + return dataTable; + } + //ExEnd + + @Test (dataProvider = "trimWhiteSpacesDataProvider") + public void trimWhiteSpaces(boolean trimWhitespaces) throws Exception + { + //ExStart + //ExFor:MailMerge.TrimWhitespaces + //ExSummary:Shows how to trim whitespaces from values of a data source while executing a mail merge. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField("MERGEFIELD myMergeField", null); + + doc.getMailMerge().setTrimWhitespaces(trimWhitespaces); + doc.getMailMerge().execute(new String[] { "myMergeField" }, new Object[] { "\t hello world! " }); + + Assert.assertEquals(trimWhitespaces ? "hello world!\f" : "\t hello world! \f", doc.getText()); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "trimWhiteSpacesDataProvider") + public static Object[][] trimWhiteSpacesDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void mailMergeGetFieldNames() throws Exception + { + //ExStart + //ExFor:MailMerge.GetFieldNames + //ExSummary:Shows how to get names of all merge fields in a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField(" MERGEFIELD FirstName "); + builder.write(" "); + builder.insertField(" MERGEFIELD LastName "); + builder.insertParagraph(); + builder.insertField(" MERGEFIELD City "); + + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("LastName"); + dataTable.getColumns().add("City"); + dataTable.getRows().add(new Object[] { "John", "Doe", "New York" }); + dataTable.getRows().add(new Object[] { "Joe", "Bloggs", "Washington" }); + + // For every MERGEFIELD name in the document, ensure that the data table contains a column + // with the same name, and then execute the mail merge. + String[] fieldNames = doc.getMailMerge().getFieldNames(); + + Assert.assertEquals(3, fieldNames.length); + + for (String fieldName : fieldNames) + Assert.assertTrue(dataTable.getColumns().contains(fieldName)); + + doc.getMailMerge().execute(dataTable); + //ExEnd + + TestUtil.mailMergeMatchesDataTable(dataTable, doc, true); + } + + @Test + public void deleteFields() throws Exception + { + //ExStart + //ExFor:MailMerge.DeleteFields + //ExSummary:Shows how to delete all MERGEFIELDs from a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Dear "); + builder.insertField(" MERGEFIELD FirstName "); + builder.write(" "); + builder.insertField(" MERGEFIELD LastName "); + builder.writeln(","); + builder.writeln("Greetings!"); + + Assert.assertEquals("Dear \u0013 MERGEFIELD FirstName \u0014«FirstName»\u0015 \u0013 MERGEFIELD LastName \u0014«LastName»\u0015,\rGreetings!", doc.getText().trim()); + + doc.getMailMerge().deleteFields(); + + Assert.assertEquals("Dear ,\rGreetings!", doc.getText().trim()); + //ExEnd + } + + @Test (dataProvider = "removeUnusedFieldsDataProvider") + public void removeUnusedFields(/*MailMergeCleanupOptions*/int mailMergeCleanupOptions) throws Exception + { + //ExStart + //ExFor:MailMerge.CleanupOptions + //ExFor:MailMergeCleanupOptions + //ExSummary:Shows how to automatically remove MERGEFIELDs that go unused during mail merge. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a document with MERGEFIELDs for three columns of a mail merge data source table, + // and then create a table with only two columns whose names match our MERGEFIELDs. + builder.insertField(" MERGEFIELD FirstName "); + builder.write(" "); + builder.insertField(" MERGEFIELD LastName "); + builder.insertParagraph(); + builder.insertField(" MERGEFIELD City "); + + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("LastName"); + dataTable.getRows().add(new Object[] { "John", "Doe" }); + dataTable.getRows().add(new Object[] { "Joe", "Bloggs" }); + + // Our third MERGEFIELD references a "City" column, which does not exist in our data source. + // The mail merge will leave fields such as this intact in their pre-merge state. + // Setting the "CleanupOptions" property to "RemoveUnusedFields" will remove any MERGEFIELDs + // that go unused during a mail merge to clean up the merge documents. + doc.getMailMerge().setCleanupOptions(mailMergeCleanupOptions); + doc.getMailMerge().execute(dataTable); + + if (mailMergeCleanupOptions == MailMergeCleanupOptions.REMOVE_UNUSED_FIELDS || + mailMergeCleanupOptions == MailMergeCleanupOptions.REMOVE_STATIC_FIELDS) + Assert.assertEquals(0, doc.getRange().getFields().getCount()); + else + Assert.assertEquals(2, doc.getRange().getFields().getCount()); + //ExEnd + + TestUtil.mailMergeMatchesDataTable(dataTable, doc, true); + } + + //JAVA-added data provider for test method + @DataProvider(name = "removeUnusedFieldsDataProvider") + public static Object[][] removeUnusedFieldsDataProvider() throws Exception + { + return new Object[][] + { + {MailMergeCleanupOptions.NONE}, + {MailMergeCleanupOptions.REMOVE_CONTAINING_FIELDS}, + {MailMergeCleanupOptions.REMOVE_EMPTY_PARAGRAPHS}, + {MailMergeCleanupOptions.REMOVE_EMPTY_TABLE_ROWS}, + {MailMergeCleanupOptions.REMOVE_STATIC_FIELDS}, + {MailMergeCleanupOptions.REMOVE_UNUSED_FIELDS}, + {MailMergeCleanupOptions.REMOVE_UNUSED_REGIONS}, + }; + } + + @Test (dataProvider = "removeEmptyParagraphsDataProvider") + public void removeEmptyParagraphs(/*MailMergeCleanupOptions*/int mailMergeCleanupOptions) throws Exception + { + //ExStart + //ExFor:MailMerge.CleanupOptions + //ExFor:MailMergeCleanupOptions + //ExSummary:Shows how to remove empty paragraphs that a mail merge may create from the merge output document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField(" MERGEFIELD TableStart:MyTable"); + builder.insertField(" MERGEFIELD FirstName "); + builder.write(" "); + builder.insertField(" MERGEFIELD LastName "); + builder.insertField(" MERGEFIELD TableEnd:MyTable"); + + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("FirstName"); + dataTable.getColumns().add("LastName"); + dataTable.getRows().add(new Object[] { "John", "Doe" }); + dataTable.getRows().add(new Object[] { "", "" }); + dataTable.getRows().add(new Object[] { "Jane", "Doe" }); + + doc.getMailMerge().setCleanupOptions(mailMergeCleanupOptions); + doc.getMailMerge().executeWithRegions(dataTable); + + if (doc.getMailMerge().getCleanupOptions() == MailMergeCleanupOptions.REMOVE_EMPTY_PARAGRAPHS) + Assert.assertEquals("John Doe\r" + + "Jane Doe", doc.getText().trim()); + else + Assert.assertEquals("John Doe\r" + + " \r" + + "Jane Doe", doc.getText().trim()); + //ExEnd + + TestUtil.mailMergeMatchesDataTable(dataTable, doc, false); + } + + //JAVA-added data provider for test method + @DataProvider(name = "removeEmptyParagraphsDataProvider") + public static Object[][] removeEmptyParagraphsDataProvider() throws Exception + { + return new Object[][] + { + {MailMergeCleanupOptions.NONE}, + {MailMergeCleanupOptions.REMOVE_CONTAINING_FIELDS}, + {MailMergeCleanupOptions.REMOVE_EMPTY_PARAGRAPHS}, + {MailMergeCleanupOptions.REMOVE_EMPTY_TABLE_ROWS}, + {MailMergeCleanupOptions.REMOVE_STATIC_FIELDS}, + {MailMergeCleanupOptions.REMOVE_UNUSED_FIELDS}, + {MailMergeCleanupOptions.REMOVE_UNUSED_REGIONS}, + }; + } + + @Test (enabled = false, description = "WORDSNET-17733", dataProvider = "removeColonBetweenEmptyMergeFieldsDataProvider") + public void removeColonBetweenEmptyMergeFields(String punctuationMark, + boolean cleanupParagraphsWithPunctuationMarks, String resultText) throws Exception + { + //ExStart + //ExFor:MailMerge.CleanupParagraphsWithPunctuationMarks + //ExSummary:Shows how to remove paragraphs with punctuation marks after a mail merge operation. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + FieldMergeField mergeFieldOption1 = (FieldMergeField) builder.insertField("MERGEFIELD", "Option_1"); + mergeFieldOption1.setFieldName("Option_1"); + + builder.write(punctuationMark); + + FieldMergeField mergeFieldOption2 = (FieldMergeField) builder.insertField("MERGEFIELD", "Option_2"); + mergeFieldOption2.setFieldName("Option_2"); + + // Configure the "CleanupOptions" property to remove any empty paragraphs that this mail merge would create. + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_EMPTY_PARAGRAPHS); + + // Setting the "CleanupParagraphsWithPunctuationMarks" property to "true" will also count paragraphs + // with punctuation marks as empty and will get the mail merge operation to remove them as well. + // Setting the "CleanupParagraphsWithPunctuationMarks" property to "false" + // will remove empty paragraphs, but not ones with punctuation marks. + // This is a list of punctuation marks that this property concerns: "!", ",", ".", ":", ";", "?", "¡", "¿". + doc.getMailMerge().setCleanupParagraphsWithPunctuationMarks(cleanupParagraphsWithPunctuationMarks); + + doc.getMailMerge().execute(new String[] { "Option_1", "Option_2" }, new Object[] { null, null }); + + doc.save(getArtifactsDir() + "MailMerge.RemoveColonBetweenEmptyMergeFields.docx"); + //ExEnd + + Assert.assertEquals(resultText, doc.getText()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "removeColonBetweenEmptyMergeFieldsDataProvider") + public static Object[][] removeColonBetweenEmptyMergeFieldsDataProvider() throws Exception + { + return new Object[][] + { + {"!", false, ""}, + {", ", false, ""}, + {" . ", false, ""}, + {" :", false, ""}, + {" ; ", false, ""}, + {" ? ", false, ""}, + {" ¡ ", false, ""}, + {" ¿ ", false, ""}, + {"!", true, "!\f"}, + {", ", true, ", \f"}, + {" . ", true, " . \f"}, + {" :", true, " :\f"}, + {" ; ", true, " ; \f"}, + {" ? ", true, " ? \f"}, + {" ¡ ", true, " ¡ \f"}, + {" ¿ ", true, " ¿ \f"}, + }; + } + + //ExStart + //ExFor:MailMerge.MappedDataFields + //ExFor:MappedDataFieldCollection + //ExFor:MappedDataFieldCollection.Add + //ExFor:MappedDataFieldCollection.Clear + //ExFor:MappedDataFieldCollection.ContainsKey(String) + //ExFor:MappedDataFieldCollection.ContainsValue(String) + //ExFor:MappedDataFieldCollection.Count + //ExFor:MappedDataFieldCollection.GetEnumerator + //ExFor:MappedDataFieldCollection.Item(String) + //ExFor:MappedDataFieldCollection.Remove(String) + //ExSummary:Shows how to map data columns and MERGEFIELDs with different names so the data is transferred between them during a mail merge. + @Test //ExSkip + public void mappedDataFieldCollection() throws Exception + { + Document doc = createSourceDocMappedDataFields(); + DataTable dataTable = createSourceTableMappedDataFields(); + + // The table has a column named "Column2", but there are no MERGEFIELDs with that name. + // Also, we have a MERGEFIELD named "Column3", but the data source does not have a column with that name. + // If data from "Column2" is suitable for the "Column3" MERGEFIELD, + // we can map that column name to the MERGEFIELD in the "MappedDataFields" key/value pair. + MappedDataFieldCollection mappedDataFields = doc.getMailMerge().getMappedDataFields(); + + // We can link a data source column name to a MERGEFIELD name like this. + mappedDataFields.add("MergeFieldName", "DataSourceColumnName"); + + // Link the data source column named "Column2" to MERGEFIELDs named "Column3". + mappedDataFields.add("Column3", "Column2"); + + // The MERGEFIELD name is the "key" to the respective data source column name "value". + Assert.assertEquals("DataSourceColumnName", mappedDataFields.get("MergeFieldName")); + Assert.assertTrue(mappedDataFields.containsKey("MergeFieldName")); + Assert.assertTrue(mappedDataFields.containsValue("DataSourceColumnName")); + + // Now if we run this mail merge, the "Column3" MERGEFIELDs will take data from "Column2" of the table. + doc.getMailMerge().execute(dataTable); + + doc.save(getArtifactsDir() + "MailMerge.MappedDataFieldCollection.docx"); + + // We can iterate over the elements in this collection. + Assert.assertEquals(2, mappedDataFields.getCount()); + + Iterator> enumerator = mappedDataFields.iterator(); + try /*JAVA: was using*/ + { + while (enumerator.hasNext()) + System.out.println("Column named {enumerator.Current.Value} is mapped to MERGEFIELDs named {enumerator.Current.Key}"); + } + finally { if (enumerator != null) enumerator.close(); } + + // We can also remove elements from the collection. + mappedDataFields.remove("MergeFieldName"); + + Assert.assertFalse(mappedDataFields.containsKey("MergeFieldName")); + Assert.assertFalse(mappedDataFields.containsValue("DataSourceColumnName")); + + mappedDataFields.clear(); + + Assert.assertEquals(0, mappedDataFields.getCount()); + TestUtil.mailMergeMatchesDataTable(dataTable, new Document(getArtifactsDir() + "MailMerge.MappedDataFieldCollection.docx"), true); //ExSkip + } + + /// + /// Create a document with 2 MERGEFIELDs, one of which does not have a + /// corresponding column in the data table from the method below. + /// + private static Document createSourceDocMappedDataFields() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField(" MERGEFIELD Column1"); + builder.write(", "); + builder.insertField(" MERGEFIELD Column3"); + + return doc; + } + + /// + /// Create a data table with 2 columns, one of which does not have a + /// corresponding MERGEFIELD in the source document from the method above. + /// + private static DataTable createSourceTableMappedDataFields() + { + DataTable dataTable = new DataTable("MyTable"); + dataTable.getColumns().add("Column1"); + dataTable.getColumns().add("Column2"); + dataTable.getRows().add(new Object[] { "Value1", "Value2" }); + + return dataTable; + } + //ExEnd + + @Test + public void getFieldNames() throws Exception + { + //ExStart + //ExFor:FieldAddressBlock + //ExFor:FieldAddressBlock.GetFieldNames + //ExSummary:Shows how to get mail merge field names used by a field. + Document doc = new Document(getMyDir() + "Field sample - ADDRESSBLOCK.docx"); + + String[] addressFieldsExpect = + { + "Company", "First Name", "Middle Name", "Last Name", "Suffix", "Address 1", "City", "State", + "Country or Region", "Postal Code" + }; + + FieldAddressBlock addressBlockField = (FieldAddressBlock) doc.getRange().getFields().get(0); + String[] addressBlockFieldNames = addressBlockField.getFieldNames(); + //ExEnd + + Assert.assertEquals(addressFieldsExpect, addressBlockFieldNames); + + String[] greetingFieldsExpect = { "Courtesy Title", "Last Name" }; + + FieldGreetingLine greetingLineField = (FieldGreetingLine) doc.getRange().getFields().get(1); + String[] greetingLineFieldNames = greetingLineField.getFieldNames(); + + Assert.assertEquals(greetingFieldsExpect, greetingLineFieldNames); + } + + /// + /// Without TestCaseSource/TestCase because of some strange behavior when using long data. + /// + @Test + public void mustacheTemplateSyntaxTrue() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.write("{{ testfield1 }}"); + builder.write("{{ testfield2 }}"); + builder.write("{{ testfield3 }}"); + + doc.getMailMerge().setUseNonMergeFields(true); + doc.getMailMerge().setPreserveUnusedTags(true); + + DataTable table = new DataTable("Test"); + table.getColumns().add("testfield2"); + table.getRows().add("value 1"); + + doc.getMailMerge().execute(table); + + String paraText = DocumentHelper.getParagraphText(doc, 0); + + Assert.assertEquals("{{ testfield1 }}value 1{{ testfield3 }}\f", paraText); + } + + @Test + public void mustacheTemplateSyntaxFalse() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.write("{{ testfield1 }}"); + builder.write("{{ testfield2 }}"); + builder.write("{{ testfield3 }}"); + + doc.getMailMerge().setUseNonMergeFields(true); + doc.getMailMerge().setPreserveUnusedTags(false); + + DataTable table = new DataTable("Test"); + table.getColumns().add("testfield2"); + table.getRows().add("value 1"); + + doc.getMailMerge().execute(table); + + String paraText = DocumentHelper.getParagraphText(doc, 0); + + Assert.assertEquals("\u0013MERGEFIELD \"testfield1\"\u0014«testfield1»\u0015value 1\u0013MERGEFIELD \"testfield3\"\u0014«testfield3»\u0015\f", paraText); + } + + @Test + public void testMailMergeGetRegionsHierarchy() throws Exception + { + //ExStart + //ExFor:MailMerge.GetRegionsHierarchy + //ExFor:MailMergeRegionInfo + //ExFor:MailMergeRegionInfo.Regions + //ExFor:MailMergeRegionInfo.Name + //ExFor:MailMergeRegionInfo.Fields + //ExFor:MailMergeRegionInfo.StartField + //ExFor:MailMergeRegionInfo.EndField + //ExFor:MailMergeRegionInfo.Level + //ExFor:MailMergeRegionInfo.MustacheTags + //ExSummary:Shows how to verify mail merge regions. + Document doc = new Document(getMyDir() + "Mail merge regions.docx"); + + // Returns a full hierarchy of merge regions that contain MERGEFIELDs available in the document. + MailMergeRegionInfo regionInfo = doc.getMailMerge().getRegionsHierarchy(); + + // Get top regions in the document. + ArrayList topRegions = regionInfo.getRegions(); + + Assert.assertEquals(2, topRegions.size()); + Assert.assertEquals("Region1", topRegions.get(0).getName()); + Assert.assertEquals("Region2", topRegions.get(1).getName()); + Assert.assertEquals(1, topRegions.get(0).getLevel()); + Assert.assertEquals(1, topRegions.get(1).getLevel()); + + // Get nested region in first top region. + ArrayList nestedRegions = topRegions.get(0).getRegions(); + + Assert.assertEquals(2, nestedRegions.size()); + Assert.assertEquals("NestedRegion1", nestedRegions.get(0).getName()); + Assert.assertEquals("NestedRegion2", nestedRegions.get(1).getName()); + Assert.assertEquals(2, nestedRegions.get(0).getLevel()); + Assert.assertEquals(2, nestedRegions.get(1).getLevel()); + Assert.assertEquals(0, nestedRegions.get(1).getMustacheTags().size()); + + // Get list of fields inside the first top region. + ArrayList fieldList = topRegions.get(0).getFields(); + + Assert.assertEquals(4, fieldList.size()); + + FieldMergeField startFieldMergeField = nestedRegions.get(0).getStartField(); + + Assert.assertEquals("TableStart:NestedRegion1", startFieldMergeField.getFieldName()); + + FieldMergeField endFieldMergeField = nestedRegions.get(0).getEndField(); + + Assert.assertEquals("TableEnd:NestedRegion1", endFieldMergeField.getFieldName()); + //ExEnd + } + + //ExStart + //ExFor:MailMerge.MailMergeCallback + //ExFor:IMailMergeCallback + //ExFor:IMailMergeCallback.TagsReplaced + //ExSummary:Shows how to define custom logic for handling events during mail merge. + @Test //ExSkip + public void callback() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert two mail merge tags referencing two columns in a data source. + builder.write("{{FirstName}}"); + builder.write("{{LastName}}"); + + // Create a data source that only contains one of the columns that our merge tags reference. + DataTable table = new DataTable("Test"); + table.getColumns().add("FirstName"); + table.getRows().add("John"); + table.getRows().add("Jane"); + + // Configure our mail merge to use alternative mail merge tags. + doc.getMailMerge().setUseNonMergeFields(true); + + // Then, ensure that the mail merge will convert tags, such as our "LastName" tag, + // into MERGEFIELDs in the merge documents. + doc.getMailMerge().setPreserveUnusedTags(false); + + MailMergeTagReplacementCounter counter = new MailMergeTagReplacementCounter(); + doc.getMailMerge().setMailMergeCallback(counter); + doc.getMailMerge().execute(table); + + Assert.assertEquals(1, counter.getTagsReplacedCount()); + } + + /// + /// Counts the number of times a mail merge replaces mail merge tags that it could not fill with data with MERGEFIELDs. + /// + private static class MailMergeTagReplacementCounter implements IMailMergeCallback + { + public void tagsReplaced() + { + setTagsReplacedCount(getTagsReplacedCount() + 1)/*Property++*/; + } + + public int getTagsReplacedCount() { return mTagsReplacedCount; }; private void setTagsReplacedCount(int value) { mTagsReplacedCount = value; }; + + private int mTagsReplacedCount; + } + //ExEnd + + @Test + public void getRegionsByName() throws Exception + { + Document doc = new Document(getMyDir() + "Mail merge regions.docx"); + + ArrayList regions = doc.getMailMerge().getRegionsByName("Region1"); + Assert.assertEquals(1, doc.getMailMerge().getRegionsByName("Region1").size()); + for (MailMergeRegionInfo region : regions) Assert.assertEquals("Region1", region.getName()); + + regions = doc.getMailMerge().getRegionsByName("Region2"); + Assert.assertEquals(1, doc.getMailMerge().getRegionsByName("Region2").size()); + for (MailMergeRegionInfo region : regions) Assert.assertEquals("Region2", region.getName()); + + regions = doc.getMailMerge().getRegionsByName("NestedRegion1"); + Assert.assertEquals(2, doc.getMailMerge().getRegionsByName("NestedRegion1").size()); + for (MailMergeRegionInfo region : regions) Assert.assertEquals("NestedRegion1", region.getName()); + } + + @Test + public void cleanupOptions() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.startTable(); + builder.insertCell(); + builder.insertField(" MERGEFIELD TableStart:StudentCourse "); + builder.insertCell(); + builder.insertField(" MERGEFIELD CourseName "); + builder.insertCell(); + builder.insertField(" MERGEFIELD TableEnd:StudentCourse "); + builder.endTable(); + + DataTable data = getDataTable(); + + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_EMPTY_TABLE_ROWS); + doc.getMailMerge().executeWithRegions(data); + + doc.save(getArtifactsDir() + "MailMerge.CleanupOptions.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "MailMerge.CleanupOptions.docx", getGoldsDir() + "MailMerge.CleanupOptions Gold.docx")); + } + + /// + /// Return a data table filled with sample data. + /// + private static DataTable getDataTable() + { + DataTable dataTable = new DataTable("StudentCourse"); + dataTable.getColumns().add("CourseName"); + + DataRow dataRowEmpty = dataTable.newRow(); + dataTable.getRows().add(dataRowEmpty); + dataRowEmpty.set(0, ""); + + for (int i = 0; i < 10; i++) + { + DataRow datarow = dataTable.newRow(); + dataTable.getRows().add(datarow); + datarow.set(0, "Course " + i); + } + + return dataTable; + } + + @Test (dataProvider = "unconditionalMergeFieldsAndRegionsDataProvider") + public void unconditionalMergeFieldsAndRegions(boolean countAllMergeFields) throws Exception + { + //ExStart + //ExFor:MailMerge.UnconditionalMergeFieldsAndRegions + //ExSummary:Shows how to merge fields or regions regardless of the parent IF field's condition. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a MERGEFIELD nested inside an IF field. + // Since the IF field statement is false, it will not display the result of the MERGEFIELD. + // The MERGEFIELD will also not receive any data during a mail merge. + FieldIf fieldIf = (FieldIf)builder.insertField(" IF 1 = 2 "); + builder.moveTo(fieldIf.getSeparator()); + builder.insertField(" MERGEFIELD FullName "); + + // If we set the "UnconditionalMergeFieldsAndRegions" flag to "true", + // our mail merge will insert data into non-displayed fields such as our MERGEFIELD as well as all others. + // If we set the "UnconditionalMergeFieldsAndRegions" flag to "false", + // our mail merge will not insert data into MERGEFIELDs hidden by IF fields with false statements. + doc.getMailMerge().setUnconditionalMergeFieldsAndRegions(countAllMergeFields); + + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FullName"); + dataTable.getRows().add("James Bond"); + + doc.getMailMerge().execute(dataTable); + + doc.save(getArtifactsDir() + "MailMerge.UnconditionalMergeFieldsAndRegions.docx"); + + Assert.assertEquals(countAllMergeFields + ? "\u0013 IF 1 = 2 \"James Bond\"\u0014\u0015" + : "\u0013 IF 1 = 2 \u0013 MERGEFIELD FullName \u0014«FullName»\u0015\u0014\u0015", doc.getText().trim()); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "unconditionalMergeFieldsAndRegionsDataProvider") + public static Object[][] unconditionalMergeFieldsAndRegionsDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "retainFirstSectionStartDataProvider") + public void retainFirstSectionStart(boolean isRetainFirstSectionStart, /*SectionStart*/int sectionStart, /*SectionStart*/int expected) throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField(" MERGEFIELD FullName "); + + doc.getFirstSection().getPageSetup().setSectionStart(sectionStart); + doc.getMailMerge().setRetainFirstSectionStart(isRetainFirstSectionStart); + + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FullName"); + dataTable.getRows().add("James Bond"); + + doc.getMailMerge().execute(dataTable); + + for (Section section : (Iterable
          ) doc.getSections()) + Assert.assertEquals(expected, section.getPageSetup().getSectionStart()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "retainFirstSectionStartDataProvider") + public static Object[][] retainFirstSectionStartDataProvider() throws Exception + { + return new Object[][] + { + {true, SectionStart.CONTINUOUS, SectionStart.CONTINUOUS}, + {true, SectionStart.NEW_COLUMN, SectionStart.NEW_COLUMN}, + {true, SectionStart.NEW_PAGE, SectionStart.NEW_PAGE}, + {true, SectionStart.EVEN_PAGE, SectionStart.EVEN_PAGE}, + {true, SectionStart.ODD_PAGE, SectionStart.ODD_PAGE}, + {false, SectionStart.CONTINUOUS, SectionStart.NEW_PAGE}, + {false, SectionStart.NEW_COLUMN, SectionStart.NEW_PAGE}, + {false, SectionStart.NEW_PAGE, SectionStart.NEW_PAGE}, + {false, SectionStart.EVEN_PAGE, SectionStart.EVEN_PAGE}, + {false, SectionStart.ODD_PAGE, SectionStart.ODD_PAGE}, + }; + } + + @Test + public void mailMergeSettings() throws Exception + { + //ExStart + //ExFor:Document.MailMergeSettings + //ExFor:MailMergeCheckErrors + //ExFor:MailMergeDataType + //ExFor:MailMergeDestination + //ExFor:MailMergeMainDocumentType + //ExFor:MailMergeSettings + //ExFor:MailMergeSettings.CheckErrors + //ExFor:MailMergeSettings.Clone + //ExFor:MailMergeSettings.Destination + //ExFor:MailMergeSettings.DataType + //ExFor:MailMergeSettings.DoNotSupressBlankLines + //ExFor:MailMergeSettings.LinkToQuery + //ExFor:MailMergeSettings.MainDocumentType + //ExFor:MailMergeSettings.Odso + //ExFor:MailMergeSettings.Query + //ExFor:MailMergeSettings.ViewMergedData + //ExFor:Odso + //ExFor:Odso.Clone + //ExFor:Odso.ColumnDelimiter + //ExFor:Odso.DataSource + //ExFor:Odso.DataSourceType + //ExFor:Odso.FirstRowContainsColumnNames + //ExFor:OdsoDataSourceType + //ExSummary:Shows how to execute a mail merge with data from an Office Data Source Object. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Dear "); + builder.insertField("MERGEFIELD FirstName", ""); + builder.write(" "); + builder.insertField("MERGEFIELD LastName", ""); + builder.writeln(": "); + builder.insertField("MERGEFIELD Message", ""); + + // Create a data source in the form of an ASCII file, with the "|" character + // acting as the delimiter that separates columns. The first line contains the three columns' names, + // and each subsequent line is a row with their respective values. + String[] lines = { "FirstName|LastName|Message", + "John|Doe|Hello! This message was created with Aspose Words mail merge." }; + String dataSrcFilename = getArtifactsDir() + "MailMerge.MailMergeSettings.DataSource.txt"; + + File.writeAllLines(dataSrcFilename, lines); + + MailMergeSettings settings = doc.getMailMergeSettings(); + settings.setMainDocumentType(MailMergeMainDocumentType.MAILING_LABELS); + settings.setCheckErrors(MailMergeCheckErrors.SIMULATE); + settings.setDataType(MailMergeDataType.NATIVE); + settings.setDataSource(dataSrcFilename); + settings.setQuery("SELECT * FROM " + doc.getMailMergeSettings().getDataSource()); + settings.setLinkToQuery(true); + settings.setViewMergedData(true); + + Assert.assertEquals(MailMergeDestination.DEFAULT, settings.getDestination()); + Assert.assertFalse(settings.getDoNotSupressBlankLines()); + + Odso odso = settings.getOdso(); + odso.setDataSource(dataSrcFilename); + odso.setDataSourceType(OdsoDataSourceType.TEXT); + odso.setColumnDelimiter('|'); + odso.setFirstRowContainsColumnNames(true); + + Assert.Is.Not.SameAs(odso)odso.deepClone()); + Assert.Is.Not.SameAs(settings)settings.deepClone()); + + // Opening this document in Microsoft Word will execute the mail merge before displaying the contents. + doc.save(getArtifactsDir() + "MailMerge.MailMergeSettings.docx"); + //ExEnd + + settings = new Document(getArtifactsDir() + "MailMerge.MailMergeSettings.docx").getMailMergeSettings(); + + Assert.assertEquals(MailMergeMainDocumentType.MAILING_LABELS, settings.getMainDocumentType()); + Assert.assertEquals(MailMergeCheckErrors.SIMULATE, settings.getCheckErrors()); + Assert.assertEquals(MailMergeDataType.NATIVE, settings.getDataType()); + Assert.assertEquals(getArtifactsDir() + "MailMerge.MailMergeSettings.DataSource.txt", settings.getDataSource()); + Assert.assertEquals("SELECT * FROM " + doc.getMailMergeSettings().getDataSource(), settings.getQuery()); + Assert.assertTrue(settings.getLinkToQuery()); + Assert.assertTrue(settings.getViewMergedData()); + + odso = settings.getOdso(); + Assert.assertEquals(getArtifactsDir() + "MailMerge.MailMergeSettings.DataSource.txt", odso.getDataSource()); + Assert.assertEquals(OdsoDataSourceType.TEXT, odso.getDataSourceType()); + Assert.assertEquals('|', odso.getColumnDelimiter()); + Assert.assertTrue(odso.getFirstRowContainsColumnNames()); + } + + @Test + public void odsoEmail() throws Exception + { + //ExStart + //ExFor:MailMergeSettings.ActiveRecord + //ExFor:MailMergeSettings.AddressFieldName + //ExFor:MailMergeSettings.ConnectString + //ExFor:MailMergeSettings.MailAsAttachment + //ExFor:MailMergeSettings.MailSubject + //ExFor:MailMergeSettings.Clear + //ExFor:Odso.TableName + //ExFor:Odso.UdlConnectString + //ExSummary:Shows how to execute a mail merge while connecting to an external data source. + Document doc = new Document(getMyDir() + "Odso data.docx"); + testOdsoEmail(doc); //ExSkip + MailMergeSettings settings = doc.getMailMergeSettings(); + + System.out.println("Connection string:\n\t{settings.ConnectString}"); + System.out.println("Mail merge docs as attachment:\n\t{settings.MailAsAttachment}"); + System.out.println("Mail merge doc e-mail subject:\n\t{settings.MailSubject}"); + System.out.println("Column that contains e-mail addresses:\n\t{settings.AddressFieldName}"); + System.out.println("Active record:\n\t{settings.ActiveRecord}"); + + Odso odso = settings.getOdso(); + + System.out.println("File will connect to data source located in:\n\t\"{odso.DataSource}\""); + System.out.println("Source type:\n\t{odso.DataSourceType}"); + System.out.println("UDL connection string:\n\t{odso.UdlConnectString}"); + System.out.println("Table:\n\t{odso.TableName}"); + System.out.println("Query:\n\t{doc.MailMergeSettings.Query}"); + + // We can reset these settings by clearing them. Once we do that and save the document, + // Microsoft Word will no longer execute a mail merge when we use it to load the document. + settings.clear(); + + doc.save(getArtifactsDir() + "MailMerge.OdsoEmail.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "MailMerge.OdsoEmail.docx"); + Assert.assertEquals("", doc.getMailMergeSettings().getConnectString()); + } + + private void testOdsoEmail(Document doc) + { + MailMergeSettings settings = doc.getMailMergeSettings(); + + Assert.assertFalse(settings.getMailAsAttachment()); + Assert.assertEquals("test subject", settings.getMailSubject()); + Assert.assertEquals("Email_Address", settings.getAddressFieldName()); + Assert.assertEquals(66, settings.getActiveRecord()); + Assert.assertEquals("SELECT * FROM `Contacts` ", settings.getQuery()); + + Odso odso = settings.getOdso(); + + Assert.assertEquals(settings.getConnectString(), odso.getUdlConnectString()); + Assert.assertEquals("Personal Folders|", odso.getDataSource()); + Assert.assertEquals(OdsoDataSourceType.EMAIL, odso.getDataSourceType()); + Assert.assertEquals("Contacts", odso.getTableName()); + } + + @Test + public void mailingLabelMerge() throws Exception + { + //ExStart + //ExFor:MailMergeSettings.DataSource + //ExFor:MailMergeSettings.HeaderSource + //ExSummary:Shows how to construct a data source for a mail merge from a header source and a data source. + // Create a mailing label merge header file, which will consist of a table with one row. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startTable(); + builder.insertCell(); + builder.write("FirstName"); + builder.insertCell(); + builder.write("LastName"); + builder.endTable(); + + doc.save(getArtifactsDir() + "MailMerge.MailingLabelMerge.Header.docx"); + + // Create a mailing label merge data file consisting of a table with one row + // and the same number of columns as the header document's table. + doc = new Document(); + builder = new DocumentBuilder(doc); + + builder.startTable(); + builder.insertCell(); + builder.write("John"); + builder.insertCell(); + builder.write("Doe"); + builder.endTable(); + + doc.save(getArtifactsDir() + "MailMerge.MailingLabelMerge.Data.docx"); + + // Create a merge destination document with MERGEFIELDS with names that + // match the column names in the merge header file table. + doc = new Document(); + builder = new DocumentBuilder(doc); + + builder.write("Dear "); + builder.insertField("MERGEFIELD FirstName", ""); + builder.write(" "); + builder.insertField("MERGEFIELD LastName", ""); + + MailMergeSettings settings = doc.getMailMergeSettings(); + + // Construct a data source for our mail merge by specifying two document filenames. + // The header source will name the columns of the data source table. + settings.setHeaderSource(getArtifactsDir() + "MailMerge.MailingLabelMerge.Header.docx"); + + // The data source will provide rows of data for all the columns in the header document table. + settings.setDataSource(getArtifactsDir() + "MailMerge.MailingLabelMerge.Data.docx"); + + // Configure a mailing label type mail merge, which Microsoft Word will execute + // as soon as we use it to load the output document. + settings.setQuery("SELECT * FROM " + settings.getDataSource()); + settings.setMainDocumentType(MailMergeMainDocumentType.MAILING_LABELS); + settings.setDataType(MailMergeDataType.TEXT_FILE); + settings.setLinkToQuery(true); + settings.setViewMergedData(true); + + doc.save(getArtifactsDir() + "MailMerge.MailingLabelMerge.docx"); + //ExEnd + + Assert.assertEquals("FirstName\u0007LastName\u0007\u0007", new Document(getArtifactsDir() + "MailMerge.MailingLabelMerge.Header.docx"). + getChild(NodeType.TABLE, 0, true).getText().trim()); + + Assert.assertEquals("John\u0007Doe\u0007\u0007", new Document(getArtifactsDir() + "MailMerge.MailingLabelMerge.Data.docx"). + getChild(NodeType.TABLE, 0, true).getText().trim()); + + doc = new Document(getArtifactsDir() + "MailMerge.MailingLabelMerge.docx"); + + Assert.assertEquals(2, doc.getRange().getFields().getCount()); + + settings = doc.getMailMergeSettings(); + + Assert.assertEquals(getArtifactsDir() + "MailMerge.MailingLabelMerge.Header.docx", settings.getHeaderSource()); + Assert.assertEquals(getArtifactsDir() + "MailMerge.MailingLabelMerge.Data.docx", settings.getDataSource()); + Assert.assertEquals("SELECT * FROM " + settings.getDataSource(), settings.getQuery()); + Assert.assertEquals(MailMergeMainDocumentType.MAILING_LABELS, settings.getMainDocumentType()); + Assert.assertEquals(MailMergeDataType.TEXT_FILE, settings.getDataType()); + Assert.assertTrue(settings.getLinkToQuery()); + Assert.assertTrue(settings.getViewMergedData()); + } + + @Test + public void odsoFieldMapDataCollection() throws Exception + { + //ExStart + //ExFor:Odso.FieldMapDatas + //ExFor:OdsoFieldMapData + //ExFor:OdsoFieldMapData.Clone + //ExFor:OdsoFieldMapData.Column + //ExFor:OdsoFieldMapData.MappedName + //ExFor:OdsoFieldMapData.Name + //ExFor:OdsoFieldMapData.Type + //ExFor:OdsoFieldMapDataCollection + //ExFor:OdsoFieldMapDataCollection.Add(OdsoFieldMapData) + //ExFor:OdsoFieldMapDataCollection.Clear + //ExFor:OdsoFieldMapDataCollection.Count + //ExFor:OdsoFieldMapDataCollection.GetEnumerator + //ExFor:OdsoFieldMapDataCollection.Item(Int32) + //ExFor:OdsoFieldMapDataCollection.RemoveAt(Int32) + //ExFor:OdsoFieldMappingType + //ExSummary:Shows how to access the collection of data that maps data source columns to merge fields. + Document doc = new Document(getMyDir() + "Odso data.docx"); + + // This collection defines how a mail merge will map columns from a data source + // to predefined MERGEFIELD, ADDRESSBLOCK and GREETINGLINE fields. + OdsoFieldMapDataCollection dataCollection = doc.getMailMergeSettings().getOdso().getFieldMapDatas(); + Assert.assertEquals(30, dataCollection.getCount()); + + Iterator enumerator = dataCollection.iterator(); + try /*JAVA: was using*/ + { + int index = 0; + while (enumerator.hasNext()) + { + System.out.println("Field map data index {index++}, type \"{enumerator.Current.Type}\":"); + + System.out.println(enumerator.next().getType() != OdsoFieldMappingType.NULL + ? $"\tColumn \"{enumerator.Current.Name}\", number {enumerator.Current.Column} mapped to merge field \"{enumerator.Current.MappedName}\"." + : "\tNo valid column to field mapping data present."); + } + } + finally { if (enumerator != null) enumerator.close(); } + + // Clone the elements in this collection. + Assert.Is.Not.EqualTo(dataCollection.get(0))dataCollection.get(0).deepClone()); + + // Use the "RemoveAt" method elements individually by index. + dataCollection.removeAt(0); + + Assert.assertEquals(29, dataCollection.getCount()); + + // Use the "Clear" method to clear the entire collection at once. + dataCollection.clear(); + + Assert.assertEquals(0, dataCollection.getCount()); + //ExEnd + } + + @Test + public void odsoRecipientDataCollection() throws Exception + { + //ExStart + //ExFor:Odso.RecipientDatas + //ExFor:OdsoRecipientData + //ExFor:OdsoRecipientData.Active + //ExFor:OdsoRecipientData.Clone + //ExFor:OdsoRecipientData.Column + //ExFor:OdsoRecipientData.Hash + //ExFor:OdsoRecipientData.UniqueTag + //ExFor:OdsoRecipientDataCollection + //ExFor:OdsoRecipientDataCollection.Add(OdsoRecipientData) + //ExFor:OdsoRecipientDataCollection.Clear + //ExFor:OdsoRecipientDataCollection.Count + //ExFor:OdsoRecipientDataCollection.GetEnumerator + //ExFor:OdsoRecipientDataCollection.Item(Int32) + //ExFor:OdsoRecipientDataCollection.RemoveAt(Int32) + //ExSummary:Shows how to access the collection of data that designates which merge data source records a mail merge will exclude. + Document doc = new Document(getMyDir() + "Odso data.docx"); + + OdsoRecipientDataCollection dataCollection = doc.getMailMergeSettings().getOdso().getRecipientDatas(); + + Assert.assertEquals(70, dataCollection.getCount()); + + Iterator enumerator = dataCollection.iterator(); + try /*JAVA: was using*/ + { + int index = 0; + while (enumerator.hasNext()) + { + System.out.println("Odso recipient data index {index++} will {(enumerator.Current.Active ? "); + System.out.println("\tColumn #{enumerator.Current.Column}"); + System.out.println("\tHash code: {enumerator.Current.Hash}"); + System.out.println("\tContents array length: {enumerator.Current.UniqueTag.Length}"); + } + } + finally { if (enumerator != null) enumerator.close(); } + + // We can clone the elements in this collection. + Assert.Is.Not.EqualTo(dataCollection.get(0))dataCollection.get(0).deepClone()); + + // We can also remove elements individually, or clear the entire collection at once. + dataCollection.removeAt(0); + + Assert.assertEquals(69, dataCollection.getCount()); + + dataCollection.clear(); + + Assert.assertEquals(0, dataCollection.getCount()); + //ExEnd + } + + @Test + public void changeFieldUpdateCultureSource() throws Exception + { + //ExStart + //ExFor:Document.FieldOptions + //ExFor:FieldOptions + //ExFor:FieldOptions.FieldUpdateCultureSource + //ExFor:FieldUpdateCultureSource + //ExSummary:Shows how to specify the source of the culture used for date formatting during a field update or mail merge. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert two merge fields with German locale. + builder.getFont().setLocaleId(new msCultureInfo("de-DE").getLCID()); + builder.insertField("MERGEFIELD Date1 \\@ \"dddd, d MMMM yyyy\""); + builder.write(" - "); + builder.insertField("MERGEFIELD Date2 \\@ \"dddd, d MMMM yyyy\""); + + // Set the current culture to US English after preserving its original value in a variable. + msCultureInfo currentCulture = CurrentThread.getCurrentCulture(); + CurrentThread.setCurrentCulture(new msCultureInfo("en-US")); + + // This merge will use the current thread's culture to format the date, US English. + doc.getMailMerge().execute(new String[] { "Date1" }, new Object[] { new DateTime(2020, 1, 1) }); + + // Configure the next merge to source its culture value from the field code. The value of that culture will be German. + doc.getFieldOptions().setFieldUpdateCultureSource(FieldUpdateCultureSource.FIELD_CODE); + doc.getMailMerge().execute(new String[] { "Date2" }, new Object[] { new DateTime(2020, 1, 1) }); + + // The first merge result contains a date formatted in English, while the second one is in German. + Assert.assertEquals("Wednesday, 1 January 2020 - Mittwoch, 1 Januar 2020", doc.getRange().getText().trim()); + + // Restore the thread's original culture. + CurrentThread.setCurrentCulture(currentCulture); + //ExEnd + } + + @Test + public void restartListsAtEachSection() throws Exception + { + //ExStart + //ExFor:MailMerge.RestartListsAtEachSection + //ExSummary:Shows how to control whether or not list numbering is restarted at each section when mail merge is performed. + Document doc = new Document(getMyDir() + "Section breaks with numbering.docx"); + + doc.getMailMerge().setRestartListsAtEachSection(false); + doc.getMailMerge().execute(new String[0], new Object[0]); + + doc.save(getArtifactsDir() + "MailMerge.RestartListsAtEachSection.pdf"); + //ExEnd + } + + @Test + public void removeLastEmptyParagraph() throws Exception + { + //ExStart + //ExFor:DocumentBuilder.InsertHtml(String, HtmlInsertOptions) + //ExSummary:Shows how to use options while inserting html. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField(" MERGEFIELD Name "); + builder.insertParagraph(); + builder.insertField(" MERGEFIELD EMAIL "); + builder.insertParagraph(); + + // By default "DocumentBuilder.InsertHtml" inserts a HTML fragment that ends with a block-level HTML element, + // it normally closes that block-level element and inserts a paragraph break. + // As a result, a new empty paragraph appears after inserted document. + // If we specify "HtmlInsertOptions.RemoveLastEmptyParagraph", those extra empty paragraphs will be removed. + builder.moveToMergeField("NAME"); + builder.insertHtml("

          John Smith

          ", HtmlInsertOptions.USE_BUILDER_FORMATTING | HtmlInsertOptions.REMOVE_LAST_EMPTY_PARAGRAPH); + builder.moveToMergeField("EMAIL"); + builder.insertHtml("

          jsmith@example.com

          ", HtmlInsertOptions.USE_BUILDER_FORMATTING); + + doc.save(getArtifactsDir() + "MailMerge.RemoveLastEmptyParagraph.docx"); + //ExEnd + + Assert.assertEquals(4, doc.getFirstSection().getBody().getParagraphs().getCount()); + } + + @Test + public void mustacheTags() throws Exception + { + //ExStart + //ExFor:MustacheTag + //ExFor:MustacheTag.Text + //ExFor:MustacheTag.ReferenceOffset + //ExFor:MustacheTag.ReferenceRun + //ExFor:MailMergeRegionInfo.StartMustacheTag + //ExFor:MailMergeRegionInfo.EndMustacheTag + //ExSummary:Shows how to work with the mustache tags. + Document document = new Document(getMyDir() + "Mail merge mustache tags.docx"); + document.getMailMerge().setUseNonMergeFields(true); + + MailMergeRegionInfo hierarchy = document.getMailMerge().getRegionsHierarchy(); + + for (MustacheTag mustacheTag : hierarchy.getMustacheTags()) + { + System.out.println(mustacheTag.getText()); + msConsole.writeLine(mustacheTag.getReferenceOffset()); + System.out.println(mustacheTag.getReferenceRun()); + } + + for (MailMergeRegionInfo region : hierarchy.getRegions()) + { + System.out.println(region.getStartMustacheTag().getText()); + System.out.println(region.getEndMustacheTag().getText()); + } + //ExEnd + } + + @Test + public void removeEmptyTables() throws Exception + { + //ExStart:RemoveEmptyTables + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:MailMergeCleanupOptions + //ExSummary:Shows how to remove whole empty table during mail merge. + DataTable tableCustomers = new DataTable("A"); + tableCustomers.getColumns().add("CustomerID"); + tableCustomers.getColumns().add("CustomerName"); + tableCustomers.getRows().add(new Object[] { 1, "John Doe" }); + tableCustomers.getRows().add(new Object[] { 2, "Jane Doe" }); + + DataSet ds = new DataSet(); + ds.getTables().add(tableCustomers); + + Document doc = new Document(getMyDir() + "Mail merge tables.docx"); + Assert.assertEquals(2, doc.getChildNodes(NodeType.TABLE, true).getCount()); + + doc.getMailMerge().setMergeDuplicateRegions(false); + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_EMPTY_TABLES | MailMergeCleanupOptions.REMOVE_UNUSED_REGIONS); + doc.getMailMerge().executeWithRegions(ds.getTables().get("A")); + + doc.save(getArtifactsDir() + "MailMerge.RemoveEmptyTables.docx"); + + doc = new Document(getArtifactsDir() + "MailMerge.RemoveEmptyTables.docx"); + Assert.assertEquals(1, doc.getChildNodes(NodeType.TABLE, true).getCount()); + //ExEnd:RemoveEmptyTables + } +} + diff --git a/Examples/ApiExamples/JavaPorting/ExMailMergeCustom.java b/Examples/ApiExamples/JavaPorting/ExMailMergeCustom.java new file mode 100644 index 00000000..f1faf637 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExMailMergeCustom.java @@ -0,0 +1,359 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import com.aspose.ms.java.collections.StringSwitchMap; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import java.util.ArrayList; +import com.aspose.words.IMailMergeDataSource; +import com.aspose.ms.System.Collections.msArrayList; +import com.aspose.words.IMailMergeDataSourceRoot; +import com.aspose.ms.System.Collections.msDictionary; +import java.util.HashMap; +import com.aspose.words.net.System.Data.DataTable; +import com.aspose.words.ref.Ref; + + +@Test +public class ExMailMergeCustom extends ApiExampleBase +{ + //ExStart + //ExFor:IMailMergeDataSource + //ExFor:IMailMergeDataSource.TableName + //ExFor:IMailMergeDataSource.MoveNext + //ExFor:IMailMergeDataSource.GetValue + //ExFor:IMailMergeDataSource.GetChildDataSource + //ExFor:MailMerge.Execute(IMailMergeDataSource) + //ExSummary:Shows how to execute a mail merge with a data source in the form of a custom object. + @Test //ExSkip + public void customDataSource() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertField(" MERGEFIELD FullName "); + builder.insertParagraph(); + builder.insertField(" MERGEFIELD Address "); + + ArrayList customers = new ArrayList(); + { + customers.add(new Customer("Thomas Hardy", "120 Hanover Sq., London")); + customers.add(new Customer("Paolo Accorti", "Via Monte Bianco 34, Torino")); + } + + // To use a custom object as a data source, it must implement the IMailMergeDataSource interface. + CustomerMailMergeDataSource dataSource = new CustomerMailMergeDataSource(customers); + + doc.getMailMerge().execute(dataSource); + + doc.save(getArtifactsDir() + "MailMergeCustom.CustomDataSource.docx"); + testCustomDataSource(customers, new Document(getArtifactsDir() + "MailMergeCustom.CustomDataSource.docx")); //ExSkip + } + + /// + /// An example of a "data entity" class in your application. + /// + public static class Customer + { + public Customer(String aFullName, String anAddress) + { + setFullName(aFullName); + setAddress(anAddress); + } + + public String getFullName() { return mFullName; }; public void setFullName(String value) { mFullName = value; }; + + private String mFullName; + public String getAddress() { return mAddress; }; public void setAddress(String value) { mAddress = value; }; + + private String mAddress; + } + + /// + /// A custom mail merge data source that you implement to allow Aspose.Words + /// to mail merge data from your Customer objects into Microsoft Word documents. + /// + public static class CustomerMailMergeDataSource implements IMailMergeDataSource + { + public CustomerMailMergeDataSource(ArrayList customers) + { + mCustomers = customers; + + // When we initialize the data source, its position must be before the first record. + mRecordIndex = -1; + } + + /// + /// The name of the data source. Used by Aspose.Words only when executing mail merge with repeatable regions. + /// + public String getTableName() { return "Customer"; } + + /// + /// Aspose.Words calls this method to get a value for every data field. + /// + public boolean getValue(String fieldName, /*out*/Ref fieldValue) + { + switch (gStringSwitchMap.of(fieldName)) + { + case /*"FullName"*/0: + fieldValue.set(mCustomers.get(mRecordIndex).getFullName()); + return true; + case /*"Address"*/1: + fieldValue.set(mCustomers.get(mRecordIndex).getAddress()); + return true; + default: + // Return "false" to the Aspose.Words mail merge engine to signify + // that we could not find a field with this name. + fieldValue.set(null); + return false; + } + } + + /// + /// A standard implementation for moving to a next record in a collection. + /// + public boolean moveNext() + { + if (!isEof()) + mRecordIndex++; + + return !isEof(); + } + + public IMailMergeDataSource getChildDataSource(String tableName) + { + return null; + } + + private boolean isEof() { return (mRecordIndex >= mCustomers.size()); } + + private /*final*/ ArrayList mCustomers; + private int mRecordIndex; + } + //ExEnd + + private void testCustomDataSource(ArrayList customerList, Document doc) + { + String[][] mergeData = new String[customerList.size()][]; + + for (int i = 0; i < customerList.size(); i++) + mergeData[i] = new String[] { customerList.get(i).getFullName(), customerList.get(i).getAddress() }; + + TestUtil.mailMergeMatchesArray(mergeData, doc, true); + } + + //ExStart + //ExFor:IMailMergeDataSourceRoot + //ExFor:IMailMergeDataSourceRoot.GetDataSource(String) + //ExFor:MailMerge.ExecuteWithRegions(IMailMergeDataSourceRoot) + //ExSummary:Performs mail merge from a custom data source with master-detail data. + @Test //ExSkip + public void customDataSourceRoot() throws Exception + { + // Create a document with two mail merge regions named "Washington" and "Seattle". + String[] mailMergeRegions = { "Vancouver", "Seattle" }; + Document doc = createSourceDocumentWithMailMergeRegions(mailMergeRegions); + + // Create two data sources for the mail merge. + EmployeeList employeesWashingtonBranch = new EmployeeList(); + msArrayList.add(employeesWashingtonBranch, new Employee("John Doe", "Sales")); + msArrayList.add(employeesWashingtonBranch, new Employee("Jane Doe", "Management")); + + EmployeeList employeesSeattleBranch = new EmployeeList(); + msArrayList.add(employeesSeattleBranch, new Employee("John Cardholder", "Management")); + msArrayList.add(employeesSeattleBranch, new Employee("Joe Bloggs", "Sales")); + + // Register our data sources by name in a data source root. + // If we are about to use this data source root in a mail merge with regions, + // each source's registered name must match the name of an existing mail merge region in the mail merge source document. + DataSourceRoot sourceRoot = new DataSourceRoot(); + sourceRoot.registerSource(mailMergeRegions[0], new EmployeeListMailMergeSource(employeesWashingtonBranch)); + sourceRoot.registerSource(mailMergeRegions[1], new EmployeeListMailMergeSource(employeesSeattleBranch)); + + // Since we have consecutive mail merge regions, we would normally have to perform two mail merges. + // However, one mail merge source with a data root can fill in multiple regions + // if the root contains tables with corresponding names/column names. + doc.getMailMerge().executeWithRegions(sourceRoot); + + doc.save(getArtifactsDir() + "MailMergeCustom.CustomDataSourceRoot.docx"); + testCustomDataSourceRoot(mailMergeRegions, sourceRoot, new Document(getArtifactsDir() + "MailMergeCustom.CustomDataSourceRoot.docx")); //ExSkip + } + + /// + /// Create a document that contains consecutive mail merge regions, with names designated by the input array, + /// for a data table of employees. + /// + private static Document createSourceDocumentWithMailMergeRegions(String[] regions) throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + for (String s : regions) + { + builder.writeln("\n" + s + " branch: "); + builder.insertField(" MERGEFIELD TableStart:" + s); + builder.insertField(" MERGEFIELD FullName"); + builder.write(", "); + builder.insertField(" MERGEFIELD Department"); + builder.insertField(" MERGEFIELD TableEnd:" + s); + } + + return doc; + } + + /// + /// An example of a "data entity" class in your application. + /// + private static class Employee + { + public Employee(String aFullName, String aDepartment) + { + mFullName = aFullName; + mDepartment = aDepartment; + } + + public String getFullName() { return mFullName; }; + + private String mFullName; + public String getDepartment() { return mDepartment; }; + + private String mDepartment; + } + + /// + /// An example of a typed collection that contains your "data" objects. + /// + private static class EmployeeList extends ArrayList + { + public /*new*/ Employee get(int index) { return (Employee)super.get(index); } + public /*new*/void set(int index, Employee value) { super.set(index, value); } + } + + /// + /// Data source root that can be passed directly into a mail merge which can register and contain many child data sources. + /// These sources must all implement IMailMergeDataSource, and are registered and differentiated by a name + /// which corresponds to a mail merge region that will read the respective data. + /// + private static class DataSourceRoot implements IMailMergeDataSourceRoot + { + public IMailMergeDataSource getDataSource(String tableName) + { + EmployeeListMailMergeSource source = mSources.get(tableName); + source.reset(); + return mSources.get(tableName); + } + + public void registerSource(String sourceName, EmployeeListMailMergeSource source) + { + msDictionary.add(mSources, sourceName, source); + } + + private /*final*/ HashMap mSources = new HashMap(); + } + + /// + /// Custom mail merge data source. + /// + private static class EmployeeListMailMergeSource implements IMailMergeDataSource + { + public EmployeeListMailMergeSource(EmployeeList employees) + { + mEmployees = employees; + mRecordIndex = -1; + } + + /// + /// A standard implementation for moving to a next record in a collection. + /// + public boolean moveNext() + { + if (!isEof()) + mRecordIndex++; + + return !isEof(); + } + + private boolean isEof() { return (mRecordIndex >= mEmployees.size()); } + + public void reset() + { + mRecordIndex = -1; + } + + /// + /// The name of the data source. Used by Aspose.Words only when executing mail merge with repeatable regions. + /// + public String getTableName() { return "Employees"; } + + /// + /// Aspose.Words calls this method to get a value for every data field. + /// + public boolean getValue(String fieldName, /*out*/Ref fieldValue) + { + switch (gStringSwitchMap.of(fieldName)) + { + case /*"FullName"*/0: + fieldValue.set(mEmployees.get(mRecordIndex).getFullName()); + return true; + case /*"Department"*/2: + fieldValue.set(mEmployees.get(mRecordIndex).getDepartment()); + return true; + default: + // Return "false" to the Aspose.Words mail merge engine to signify + // that we could not find a field with this name. + fieldValue.set(null); + return false; + } + } + + /// + /// Child data sources are for nested mail merges. + /// + public IMailMergeDataSource getChildDataSource(String tableName) + { + throw new UnsupportedOperationException(); + } + + private /*final*/ EmployeeList mEmployees; + private int mRecordIndex; + } + //ExEnd + + private void testCustomDataSourceRoot(String[] registeredSources, DataSourceRoot sourceRoot, Document doc) + { + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FullName"); + dataTable.getColumns().add("Department"); + + for (int i = 0; i < registeredSources.length; i++) + { + EmployeeListMailMergeSource source = (EmployeeListMailMergeSource)sourceRoot.getDataSource(registeredSources[i]); + while (source.moveNext()) + { + source.GetValue("FullName", /*out*/ Object fullName); + source.GetValue("Department", /*out*/ Object department); + + dataTable.getRows().Add( { fullName, department }); + } + } + + TestUtil.mailMergeMatchesDataTable(dataTable, doc, false); + } + + //JAVA-added for string switch emulation + private static final StringSwitchMap gStringSwitchMap = new StringSwitchMap + ( + "FullName", + "Address", + "Department" + ); + +} diff --git a/Examples/ApiExamples/JavaPorting/ExMailMergeCustomNested.java b/Examples/ApiExamples/JavaPorting/ExMailMergeCustomNested.java new file mode 100644 index 00000000..272036ff --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExMailMergeCustomNested.java @@ -0,0 +1,288 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import com.aspose.ms.java.collections.StringSwitchMap; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.ms.System.Collections.msArrayList; +import java.util.ArrayList; +import com.aspose.words.IMailMergeDataSource; +import com.aspose.words.ref.Ref; + + +@Test +public class ExMailMergeCustomNested extends ApiExampleBase +{ + //ExStart + //ExFor:MailMerge.ExecuteWithRegions(IMailMergeDataSource) + //ExSummary:Shows how to use mail merge regions to execute a nested mail merge. + @Test //ExSkip + public void customDataSource() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Normally, MERGEFIELDs contain the name of a column of a mail merge data source. + // Instead, we can use "TableStart:" and "TableEnd:" prefixes to begin/end a mail merge region. + // Each region will belong to a table with a name that matches the string immediately after the prefix's colon. + builder.insertField(" MERGEFIELD TableStart:Customers"); + + // These MERGEFIELDs are inside the mail merge region of the "Customers" table. + // When we execute the mail merge, this field will receive data from rows in a data source named "Customers". + builder.write("Full name:\t"); + builder.insertField(" MERGEFIELD FullName "); + builder.write("\nAddress:\t"); + builder.insertField(" MERGEFIELD Address "); + builder.write("\nOrders:\n"); + + // Create a second mail merge region inside the outer region for a data source named "Orders". + // The "Orders" data entries have a many-to-one relationship with the "Customers" data source. + builder.insertField(" MERGEFIELD TableStart:Orders"); + + builder.write("\tItem name:\t"); + builder.insertField(" MERGEFIELD Name "); + builder.write("\n\tQuantity:\t"); + builder.insertField(" MERGEFIELD Quantity "); + builder.insertParagraph(); + + builder.insertField(" MERGEFIELD TableEnd:Orders"); + builder.insertField(" MERGEFIELD TableEnd:Customers"); + + // Create related data with names that match those of our mail merge regions. + CustomerList customers = new CustomerList(); + msArrayList.add(customers, new Customer("Thomas Hardy", "120 Hanover Sq., London")); + msArrayList.add(customers, new Customer("Paolo Accorti", "Via Monte Bianco 34, Torino")); + + customers.get(0).getOrders().add(new Order("Rugby World Cup Cap", 2)); + customers.get(0).getOrders().add(new Order("Rugby World Cup Ball", 1)); + customers.get(1).getOrders().add(new Order("Rugby World Cup Guide", 1)); + + // To mail merge from your data source, we must wrap it into an object that implements the IMailMergeDataSource interface. + CustomerMailMergeDataSource customersDataSource = new CustomerMailMergeDataSource(customers); + + doc.getMailMerge().executeWithRegions(customersDataSource); + + doc.save(getArtifactsDir() + "NestedMailMergeCustom.CustomDataSource.docx"); + testCustomDataSource(customers, new Document(getArtifactsDir() + "NestedMailMergeCustom.CustomDataSource.docx")); //ExSkip + } + + /// + /// An example of a "data entity" class in your application. + /// + public static class Customer + { + public Customer(String aFullName, String anAddress) + { + setFullName(aFullName); + setAddress(anAddress); + setOrders(new ArrayList()); + } + + public String getFullName() { return mFullName; }; public void setFullName(String value) { mFullName = value; }; + + private String mFullName; + public String getAddress() { return mAddress; }; public void setAddress(String value) { mAddress = value; }; + + private String mAddress; + public ArrayList getOrders() { return mOrders; }; public void setOrders(ArrayList value) { mOrders = value; }; + + private ArrayList mOrders; + } + + /// + /// An example of a typed collection that contains your "data" objects. + /// + public static class CustomerList extends ArrayList + { + public /*new*/ Customer get(int index) { return (Customer) super.get(index); } + public /*new*/void set(int index, Customer value) { super.set(index, value); } + } + + /// + /// An example of a child "data entity" class in your application. + /// + public static class Order + { + public Order(String oName, int oQuantity) + { + setName(oName); + setQuantity(oQuantity); + } + + public String getName() { return mName; }; public void setName(String value) { mName = value; }; + + private String mName; + public int getQuantity() { return mQuantity; }; public void setQuantity(int value) { mQuantity = value; }; + + private int mQuantity; + } + + /// + /// A custom mail merge data source that you implement to allow Aspose.Words + /// to mail merge data from your Customer objects into Microsoft Word documents. + /// + public static class CustomerMailMergeDataSource implements IMailMergeDataSource + { + public CustomerMailMergeDataSource(CustomerList customers) + { + mCustomers = customers; + + // When we initialize the data source, its position must be before the first record. + mRecordIndex = -1; + } + + /// + /// The name of the data source. Used by Aspose.Words only when executing mail merge with repeatable regions. + /// + public String getTableName() { return "Customers"; } + + /// + /// Aspose.Words calls this method to get a value for every data field. + /// + public boolean getValue(String fieldName, /*out*/Ref fieldValue) + { + switch (gStringSwitchMap.of(fieldName)) + { + case /*"FullName"*/0: + fieldValue.set(mCustomers.get(mRecordIndex).getFullName()); + return true; + case /*"Address"*/1: + fieldValue.set(mCustomers.get(mRecordIndex).getAddress()); + return true; + case /*"Order"*/2: + fieldValue.set(mCustomers.get(mRecordIndex).getOrders()); + return true; + default: + // Return "false" to the Aspose.Words mail merge engine to signify + // that we could not find a field with this name. + fieldValue.set(null); + return false; + } + } + + /// + /// A standard implementation for moving to a next record in a collection. + /// + public boolean moveNext() + { + if (!isEof()) + mRecordIndex++; + + return !isEof(); + } + + public IMailMergeDataSource getChildDataSource(String tableName) + { + switch (gStringSwitchMap.of(tableName)) + { + // Get the child data source, whose name matches the mail merge region that uses its columns. + case /*"Orders"*/3: + return new OrderMailMergeDataSource(mCustomers.get(mRecordIndex).getOrders()); + default: + return null; + } + } + + private boolean isEof() { return (mRecordIndex >= mCustomers.size()); } + + private /*final*/ CustomerList mCustomers; + private int mRecordIndex; + } + + public static class OrderMailMergeDataSource implements IMailMergeDataSource + { + public OrderMailMergeDataSource(ArrayList orders) + { + mOrders = orders; + + // When we initialize the data source, its position must be before the first record. + mRecordIndex = -1; + } + + /// + /// The name of the data source. Used by Aspose.Words only when executing mail merge with repeatable regions. + /// + public String getTableName() { return "Orders"; } + + /// + /// Aspose.Words calls this method to get a value for every data field. + /// + public boolean getValue(String fieldName, /*out*/Ref fieldValue) + { + switch (gStringSwitchMap.of(fieldName)) + { + case /*"Name"*/4: + fieldValue.set(mOrders.get(mRecordIndex).getName()); + return true; + case /*"Quantity"*/5: + fieldValue.set(mOrders.get(mRecordIndex).getQuantity()); + return true; + default: + // Return "false" to the Aspose.Words mail merge engine to signify + // that we could not find a field with this name. + fieldValue.set(null); + return false; + } + } + + /// + /// A standard implementation for moving to a next record in a collection. + /// + public boolean moveNext() + { + if (!isEof()) + mRecordIndex++; + + return !isEof(); + } + + /// + /// Return null because we do not have any child elements for this sort of object. + /// + public IMailMergeDataSource getChildDataSource(String tableName) + { + return null; + } + + private boolean isEof() { return (mRecordIndex >= mOrders.size()); } + + private /*final*/ ArrayList mOrders; + private int mRecordIndex; + } + //ExEnd + + private void testCustomDataSource(CustomerList customers, Document doc) + { + ArrayList mailMergeData = new ArrayList(); + + for (Customer customer : (Iterable) customers) + { + for (Order order : (Iterable) customer.getOrders()) + mailMergeData.add(new String[]{ order.getName(), Integer.toString(order.getQuantity()) }); + mailMergeData.add(new String[] {customer.getFullName(), customer.getAddress()}); + } + + TestUtil.mailMergeMatchesArray(msArrayList.toArray(mailMergeData, new String[][0]), doc, false); + } + + //JAVA-added for string switch emulation + private static final StringSwitchMap gStringSwitchMap = new StringSwitchMap + ( + "FullName", + "Address", + "Order", + "Orders", + "Name", + "Quantity" + ); + +} diff --git a/Examples/ApiExamples/JavaPorting/ExMailMergeEvent.java b/Examples/ApiExamples/JavaPorting/ExMailMergeEvent.java new file mode 100644 index 00000000..a2b5cd14 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExMailMergeEvent.java @@ -0,0 +1,414 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.IFieldMergingCallback; +import com.aspose.words.FieldMergingArgs; +import com.aspose.words.ImageFieldMergingArgs; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.net.System.Data.DataTable; +import com.aspose.words.net.System.Data.DataRow; +import java.awt.Color; +import com.aspose.words.Shape; +import com.aspose.words.NodeType; +import com.aspose.words.ImageType; +import com.aspose.words.net.System.Data.IDataReader; +import com.aspose.ms.System.IO.MemoryStream; + + +@Test +public class ExMailMergeEvent extends ApiExampleBase +{ + //ExStart + //ExFor:DocumentBuilder.InsertHtml(String) + //ExFor:MailMerge.FieldMergingCallback + //ExFor:IFieldMergingCallback + //ExFor:FieldMergingArgs + //ExFor:FieldMergingArgsBase + //ExFor:FieldMergingArgsBase.Field + //ExFor:FieldMergingArgsBase.DocumentFieldName + //ExFor:FieldMergingArgsBase.Document + //ExFor:IFieldMergingCallback.FieldMerging + //ExFor:FieldMergingArgs.Text + //ExSummary:Shows how to execute a mail merge with a custom callback that handles merge data in the form of HTML documents. + @Test //ExSkip + public void mergeHtml() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField("MERGEFIELD html_Title \\b Content"); + builder.insertField("MERGEFIELD html_Body \\b Content"); + + Object[] mergeData = + { + "" + + "

          " + + "Hello World!" + + "

          " + + "", + + "" + + "
          " + + "

          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

          " + + "
          " + + "" + }; + + doc.getMailMerge().setFieldMergingCallback(new HandleMergeFieldInsertHtml()); + doc.getMailMerge().execute(new String[] { "html_Title", "html_Body" }, mergeData); + + doc.save(getArtifactsDir() + "MailMergeEvent.MergeHtml.docx"); + } + + /// + /// If the mail merge encounters a MERGEFIELD whose name starts with the "html_" prefix, + /// this callback parses its merge data as HTML content and adds the result to the document location of the MERGEFIELD. + /// + private static class HandleMergeFieldInsertHtml implements IFieldMergingCallback + { + /// + /// Called when a mail merge merges data into a MERGEFIELD. + /// + public void /*IFieldMergingCallback.*/fieldMerging(FieldMergingArgs args) throws Exception + { + if (args.getDocumentFieldName().startsWith("html_") && args.getField().getFieldCode().contains("\\b")) + { + // Add parsed HTML data to the document's body. + DocumentBuilder builder = new DocumentBuilder(args.getDocument()); + builder.moveToMergeField(args.getDocumentFieldName()); + builder.insertHtml((String)args.getFieldValue()); + + // Since we have already inserted the merged content manually, + // we will not need to respond to this event by returning content via the "Text" property. + args.setText(""); + } + } + + public void /*IFieldMergingCallback.*/imageFieldMerging(ImageFieldMergingArgs args) + { + // Do nothing. + } + } + //ExEnd + + //ExStart + //ExFor:FieldMergingArgsBase.FieldValue + //ExSummary:Shows how to edit values that MERGEFIELDs receive as a mail merge takes place. + @Test //ExSkip + public void fieldFormats() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert some MERGEFIELDs with format switches that will edit the values they will receive during a mail merge. + builder.insertField("MERGEFIELD text_Field1 \\* Caps", null); + builder.write(", "); + builder.insertField("MERGEFIELD text_Field2 \\* Upper", null); + builder.write(", "); + builder.insertField("MERGEFIELD numeric_Field1 \\# 0.0", null); + + builder.getDocument().getMailMerge().setFieldMergingCallback(new FieldValueMergingCallback()); + + builder.getDocument().getMailMerge().execute( + new String[] { "text_Field1", "text_Field2", "numeric_Field1" }, + new Object[] { "Field 1", "Field 2", 10 }); + String t = doc.getText().trim(); + Assert.assertEquals("Merge Value For \"Text_Field1\": Field 1, MERGE VALUE FOR \"TEXT_FIELD2\": FIELD 2, 10000.0", doc.getText().trim()); + } + + /// + /// Edits the values that MERGEFIELDs receive during a mail merge. + /// The name of a MERGEFIELD must have a prefix for this callback to take effect on its value. + /// + private static class FieldValueMergingCallback implements IFieldMergingCallback + { + /// + /// Called when a mail merge merges data into a MERGEFIELD. + /// + public void /*IFieldMergingCallback.*/fieldMerging(FieldMergingArgs e) + { + if (e.getFieldName().startsWith("text_")) + e.setFieldValue("Merge value for \"{e.FieldName}\": {(string)e.FieldValue}"); + else if (e.getFieldName().startsWith("numeric_")) + e.setFieldValue((/*int*/Integer)e.getFieldValue() * 1000); + } + + public void /*IFieldMergingCallback.*/imageFieldMerging(ImageFieldMergingArgs e) + { + // Do nothing. + } + } + //ExEnd + + //ExStart + //ExFor:DocumentBuilder.MoveToMergeField(String) + //ExFor:FieldMergingArgsBase.FieldName + //ExFor:FieldMergingArgsBase.TableName + //ExFor:FieldMergingArgsBase.RecordIndex + //ExSummary:Shows how to insert checkbox form fields into MERGEFIELDs as merge data during mail merge. + @Test //ExSkip + public void insertCheckBox() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Use MERGEFIELDs with "TableStart"/"TableEnd" tags to define a mail merge region + // which belongs to a data source named "StudentCourse" and has a MERGEFIELD which accepts data from a column named "CourseName". + builder.startTable(); + builder.insertCell(); + builder.insertField(" MERGEFIELD TableStart:StudentCourse "); + builder.insertCell(); + builder.insertField(" MERGEFIELD CourseName "); + builder.insertCell(); + builder.insertField(" MERGEFIELD TableEnd:StudentCourse "); + builder.endTable(); + + doc.getMailMerge().setFieldMergingCallback(new HandleMergeFieldInsertCheckBox()); + + DataTable dataTable = getStudentCourseDataTable(); + + doc.getMailMerge().executeWithRegions(dataTable); + doc.save(getArtifactsDir() + "MailMergeEvent.InsertCheckBox.docx"); + TestUtil.mailMergeMatchesDataTable(dataTable, new Document(getArtifactsDir() + "MailMergeEvent.InsertCheckBox.docx"), false); //ExSkip + } + + /// + /// Upon encountering a MERGEFIELD with a specific name, inserts a check box form field instead of merge data text. + /// + private static class HandleMergeFieldInsertCheckBox implements IFieldMergingCallback + { + /// + /// Called when a mail merge merges data into a MERGEFIELD. + /// + public void /*IFieldMergingCallback.*/fieldMerging(FieldMergingArgs args) throws Exception + { + if ("CourseName".equals(args.getDocumentFieldName())) + { + Assert.assertEquals("StudentCourse", args.getTableName()); + + DocumentBuilder builder = new DocumentBuilder(args.getDocument()); + builder.moveToMergeField(args.getFieldName()); + builder.insertCheckBox(args.getDocumentFieldName() + mCheckBoxCount, false, 0); + + String fieldValue = args.getFieldValue().toString(); + + // In this case, for every record index 'n', the corresponding field value is "Course n". + Assert.assertEquals(char.GetNumericValue(fieldValue.charAt(7)), args.getRecordIndex()); + + builder.write(fieldValue); + mCheckBoxCount++; + } + } + + public void /*IFieldMergingCallback.*/imageFieldMerging(ImageFieldMergingArgs args) + { + // Do nothing. + } + + private int mCheckBoxCount; + } + + /// + /// Creates a mail merge data source. + /// + private static DataTable getStudentCourseDataTable() + { + DataTable dataTable = new DataTable("StudentCourse"); + dataTable.getColumns().add("CourseName"); + for (int i = 0; i < 10; i++) + { + DataRow datarow = dataTable.newRow(); + dataTable.getRows().add(datarow); + datarow.set(0, "Course " + i); + } + + return dataTable; + } + //ExEnd + + //ExStart + //ExFor:MailMerge.ExecuteWithRegions(DataTable) + //ExSummary:Demonstrates how to format cells during a mail merge. + @Test //ExSkip + public void alternatingRows() throws Exception + { + Document doc = new Document(getMyDir() + "Mail merge destination - Northwind suppliers.docx"); + + doc.getMailMerge().setFieldMergingCallback(new HandleMergeFieldAlternatingRows()); + + DataTable dataTable = getSuppliersDataTable(); + doc.getMailMerge().executeWithRegions(dataTable); + + doc.save(getArtifactsDir() + "MailMergeEvent.AlternatingRows.docx"); + TestUtil.mailMergeMatchesDataTable(dataTable, new Document(getArtifactsDir() + "MailMergeEvent.AlternatingRows.docx"), false); //ExSkip + } + + /// + /// Formats table rows as a mail merge takes place to alternate between two colors on odd/even rows. + /// + private static class HandleMergeFieldAlternatingRows implements IFieldMergingCallback + { + /// + /// Called when a mail merge merges data into a MERGEFIELD. + /// + public void /*IFieldMergingCallback.*/fieldMerging(FieldMergingArgs args) + { + if (mBuilder == null) + mBuilder = new DocumentBuilder(args.getDocument()); + + // This is true of we are on the first column, which means we have moved to a new row. + if ("CompanyName".equals(args.getFieldName())) + { + Color rowColor = isOdd(mRowIdx) ? new Color((213), (227), (235)) : new Color((242), (242), (242)); + + for (int colIdx = 0; colIdx < 4; colIdx++) + { + mBuilder.moveToCell(0, mRowIdx, colIdx, 0); + mBuilder.getCellFormat().getShading().setBackgroundPatternColor(rowColor); + } + + mRowIdx++; + } + } + + public void /*IFieldMergingCallback.*/imageFieldMerging(ImageFieldMergingArgs args) + { + // Do nothing. + } + + private DocumentBuilder mBuilder; + private int mRowIdx; + } + + /// + /// Function needed for Visual Basic autoporting that returns the parity of the passed number. + /// + private static boolean isOdd(int value) + { + return (((value / 2 * 2)) == (value)); + } + + /// + /// Creates a mail merge data source. + /// + private static DataTable getSuppliersDataTable() + { + DataTable dataTable = new DataTable("Suppliers"); + dataTable.getColumns().add("CompanyName"); + dataTable.getColumns().add("ContactName"); + for (int i = 0; i < 10; i++) + { + DataRow datarow = dataTable.newRow(); + dataTable.getRows().add(datarow); + datarow.set(0, "Company " + i); + datarow.set(1, "Contact " + i); + } + + return dataTable; + } + //ExEnd + + @Test + public void imageFromUrl() throws Exception + { + //ExStart + //ExFor:MailMerge.Execute(String[], Object[]) + //ExSummary:Shows how to merge an image from a URI as mail merge data into a MERGEFIELD. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // MERGEFIELDs with "Image:" tags will receive an image during a mail merge. + // The string after the colon in the "Image:" tag corresponds to a column name + // in the data source whose cells contain URIs of image files. + builder.insertField("MERGEFIELD Image:logo_FromWeb "); + builder.insertField("MERGEFIELD Image:logo_FromFileSystem "); + + // Create a data source that contains URIs of images that we will merge. + // A URI can be a web URL that points to an image, or a local file system filename of an image file. + String[] columns = { "logo_FromWeb", "logo_FromFileSystem" }; + Object[] URIs = { getImageUrl(), getImageDir() + "Logo.jpg" }; + + // Execute a mail merge on a data source with one row. + doc.getMailMerge().execute(columns, URIs); + + doc.save(getArtifactsDir() + "MailMergeEvent.ImageFromUrl.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "MailMergeEvent.ImageFromUrl.docx"); + + Shape imageShape = (Shape)doc.getChild(NodeType.SHAPE, 1, true); + + TestUtil.verifyImageInShape(400, 400, ImageType.JPEG, imageShape); + + imageShape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyImageInShape(272, 92, ImageType.PNG, imageShape); + } + + //ExStart + //ExFor:MailMerge.FieldMergingCallback + //ExFor:MailMerge.ExecuteWithRegions(IDataReader,String) + //ExFor:IFieldMergingCallback + //ExFor:ImageFieldMergingArgs + //ExFor:IFieldMergingCallback.FieldMerging + //ExFor:IFieldMergingCallback.ImageFieldMerging + //ExFor:ImageFieldMergingArgs.ImageStream + //ExSummary:Shows how to insert images stored in a database BLOB field into a report. + @Test (groups = "IgnoreOnJenkins") //ExSkip + public void imageFromBlob() throws Exception + { + Document doc = new Document(getMyDir() + "Mail merge destination - Northwind employees.docx"); + + doc.getMailMerge().setFieldMergingCallback(new HandleMergeImageFieldFromBlob()); + + String connString = $"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={DatabaseDir + "Northwind.accdb"};"; + String query = "SELECT FirstName, LastName, Title, Address, City, Region, Country, PhotoBLOB FROM Employees"; + + OleDbConnection conn = new OleDbConnection(connString); + try /*JAVA: was using*/ + { + conn.Open(); + + // Open the data reader, which needs to be in a mode that reads all records at once. + OleDbCommand cmd = new OleDbCommand(query, conn); + IDataReader dataReader = cmd.ExecuteReader(); + + doc.getMailMerge().executeWithRegions(dataReader, "Employees"); + } + finally { if (conn != null) conn.close(); } + + doc.save(getArtifactsDir() + "MailMergeEvent.ImageFromBlob.docx"); + TestUtil.mailMergeMatchesQueryResult(getDatabaseDir() + "Northwind.accdb", query, new Document(getArtifactsDir() + "MailMergeEvent.ImageFromBlob.docx"), false); //ExSkip + } + + private static class HandleMergeImageFieldFromBlob implements IFieldMergingCallback + { + public void /*IFieldMergingCallback.*/fieldMerging(FieldMergingArgs args) + { + // Do nothing. + } + + /// + /// This is called when a mail merge encounters a MERGEFIELD in the document with an "Image:" tag in its name. + /// + public void /*IFieldMergingCallback.*/imageFieldMerging(ImageFieldMergingArgs e) throws Exception + { + MemoryStream imageStream = new MemoryStream((byte[])e.getFieldValue()); + e.setImageStreamInternal(imageStream); + } + } + //ExEnd +} + diff --git a/Examples/ApiExamples/JavaPorting/ExMarkdownLoadOptions.java b/Examples/ApiExamples/JavaPorting/ExMarkdownLoadOptions.java new file mode 100644 index 00000000..f9d83ce2 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExMarkdownLoadOptions.java @@ -0,0 +1,96 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.ms.System.IO.MemoryStream; +import com.aspose.ms.System.Text.Encoding; +import com.aspose.words.MarkdownLoadOptions; +import com.aspose.words.Document; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.Paragraph; +import com.aspose.words.NodeType; +import com.aspose.words.Underline; +import com.aspose.words.ControlChar; + + +@Test +public class ExMarkdownLoadOptions extends ApiExampleBase +{ + @Test + public void preserveEmptyLines() throws Exception + { + //ExStart:PreserveEmptyLines + //GistId:a775441ecb396eea917a2717cb9e8f8f + //ExFor:MarkdownLoadOptions + //ExFor:MarkdownLoadOptions.#ctor + //ExFor:MarkdownLoadOptions.PreserveEmptyLines + //ExSummary:Shows how to preserve empty line while load a document. + String mdText = $"{Environment.NewLine}Line1{Environment.NewLine}{Environment.NewLine}Line2{Environment.NewLine}{Environment.NewLine}"; + MemoryStream stream = new MemoryStream(Encoding.getUTF8().getBytes(mdText)); + try /*JAVA: was using*/ + { + MarkdownLoadOptions loadOptions = new MarkdownLoadOptions(); { loadOptions.setPreserveEmptyLines(true); } + Document doc = new Document(stream, loadOptions); + + Assert.assertEquals("\rLine1\r\rLine2\r\f", doc.getText()); + } + finally { if (stream != null) stream.close(); } + //ExEnd:PreserveEmptyLines + } + + @Test + public void importUnderlineFormatting() throws Exception + { + //ExStart:ImportUnderlineFormatting + //GistId:e06aa7a168b57907a5598e823a22bf0a + //ExFor:MarkdownLoadOptions.ImportUnderlineFormatting + //ExSummary:Shows how to recognize plus characters "++" as underline text formatting. + MemoryStream stream = new MemoryStream(Encoding.getASCII().getBytes("++12 and B++")); + try /*JAVA: was using*/ + { + MarkdownLoadOptions loadOptions = new MarkdownLoadOptions(); { loadOptions.setImportUnderlineFormatting(true); } + Document doc = new Document(stream, loadOptions); + + Paragraph para = (Paragraph)doc.getChild(NodeType.PARAGRAPH, 0, true); + Assert.assertEquals(Underline.SINGLE, para.getRuns().get(0).getFont().getUnderline()); + + loadOptions = new MarkdownLoadOptions(); { loadOptions.setImportUnderlineFormatting(false); } + doc = new Document(stream, loadOptions); + + para = (Paragraph)doc.getChild(NodeType.PARAGRAPH, 0, true); + Assert.assertEquals(Underline.NONE, para.getRuns().get(0).getFont().getUnderline()); + } + finally { if (stream != null) stream.close(); } + //ExEnd:ImportUnderlineFormatting + } + + @Test + public void softLineBreakCharacter() throws Exception + { + //ExStart:SoftLineBreakCharacter + //GistId:571cc6e23284a2ec075d15d4c32e3bbf + //ExFor:MarkdownLoadOptions.SoftLineBreakCharacter + //ExSummary:Shows how to set soft line break character. + MemoryStream stream = new MemoryStream(Encoding.getUTF8().getBytes("line1\nline2")); + try /*JAVA: was using*/ + { + MarkdownLoadOptions loadOptions = new MarkdownLoadOptions(); + loadOptions.setSoftLineBreakCharacter(ControlChar.LINE_BREAK_CHAR); + Document doc = new Document(stream, loadOptions); + + Assert.assertEquals("line1\u000bline2", doc.getText().trim()); + } + finally { if (stream != null) stream.close(); } + //ExEnd:SoftLineBreakCharacter + } +} + diff --git a/Examples/ApiExamples/JavaPorting/ExMarkdownSaveOptions.java b/Examples/ApiExamples/JavaPorting/ExMarkdownSaveOptions.java new file mode 100644 index 00000000..a6a0c0e5 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExMarkdownSaveOptions.java @@ -0,0 +1,455 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.TableContentAlignment; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.ParagraphAlignment; +import com.aspose.words.MarkdownSaveOptions; +import com.aspose.words.Document; +import com.aspose.words.Table; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.SaveFormat; +import com.aspose.ms.System.IO.Directory; +import com.aspose.words.IImageSavingCallback; +import com.aspose.words.ImageSavingArgs; +import com.aspose.ms.System.IO.FileStream; +import com.aspose.ms.System.IO.FileMode; +import com.aspose.ms.System.IO.File; +import com.aspose.words.MarkdownListExportMode; +import com.aspose.ms.System.IO.Path; +import com.aspose.words.Underline; +import com.aspose.words.ShapeType; +import com.aspose.words.MarkdownLinkExportMode; +import com.aspose.words.MarkdownExportAsHtml; +import com.aspose.ms.System.Environment; +import com.aspose.words.MarkdownOfficeMathExportMode; +import com.aspose.words.MarkdownEmptyParagraphExportMode; +import org.testng.annotations.DataProvider; + + +@Test +class ExMarkdownSaveOptions !Test class should be public in Java to run, please fix .Net source! extends ApiExampleBase +{ + @Test (dataProvider = "markdownDocumentTableContentAlignmentDataProvider") + public void markdownDocumentTableContentAlignment(/*TableContentAlignment*/int tableContentAlignment) throws Exception + { + //ExStart + //ExFor:TableContentAlignment + //ExFor:MarkdownSaveOptions.TableContentAlignment + //ExSummary:Shows how to align contents in tables. + DocumentBuilder builder = new DocumentBuilder(); + + builder.insertCell(); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.RIGHT); + builder.write("Cell1"); + builder.insertCell(); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.write("Cell2"); + + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); { saveOptions.setTableContentAlignment(tableContentAlignment); } + + builder.getDocument().save(getArtifactsDir() + "MarkdownSaveOptions.MarkdownDocumentTableContentAlignment.md", saveOptions); + + Document doc = new Document(getArtifactsDir() + "MarkdownSaveOptions.MarkdownDocumentTableContentAlignment.md"); + Table table = doc.getFirstSection().getBody().getTables().get(0); + + switch (tableContentAlignment) + { + case TableContentAlignment.AUTO: + Assert.assertEquals(ParagraphAlignment.RIGHT, table.getFirstRow().getCells().get(0).getFirstParagraph().getParagraphFormat().getAlignment()); + Assert.assertEquals(ParagraphAlignment.CENTER, table.getFirstRow().getCells().get(1).getFirstParagraph().getParagraphFormat().getAlignment()); + break; + case TableContentAlignment.LEFT: + Assert.assertEquals(ParagraphAlignment.LEFT, table.getFirstRow().getCells().get(0).getFirstParagraph().getParagraphFormat().getAlignment()); + Assert.assertEquals(ParagraphAlignment.LEFT, table.getFirstRow().getCells().get(1).getFirstParagraph().getParagraphFormat().getAlignment()); + break; + case TableContentAlignment.CENTER: + Assert.assertEquals(ParagraphAlignment.CENTER, table.getFirstRow().getCells().get(0).getFirstParagraph().getParagraphFormat().getAlignment()); + Assert.assertEquals(ParagraphAlignment.CENTER, table.getFirstRow().getCells().get(1).getFirstParagraph().getParagraphFormat().getAlignment()); + break; + case TableContentAlignment.RIGHT: + Assert.assertEquals(ParagraphAlignment.RIGHT, table.getFirstRow().getCells().get(0).getFirstParagraph().getParagraphFormat().getAlignment()); + Assert.assertEquals(ParagraphAlignment.RIGHT, table.getFirstRow().getCells().get(1).getFirstParagraph().getParagraphFormat().getAlignment()); + break; + } + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "markdownDocumentTableContentAlignmentDataProvider") + public static Object[][] markdownDocumentTableContentAlignmentDataProvider() throws Exception + { + return new Object[][] + { + {TableContentAlignment.LEFT}, + {TableContentAlignment.RIGHT}, + {TableContentAlignment.CENTER}, + {TableContentAlignment.AUTO}, + }; + } + + //ExStart + //ExFor:MarkdownSaveOptions + //ExFor:MarkdownSaveOptions.#ctor + //ExFor:MarkdownSaveOptions.ImageSavingCallback + //ExFor:MarkdownSaveOptions.SaveFormat + //ExFor:IImageSavingCallback + //ExSummary:Shows how to rename the image name during saving into Markdown document. + @Test //ExSkip + public void renameImages() throws Exception + { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + // If we convert a document that contains images into Markdown, we will end up with one Markdown file which links to several images. + // Each image will be in the form of a file in the local file system. + // There is also a callback that can customize the name and file system location of each image. + saveOptions.setImageSavingCallback(new SavedImageRename("MarkdownSaveOptions.HandleDocument.md")); + saveOptions.setSaveFormat(SaveFormat.MARKDOWN); + + // The ImageSaving() method of our callback will be run at this time. + doc.save(getArtifactsDir() + "MarkdownSaveOptions.HandleDocument.md", saveOptions); + + Assert.That(Directory.getFiles(getArtifactsDir()) + .Where(s => s.StartsWith(ArtifactsDir + "MarkdownSaveOptions.HandleDocument.md shape")) + .Count(f => f.EndsWith(".jpeg")), assertEquals(1, ); + Assert.That(Directory.getFiles(getArtifactsDir()) + .Where(s => s.StartsWith(ArtifactsDir + "MarkdownSaveOptions.HandleDocument.md shape")) + .Count(f => f.EndsWith(".png")), assertEquals(8, ); + } + + /// + /// Renames saved images that are produced when an Markdown document is saved. + /// + public static class SavedImageRename implements IImageSavingCallback + { + public SavedImageRename(String outFileName) + { + mOutFileName = outFileName; + } + + public void /*IImageSavingCallback.*/imageSaving(ImageSavingArgs args) throws Exception + { + String imageFileName = $"{mOutFileName} shape {++mCount}, of type {args.CurrentShape.ShapeType}{Path.GetExtension(args.ImageFileName)}"; + + args.setImageFileName(imageFileName); + args.ImageStream = new FileStream(getArtifactsDir() + imageFileName, FileMode.CREATE); + + Assert.That(args.ImageStream.CanWrite, assertTrue(); + Assert.assertTrue(args.isImageAvailable()); + Assert.assertFalse(args.getKeepImageStreamOpen()); + } + + private int mCount; + private /*final*/ String mOutFileName; + } + //ExEnd + + @Test (dataProvider = "exportImagesAsBase64DataProvider") + public void exportImagesAsBase64(boolean exportImagesAsBase64) throws Exception + { + //ExStart + //ExFor:MarkdownSaveOptions.ExportImagesAsBase64 + //ExSummary:Shows how to save a .md document with images embedded inside it. + Document doc = new Document(getMyDir() + "Images.docx"); + + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); { saveOptions.setExportImagesAsBase64(exportImagesAsBase64); } + + doc.save(getArtifactsDir() + "MarkdownSaveOptions.ExportImagesAsBase64.md", saveOptions); + + String outDocContents = File.readAllText(getArtifactsDir() + "MarkdownSaveOptions.ExportImagesAsBase64.md"); + + Assert.assertTrue(exportImagesAsBase64 + ? outDocContents.contains("data:image/jpeg;base64") + : outDocContents.contains("MarkdownSaveOptions.ExportImagesAsBase64.001.jpeg")); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "exportImagesAsBase64DataProvider") + public static Object[][] exportImagesAsBase64DataProvider() throws Exception + { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test (dataProvider = "listExportModeDataProvider") + public void listExportMode(/*MarkdownListExportMode*/int markdownListExportMode) throws Exception + { + //ExStart + //ExFor:MarkdownSaveOptions.ListExportMode + //ExFor:MarkdownListExportMode + //ExSummary:Shows how to list items will be written to the markdown document. + Document doc = new Document(getMyDir() + "List item.docx"); + + // Use MarkdownListExportMode.PlainText or MarkdownListExportMode.MarkdownSyntax to export list. + MarkdownSaveOptions options = new MarkdownSaveOptions(); { options.setListExportMode(markdownListExportMode); } + doc.save(getArtifactsDir() + "MarkdownSaveOptions.ListExportMode.md", options); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "listExportModeDataProvider") + public static Object[][] listExportModeDataProvider() throws Exception + { + return new Object[][] + { + {MarkdownListExportMode.PLAIN_TEXT}, + {MarkdownListExportMode.MARKDOWN_SYNTAX}, + }; + } + + @Test + public void imagesFolder() throws Exception + { + //ExStart + //ExFor:MarkdownSaveOptions.ImagesFolder + //ExFor:MarkdownSaveOptions.ImagesFolderAlias + //ExSummary:Shows how to specifies the name of the folder used to construct image URIs. + DocumentBuilder builder = new DocumentBuilder(); + + builder.writeln("Some image below:"); + builder.insertImage(getImageDir() + "Logo.jpg"); + + String imagesFolder = Path.combine(getArtifactsDir(), "ImagesDir"); + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + // Use the "ImagesFolder" property to assign a folder in the local file system into which + // Aspose.Words will save all the document's linked images. + saveOptions.setImagesFolder(imagesFolder); + // Use the "ImagesFolderAlias" property to use this folder + // when constructing image URIs instead of the images folder's name. + saveOptions.setImagesFolderAlias("http://example.com/images"); + + builder.getDocument().save(getArtifactsDir() + "MarkdownSaveOptions.ImagesFolder.md", saveOptions); + //ExEnd + + String[] dirFiles = Directory.getFiles(imagesFolder, "MarkdownSaveOptions.ImagesFolder.001.jpeg"); + Assert.assertEquals(1, dirFiles.length); + Document doc = new Document(getArtifactsDir() + "MarkdownSaveOptions.ImagesFolder.md"); + doc.getText().contains("http://example.com/images/MarkdownSaveOptions.ImagesFolder.001.jpeg"); + } + + @Test + public void exportUnderlineFormatting() throws Exception + { + //ExStart:ExportUnderlineFormatting + //GistId:eeeec1fbf118e95e7df3f346c91ed726 + //ExFor:MarkdownSaveOptions.ExportUnderlineFormatting + //ExSummary:Shows how to export underline formatting as ++. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.setUnderline(Underline.SINGLE); + builder.write("Lorem ipsum. Dolor sit amet."); + + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); { saveOptions.setExportUnderlineFormatting(true); } + doc.save(getArtifactsDir() + "MarkdownSaveOptions.ExportUnderlineFormatting.md", saveOptions); + //ExEnd:ExportUnderlineFormatting + } + + @Test + public void linkExportMode() throws Exception + { + //ExStart:LinkExportMode + //GistId:ac8ba4eb35f3fbb8066b48c999da63b0 + //ExFor:MarkdownSaveOptions.LinkExportMode + //ExFor:MarkdownLinkExportMode + //ExSummary:Shows how to links will be written to the .md file. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertShape(ShapeType.BALLOON, 100.0, 100.0); + + // Image will be written as reference: + // ![ref1] + // + // [ref1]: aw_ref.001.png + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + saveOptions.setLinkExportMode(MarkdownLinkExportMode.REFERENCE); + doc.save(getArtifactsDir() + "MarkdownSaveOptions.LinkExportMode.Reference.md", saveOptions); + + // Image will be written as inline: + // ![](aw_inline.001.png) + saveOptions.setLinkExportMode(MarkdownLinkExportMode.INLINE); + doc.save(getArtifactsDir() + "MarkdownSaveOptions.LinkExportMode.Inline.md", saveOptions); + //ExEnd:LinkExportMode + + String outDocContents = File.readAllText(getArtifactsDir() + "MarkdownSaveOptions.LinkExportMode.Inline.md"); + Assert.assertEquals("![](MarkdownSaveOptions.LinkExportMode.Inline.001.png)", outDocContents.trim()); + } + + @Test + public void exportTableAsHtml() throws Exception + { + //ExStart:ExportTableAsHtml + //GistId:bb594993b5fe48692541e16f4d354ac2 + //ExFor:MarkdownExportAsHtml + //ExFor:MarkdownSaveOptions.ExportAsHtml + //ExSummary:Shows how to export a table to Markdown as raw HTML. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Sample table:"); + + // Create table. + builder.insertCell(); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.RIGHT); + builder.write("Cell1"); + builder.insertCell(); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.write("Cell2"); + + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + saveOptions.setExportAsHtml(MarkdownExportAsHtml.TABLES); + + doc.save(getArtifactsDir() + "MarkdownSaveOptions.ExportTableAsHtml.md", saveOptions); + //ExEnd:ExportTableAsHtml + + String newLine = Environment.getNewLine(); + String outDocContents = File.readAllText(getArtifactsDir() + "MarkdownSaveOptions.ExportTableAsHtml.md"); + Assert.assertEquals("Sample table:{newLine}" + + "
          " + + "

          Cell1

          " + + "
          " + + "

          Cell2

          " + + "
          ", outDocContents.trim()); + } + + @Test + public void imageResolution() throws Exception + { + //ExStart:ImageResolution + //GistId:f86d49dc0e6781b93e576539a01e6ca2 + //ExFor:MarkdownSaveOptions.ImageResolution + //ExSummary:Shows how to set the output resolution for images. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + saveOptions.setImageResolution(300); + + doc.save(getArtifactsDir() + "MarkdownSaveOptions.ImageResolution.md", saveOptions); + //ExEnd:ImageResolution + } + + @Test + public void officeMathExportMode() throws Exception + { + //ExStart:OfficeMathExportMode + //GistId:f86d49dc0e6781b93e576539a01e6ca2 + //ExFor:MarkdownSaveOptions.OfficeMathExportMode + //ExFor:MarkdownOfficeMathExportMode + //ExSummary:Shows how OfficeMath will be written to the document. + Document doc = new Document(getMyDir() + "Office math.docx"); + + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + saveOptions.setOfficeMathExportMode(MarkdownOfficeMathExportMode.IMAGE); + + doc.save(getArtifactsDir() + "MarkdownSaveOptions.OfficeMathExportMode.md", saveOptions); + //ExEnd:OfficeMathExportMode + } + + @Test (dataProvider = "emptyParagraphExportModeDataProvider") + public void emptyParagraphExportMode(/*MarkdownEmptyParagraphExportMode*/int exportMode) throws Exception + { + //ExStart:EmptyParagraphExportMode + //GistId:ad73e0dd58a8c2ae742bb64f8561df35 + //ExFor:MarkdownEmptyParagraphExportMode + //ExFor:MarkdownSaveOptions.EmptyParagraphExportMode + //ExSummary:Shows how to export empty paragraphs. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("First"); + builder.writeln("\r\n\r\n\r\n"); + builder.writeln("Last"); + + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + saveOptions.setEmptyParagraphExportMode(exportMode); + + doc.save(getArtifactsDir() + "MarkdownSaveOptions.EmptyParagraphExportMode.md", saveOptions); + + String result = File.readAllText(getArtifactsDir() + "MarkdownSaveOptions.EmptyParagraphExportMode.md"); + + switch (exportMode) + { + case MarkdownEmptyParagraphExportMode.NONE: + Assert.assertEquals("First\r\n\r\nLast\r\n", result); + break; + case MarkdownEmptyParagraphExportMode.EMPTY_LINE: + Assert.assertEquals("First\r\n\r\n\r\n\r\n\r\nLast\r\n\r\n", result); + break; + case MarkdownEmptyParagraphExportMode.MARKDOWN_HARD_LINE_BREAK: + Assert.assertEquals("First\r\n\\\r\n\\\r\n\\\r\n\\\r\n\\\r\nLast\r\n
          \r\n", result); + break; + } + //ExEnd:EmptyParagraphExportMode + } + + //JAVA-added data provider for test method + @DataProvider(name = "emptyParagraphExportModeDataProvider") + public static Object[][] emptyParagraphExportModeDataProvider() throws Exception + { + return new Object[][] + { + {MarkdownEmptyParagraphExportMode.NONE}, + {MarkdownEmptyParagraphExportMode.EMPTY_LINE}, + {MarkdownEmptyParagraphExportMode.MARKDOWN_HARD_LINE_BREAK}, + }; + } + + @Test + public void nonCompatibleTables() throws Exception + { + //ExStart:NonCompatibleTables + //GistId:571cc6e23284a2ec075d15d4c32e3bbf + //ExFor:MarkdownExportAsHtml + //ExSummary:Shows how to export tables that cannot be correctly represented in pure Markdown as raw HTML. + String outputPath = getArtifactsDir() + "MarkdownSaveOptions.NonCompatibleTables.md"; + + Document doc = new Document(getMyDir() + "Non compatible table.docx"); + + // With the "NonCompatibleTables" option, you can export tables that have a complex structure with merged cells + // or nested tables to raw HTML and leave simple tables in Markdown format. + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + saveOptions.setExportAsHtml(MarkdownExportAsHtml.NON_COMPATIBLE_TABLES); + + doc.save(outputPath, saveOptions); + //ExEnd:NonCompatibleTables + + DocumentHelper.findTextInFile(outputPath, ""); + DocumentHelper.findTextInFile(outputPath, "|Heading 1|Heading 2|"); + } + + @Test + public void exportOfficeMathAsLatex() throws Exception + { + //ExStart:ExportOfficeMathAsLatex + //GistId:045648ef22da6b384ebcf0344717bfb5 + //ExFor:MarkdownSaveOptions.OfficeMathExportMode + //ExFor:MarkdownOfficeMathExportMode + //ExSummary:Shows how to export OfficeMath object as Latex. + Document doc = new Document(getMyDir() + "Office math.docx"); + + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + saveOptions.setOfficeMathExportMode(MarkdownOfficeMathExportMode.LATEX); + + doc.save(getArtifactsDir() + "MarkdownSaveOptions.ExportOfficeMathAsLatex.md", saveOptions); + //ExEnd:ExportOfficeMathAsLatex + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "MarkdownSaveOptions.ExportOfficeMathAsLatex.md", + getGoldsDir() + "MarkdownSaveOptions.ExportOfficeMathAsLatex.Gold.md")); + } +} + + diff --git a/Examples/ApiExamples/JavaPorting/ExMetered.java b/Examples/ApiExamples/JavaPorting/ExMetered.java new file mode 100644 index 00000000..31dd21ae --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExMetered.java @@ -0,0 +1,62 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import org.testng.Assert; +import com.aspose.words.Metered; +import com.aspose.ms.System.msConsole; +import com.aspose.words.Document; +import java.lang.Thread; + + +@Test +public class ExMetered extends ApiExampleBase +{ + @Test + public void testMeteredUsage() + { + Assert.Throws(usage); + } + + @Test (enabled = false) + public void usage() throws Exception + { + //ExStart + //ExFor:Metered + //ExFor:Metered.#ctor + //ExFor:Metered.GetConsumptionCredit + //ExFor:Metered.GetConsumptionQuantity + //ExFor:Metered.SetMeteredKey(String, String) + //ExFor:Metered.IsMeteredLicensed + //ExFor:Metered.GetProductName + //ExSummary:Shows how to activate a Metered license and track credit/consumption. + // Create a new Metered license, and then print its usage statistics. + Metered metered = new Metered(); + metered.setMeteredKey("MyPublicKey", "MyPrivateKey"); + + System.out.println("Is metered license accepted: {Metered.IsMeteredLicensed()}"); + System.out.println("Product name: {metered.GetProductName()}"); + System.out.println("Credit before operation: {Metered.GetConsumptionCredit()}"); + System.out.println("Consumption quantity before operation: {Metered.GetConsumptionQuantity()}"); + + // Operate using Aspose.Words, and then print our metered stats again to see how much we spent. + Document doc = new Document(getMyDir() + "Document.docx"); + doc.save(getArtifactsDir() + "Metered.Usage.pdf"); + + // Aspose Metered Licensing mechanism does not send the usage data to purchase server every time, + // you need to use waiting. + Thread.sleep(10000); + + System.out.println("Credit after operation: {Metered.GetConsumptionCredit()}"); + System.out.println("Consumption quantity after operation: {Metered.GetConsumptionQuantity()}"); + //ExEnd + } +} diff --git a/Examples/ApiExamples/JavaPorting/ExMossDoc2Pdf.java b/Examples/ApiExamples/JavaPorting/ExMossDoc2Pdf.java new file mode 100644 index 00000000..9c0b68a5 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExMossDoc2Pdf.java @@ -0,0 +1,131 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import com.aspose.ms.java.collections.StringSwitchMap; +import com.aspose.ms.System.IO.StreamWriter; +import java.util.Date; +import com.aspose.ms.System.DateTime; +import com.aspose.ms.System.Globalization.msCultureInfo; +import com.aspose.ms.System.Environment; +import com.aspose.words.Document; +import com.aspose.words.PdfSaveOptions; + + +/// +/// DOC2PDF document converter for SharePoint. +/// Uses Aspose.Words to perform the conversion. +/// +public /*static*/ class ExMossDoc2Pdf +{ + /* Simulation of static class by using private constructor */ + private ExMossDoc2Pdf() + {} + + /// + /// The main entry point for the application. + /// + @STAThread + public static void mossDoc2Pdf(String[] args) throws Exception + { + // Although SharePoint passes "-log " to us and we are + // supposed to log there, we will use our hardcoded path to the log file for the sake of simplicity. + // + // Make sure there are permissions to write into this folder. + // The document converter will be called under the document + // conversion account (not sure what name), so for testing purposes, + // I would give the Users group write permissions into this folder. + gLog = new StreamWriter("C:\\Aspose2Pdf\\log.txt", true); + + try + { + gLog.writeLine(new Date.toString(msCultureInfo.getInvariantCulture()) + " Started"); + gLog.writeLine(Environment.getCommandLine()); + + parseCommandLine(args); + + // Uncomment the code below when you have purchased a license for Aspose.Words. + // + // You need to deploy the license in the same folder as your + // executable, alternatively you can add the license file as an + // embedded resource to your project. + // + // Set license for Aspose.Words. + // Aspose.Words.License wordsLicense = new Aspose.Words.License(); + // wordsLicense.SetLicense("Aspose.Total.lic"); + + convertDoc2Pdf(gInFileName, gOutFileName); + } + catch (Exception e) + { + gLog.writeLine(e.getMessage()); + Environment.setExitCode(100); + } + finally + { + gLog.close(); + } + } + + private static void parseCommandLine(String[] args) + { + int i = 0; + while (i < args.length) + { + String s = args[i]; + switch (gStringSwitchMap.of(s.toLowerCase())) + { + case /*"-in"*/0: + i++; + gInFileName = args[i]; + break; + case /*"-out"*/1: + i++; + gOutFileName = args[i]; + break; + case /*"-config"*/2: + // Skip the name of the config file and do nothing. + i++; + break; + case /*"-log"*/3: + // Skip the name of the log file and do nothing. + i++; + break; + default: + throw new Exception("Unknown command line argument: " + s); + } + + i++; + } + } + + private static void convertDoc2Pdf(String inFileName, String outFileName) throws Exception + { + // You can load not only DOC here, but any format supported by + // Aspose.Words: DOC, DOCX, RTF, WordML, HTML, MHTML, ODT etc. + Document doc = new Document(inFileName); + + doc.save(outFileName, new PdfSaveOptions()); + } + + private static String gInFileName; + private static String gOutFileName; + private static StreamWriter gLog; + + //JAVA-added for string switch emulation + private static final StringSwitchMap gStringSwitchMap = new StringSwitchMap + ( + "-in", + "-out", + "-config", + "-log" + ); + +} diff --git a/Examples/ApiExamples/JavaPorting/ExMossRtf2Docx.java b/Examples/ApiExamples/JavaPorting/ExMossRtf2Docx.java new file mode 100644 index 00000000..02a7785b --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExMossRtf2Docx.java @@ -0,0 +1,30 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import com.aspose.words.Document; +import com.aspose.words.SaveFormat; + + +public /*static*/ class ExMossRtf2Docx +{ + /* Simulation of static class by using private constructor */ + private ExMossRtf2Docx() + {} + + public static void convertRtfToDocx(String inFileName, String outFileName) throws Exception + { + // Load an RTF file into Aspose.Words. + Document doc = new Document(inFileName); + + // Save the document in the OOXML format. + doc.save(outFileName, SaveFormat.DOCX); + } +} diff --git a/Examples/ApiExamples/JavaPorting/ExNode.java b/Examples/ApiExamples/JavaPorting/ExNode.java new file mode 100644 index 00000000..54824739 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExNode.java @@ -0,0 +1,760 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.Paragraph; +import com.aspose.words.Run; +import com.aspose.words.Node; +import org.testng.Assert; +import com.aspose.words.CompositeNode; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.NodeType; +import com.aspose.words.Shape; +import com.aspose.words.ShapeType; +import com.aspose.words.WrapType; +import com.aspose.words.NodeCollection; +import com.aspose.ms.System.msConsole; +import com.aspose.words.Inline; +import com.aspose.ms.System.msString; +import com.aspose.words.TableCollection; +import com.aspose.words.Table; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.BreakType; +import com.aspose.words.Section; +import com.aspose.words.NodeList; +import java.util.Iterator; +import com.aspose.words.Body; +import com.aspose.words.SaveFormat; +import com.aspose.words.HtmlSaveOptions; +import com.aspose.ms.System.Text.msStringBuilder; +import com.aspose.words.INodeChangingCallback; +import com.aspose.words.NodeChangingArgs; +import com.aspose.words.NodeChangingAction; +import com.aspose.words.RunCollection; + + +@Test +public class ExNode extends ApiExampleBase +{ + @Test + public void cloneCompositeNode() throws Exception + { + //ExStart + //ExFor:Node + //ExFor:Node.Clone + //ExSummary:Shows how to clone a composite node. + Document doc = new Document(); + Paragraph para = doc.getFirstSection().getBody().getFirstParagraph(); + para.appendChild(new Run(doc, "Hello world!")); + + // Below are two ways of cloning a composite node. + // 1 - Create a clone of a node, and create a clone of each of its child nodes as well. + Node cloneWithChildren = para.deepClone(true); + + Assert.assertTrue(((CompositeNode)cloneWithChildren).hasChildNodes()); + Assert.assertEquals("Hello world!", cloneWithChildren.getText().trim()); + + // 2 - Create a clone of a node just by itself without any children. + Node cloneWithoutChildren = para.deepClone(false); + + Assert.assertFalse(((CompositeNode)cloneWithoutChildren).hasChildNodes()); + Assert.assertEquals("", cloneWithoutChildren.getText().trim()); + //ExEnd + } + + @Test + public void getParentNode() throws Exception + { + //ExStart + //ExFor:Node.ParentNode + //ExSummary:Shows how to access a node's parent node. + Document doc = new Document(); + Paragraph para = doc.getFirstSection().getBody().getFirstParagraph(); + + // Append a child Run node to the document's first paragraph. + Run run = new Run(doc, "Hello world!"); + para.appendChild(run); + + // The paragraph is the parent node of the run node. We can trace this lineage + // all the way to the document node, which is the root of the document's node tree. + Assert.assertEquals(para, run.getParentNode()); + Assert.assertEquals(doc.getFirstSection().getBody(), para.getParentNode()); + Assert.assertEquals(doc.getFirstSection(), doc.getFirstSection().getBody().getParentNode()); + Assert.assertEquals(doc, doc.getFirstSection().getParentNode()); + //ExEnd + } + + @Test + public void ownerDocument() throws Exception + { + //ExStart + //ExFor:Node.Document + //ExFor:Node.ParentNode + //ExSummary:Shows how to create a node and set its owning document. + Document doc = new Document(); + Paragraph para = new Paragraph(doc); + para.appendChild(new Run(doc, "Hello world!")); + + // We have not yet appended this paragraph as a child to any composite node. + Assert.assertNull(para.getParentNode()); + + // If a node is an appropriate child node type of another composite node, + // we can attach it as a child only if both nodes have the same owner document. + // The owner document is the document we passed to the node's constructor. + // We have not attached this paragraph to the document, so the document does not contain its text. + Assert.assertEquals(para.getDocument(), doc); + Assert.assertEquals("", doc.getText().trim()); + + // Since the document owns this paragraph, we can apply one of its styles to the paragraph's contents. + para.getParagraphFormat().setStyle(doc.getStyles().get("Heading 1")); + + // Add this node to the document, and then verify its contents. + doc.getFirstSection().getBody().appendChild(para); + + Assert.assertEquals(doc.getFirstSection().getBody(), para.getParentNode()); + Assert.assertEquals("Hello world!", doc.getText().trim()); + //ExEnd + + Assert.assertEquals(doc, para.getDocument()); + Assert.Is.Not.Nullpara.getParentNode()); + } + + @Test + public void childNodesEnumerate() throws Exception + { + //ExStart + //ExFor:Node + //ExFor:Node.CustomNodeId + //ExFor:NodeType + //ExFor:CompositeNode + //ExFor:CompositeNode.GetChild + //ExFor:CompositeNode.GetChildNodes(NodeType, bool) + //ExFor:NodeCollection.Count + //ExFor:NodeCollection.Item + //ExSummary:Shows how to traverse through a composite node's collection of child nodes. + Document doc = new Document(); + + // Add two runs and one shape as child nodes to the first paragraph of this document. + Paragraph paragraph = (Paragraph)doc.getChild(NodeType.PARAGRAPH, 0, true); + paragraph.appendChild(new Run(doc, "Hello world! ")); + + Shape shape = new Shape(doc, ShapeType.RECTANGLE); + shape.setWidth(200.0); + shape.setHeight(200.0); + // Note that the 'CustomNodeId' is not saved to an output file and exists only during the node lifetime. + shape.setCustomNodeId(100); + shape.setWrapType(WrapType.INLINE); + paragraph.appendChild(shape); + + paragraph.appendChild(new Run(doc, "Hello again!")); + + // Iterate through the paragraph's collection of immediate children, + // and print any runs or shapes that we find within. + NodeCollection children = paragraph.getChildNodes(NodeType.ANY, false); + + Assert.assertEquals(3, paragraph.getChildNodes(NodeType.ANY, false).getCount()); + + for (Node child : (Iterable) children) + switch (child.getNodeType()) + { + case NodeType.RUN: + System.out.println("Run contents:"); + System.out.println("\t\"{child.GetText().Trim()}\""); + break; + case NodeType.SHAPE: + Shape childShape = (Shape)child; + System.out.println("Shape:"); + System.out.println("\t{childShape.ShapeType}, {childShape.Width}x{childShape.Height}"); + Assert.assertEquals(100, shape.getCustomNodeId()); //ExSkip + break; + } + //ExEnd + + Assert.assertEquals(NodeType.RUN, paragraph.getChild(NodeType.RUN, 0, true).getNodeType()); + Assert.assertEquals("Hello world! Hello again!", doc.getText().trim()); + } + + //ExStart + //ExFor:Node.NextSibling + //ExFor:CompositeNode.FirstChild + //ExFor:Node.IsComposite + //ExFor:CompositeNode.IsComposite + //ExFor:Node.NodeTypeToString + //ExFor:Paragraph.NodeType + //ExFor:Table.NodeType + //ExFor:Node.NodeType + //ExFor:Footnote.NodeType + //ExFor:FormField.NodeType + //ExFor:SmartTag.NodeType + //ExFor:Cell.NodeType + //ExFor:Row.NodeType + //ExFor:Document.NodeType + //ExFor:Comment.NodeType + //ExFor:Run.NodeType + //ExFor:Section.NodeType + //ExFor:SpecialChar.NodeType + //ExFor:Shape.NodeType + //ExFor:FieldEnd.NodeType + //ExFor:FieldSeparator.NodeType + //ExFor:FieldStart.NodeType + //ExFor:BookmarkStart.NodeType + //ExFor:CommentRangeEnd.NodeType + //ExFor:BuildingBlock.NodeType + //ExFor:GlossaryDocument.NodeType + //ExFor:BookmarkEnd.NodeType + //ExFor:GroupShape.NodeType + //ExFor:CommentRangeStart.NodeType + //ExSummary:Shows how to traverse a composite node's tree of child nodes. + @Test //ExSkip + public void recurseChildren() throws Exception + { + Document doc = new Document(getMyDir() + "Paragraphs.docx"); + + // Any node that can contain child nodes, such as the document itself, is composite. + Assert.assertTrue(doc.isComposite()); + + // Invoke the recursive function that will go through and print all the child nodes of a composite node. + traverseAllNodes(doc, 0); + } + + /// + /// Recursively traverses a node tree while printing the type of each node + /// with an indent depending on depth as well as the contents of all inline nodes. + /// + @Test (enabled = false) + public void traverseAllNodes(CompositeNode parentNode, int depth) + { + for (Node childNode = parentNode.getFirstChild(); childNode != null; childNode = childNode.getNextSibling()) + { + msConsole.write($"{new string('\t', depth)}{Node.NodeTypeToString(childNode.NodeType)}"); + + // Recurse into the node if it is a composite node. Otherwise, print its contents if it is an inline node. + if (childNode.isComposite()) + { + msConsole.writeLine(); + traverseAllNodes((CompositeNode)childNode, depth + 1); + } + else if (childNode instanceof Inline) + { + System.out.println(" - \"{childNode.GetText().Trim()}\""); + } + else + { + msConsole.writeLine(); + } + } + } + //ExEnd + + @Test + public void removeNodes() throws Exception + { + + //ExStart + //ExFor:Node + //ExFor:Node.NodeType + //ExFor:Node.Remove + //ExSummary:Shows how to remove all child nodes of a specific type from a composite node. + Document doc = new Document(getMyDir() + "Tables.docx"); + + Assert.assertEquals(2, doc.getChildNodes(NodeType.TABLE, true).getCount()); + + Node curNode = doc.getFirstSection().getBody().getFirstChild(); + + while (curNode != null) + { + // Save the next sibling node as a variable in case we want to move to it after deleting this node. + Node nextNode = curNode.getNextSibling(); + + // A section body can contain Paragraph and Table nodes. + // If the node is a Table, remove it from the parent. + if (curNode.getNodeType() == NodeType.TABLE) + curNode.remove(); + + curNode = nextNode; + } + + Assert.assertEquals(0, doc.getChildNodes(NodeType.TABLE, true).getCount()); + //ExEnd + } + + @Test + public void enumNextSibling() throws Exception + { + //ExStart + //ExFor:CompositeNode.FirstChild + //ExFor:Node.NextSibling + //ExFor:Node.NodeTypeToString + //ExFor:Node.NodeType + //ExSummary:Shows how to use a node's NextSibling property to enumerate through its immediate children. + Document doc = new Document(getMyDir() + "Paragraphs.docx"); + + for (Node node = doc.getFirstSection().getBody().getFirstChild(); node != null; node = node.getNextSibling()) + { + msConsole.writeLine(); + System.out.println("Node type: {Node.NodeTypeToString(node.NodeType)}"); + + String contents = node.getText().trim(); + System.out.println(msString.equals(contents, "") ? "This node contains no text" : $"Contents: \"{node.GetText().Trim()}\""); + } + //ExEnd + } + + @Test + public void typedAccess() throws Exception + { + + //ExStart + //ExFor:Story.Tables + //ExFor:Table.FirstRow + //ExFor:Table.LastRow + //ExFor:TableCollection + //ExSummary:Shows how to remove the first and last rows of all tables in a document. + Document doc = new Document(getMyDir() + "Tables.docx"); + + TableCollection tables = doc.getFirstSection().getBody().getTables(); + + Assert.assertEquals(5, tables.get(0).getRows().getCount()); + Assert.assertEquals(4, tables.get(1).getRows().getCount()); + + for (Table table : tables.
          Heading 1
          OfType() !!Autoporter error: Undefined expression type ) + { + table.getFirstRow()?.Remove(); + table.getLastRow()?.Remove(); + } + + Assert.assertEquals(3, tables.get(0).getRows().getCount()); + Assert.assertEquals(2, tables.get(1).getRows().getCount()); + //ExEnd + } + + @Test + public void removeChild() throws Exception + { + //ExStart + //ExFor:CompositeNode.LastChild + //ExFor:Node.PreviousSibling + //ExFor:CompositeNode.RemoveChild``1(``0) + //ExSummary:Shows how to use of methods of Node and CompositeNode to remove a section before the last section in the document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Section 1 text."); + builder.insertBreak(BreakType.SECTION_BREAK_CONTINUOUS); + builder.writeln("Section 2 text."); + + // Both sections are siblings of each other. + Section lastSection = (Section)doc.getLastChild(); + Section firstSection = (Section)lastSection.getPreviousSibling(); + + // Remove a section based on its sibling relationship with another section. + if (lastSection.getPreviousSibling() != null) + doc.removeChild(firstSection); + + // The section we removed was the first one, leaving the document with only the second. + Assert.assertEquals("Section 2 text.", doc.getText().trim()); + //ExEnd + } + + @Test + public void selectCompositeNodes() throws Exception + { + //ExStart + //ExFor:CompositeNode.SelectSingleNode + //ExFor:CompositeNode.SelectNodes + //ExFor:NodeList.GetEnumerator + //ExFor:NodeList.ToArray + //ExSummary:Shows how to select certain nodes by using an XPath expression. + Document doc = new Document(getMyDir() + "Tables.docx"); + + // This expression will extract all paragraph nodes, + // which are descendants of any table node in the document. + NodeList nodeList = doc.selectNodes("//Table//Paragraph"); + + // Iterate through the list with an enumerator and print the contents of every paragraph in each cell of the table. + int index = 0; + + Iterator e = nodeList.iterator(); + try /*JAVA: was using*/ + { + while (e.hasNext()) + System.out.println("Table paragraph index {index++}, contents: \"{e.Current.GetText().Trim()}\""); + } + finally { if (e != null) e.close(); } + + // This expression will select any paragraphs that are direct children of any Body node in the document. + nodeList = doc.selectNodes("//Body/Paragraph"); + + // We can treat the list as an array. + Assert.assertEquals(4, nodeList.toArray().length); + + // Use SelectSingleNode to select the first result of the same expression as above. + Node node = doc.selectSingleNode("//Body/Paragraph"); + + Assert.assertEquals(Paragraph.class, node.getClass()); + //ExEnd + } + + @Test + public void testNodeIsInsideField() throws Exception + { + //ExStart + //ExFor:CompositeNode.SelectNodes + //ExSummary:Shows how to use an XPath expression to test whether a node is inside a field. + Document doc = new Document(getMyDir() + "Mail merge destination - Northwind employees.docx"); + + // The NodeList that results from this XPath expression will contain all nodes we find inside a field. + // However, FieldStart and FieldEnd nodes can be on the list if there are nested fields in the path. + // Currently does not find rare fields in which the FieldCode or FieldResult spans across multiple paragraphs. + NodeList resultList = + doc.selectNodes("//FieldStart/following-sibling::node()[following-sibling::FieldEnd]"); + + // Check if the specified run is one of the nodes that are inside the field. + System.out.println("Contents of the first Run node that's part of a field: {resultList.First(n => n.NodeType == NodeType.Run).GetText().Trim()}"); + //ExEnd + } + + @Test + public void createAndAddParagraphNode() throws Exception + { + Document doc = new Document(); + + Paragraph para = new Paragraph(doc); + + Section section = doc.getLastSection(); + section.getBody().appendChild(para); + } + + @Test + public void removeSmartTagsFromCompositeNode() throws Exception + { + //ExStart + //ExFor:CompositeNode.RemoveSmartTags + //ExSummary:Removes all smart tags from descendant nodes of a composite node. + Document doc = new Document(getMyDir() + "Smart tags.doc"); + + Assert.assertEquals(8, doc.getChildNodes(NodeType.SMART_TAG, true).getCount()); + + doc.removeSmartTags(); + + Assert.assertEquals(0, doc.getChildNodes(NodeType.SMART_TAG, true).getCount()); + //ExEnd + } + + @Test + public void getIndexOfNode() throws Exception + { + //ExStart + //ExFor:CompositeNode.IndexOf + //ExSummary:Shows how to get the index of a given child node from its parent. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + Body body = doc.getFirstSection().getBody(); + + // Retrieve the index of the last paragraph in the body of the first section. + Assert.assertEquals(24, body.getChildNodes(NodeType.ANY, false).indexOf(body.getLastParagraph())); + //ExEnd + } + + @Test + public void convertNodeToHtmlWithDefaultOptions() throws Exception + { + //ExStart + //ExFor:Node.ToString(SaveFormat) + //ExFor:Node.ToString(SaveOptions) + //ExSummary:Exports the content of a node to String in HTML format. + Document doc = new Document(getMyDir() + "Document.docx"); + + Node node = doc.getLastSection().getBody().getLastParagraph(); + + // When we call the ToString method using the html SaveFormat overload, + // it converts the node's contents to their raw html representation. + Assert.assertEquals("

          " + + "Hello World!" + + "

          ", node.toString(SaveFormat.HTML)); + + // We can also modify the result of this conversion using a SaveOptions object. + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + saveOptions.setExportRelativeFontSize(true); + + Assert.assertEquals("

          " + + "Hello World!" + + "

          ", node.toString(saveOptions)); + //ExEnd + } + + @Test + public void typedNodeCollectionToArray() throws Exception + { + //ExStart + //ExFor:ParagraphCollection.ToArray + //ExSummary:Shows how to create an array from a NodeCollection. + Document doc = new Document(getMyDir() + "Paragraphs.docx"); + + Paragraph[] paras = doc.getFirstSection().getBody().getParagraphs().toArray(); + + Assert.assertEquals(22, paras.length); + //ExEnd + } + + @Test + public void nodeEnumerationHotRemove() throws Exception + { + //ExStart + //ExFor:ParagraphCollection.ToArray + //ExSummary:Shows how to use "hot remove" to remove a node during enumeration. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("The first paragraph"); + builder.writeln("The second paragraph"); + builder.writeln("The third paragraph"); + builder.writeln("The fourth paragraph"); + + // Remove a node from the collection in the middle of an enumeration. + for (Paragraph para : doc.getFirstSection().getBody().getParagraphs().toArray()) + if (para.getRange().getText().contains("third")) + para.remove(); + + Assert.assertFalse(doc.getText().contains("The third paragraph")); + //ExEnd + } + + //ExStart + //ExFor:CompositeNode.CreateNavigator + //ExSummary:Shows how to create an XPathNavigator, and then use it to traverse and read nodes. + @Test //ExSkip + public void nodeXPathNavigator() throws Exception + { + Document doc = new Document(); + XPathNavigator navigator = doc.CreateNavigator(); + + if (navigator != null) + { + Assert.assertEquals("Document", navigator.Name); + Assert.assertEquals(false, navigator.MoveToNext()); + Assert.assertEquals(1, navigator.SelectChildren(XPathNodeType.All).Count); + + // The document tree has the document, first section, + // body, and first paragraph as nodes, with each being an only child of the previous. + // We can add a few more to give the tree some branches for the navigator to traverse. + DocumentBuilder docBuilder = new DocumentBuilder(doc); + docBuilder.write("Section 1, Paragraph 1. "); + docBuilder.insertParagraph(); + docBuilder.write("Section 1, Paragraph 2. "); + doc.appendChild(new Section(doc)); + docBuilder.moveToSection(1); + docBuilder.write("Section 2, Paragraph 1. "); + + // Use our navigator to print a map of all the nodes in the document to the console. + StringBuilder stringBuilder = new StringBuilder(); + mapDocument(navigator, stringBuilder, 0); + msConsole.write(stringBuilder.toString()); + testNodeXPathNavigator(stringBuilder.toString(), doc); //ExSkip + } + } + + /// + /// Traverses all children of a composite node and map the structure in the style of a directory tree. + /// The amount of space indentation indicates depth relative to the initial node. + /// Prints the text contents of the current node only if it is a Run. + /// + private static void mapDocument(XPathNavigator navigator, StringBuilder stringBuilder, int depth) + { + do + { + msStringBuilder.append(stringBuilder, ' ', depth); + msStringBuilder.append(stringBuilder, navigator.Name + ": "); + + if ("Run".equals(navigator.Name)) + { + msStringBuilder.append(stringBuilder, navigator.Value); + } + + stringBuilder.append('\n'); + + if (navigator.HasChildren) + { + navigator.MoveToFirstChild(); + mapDocument(navigator, stringBuilder, depth + 1); + navigator.MoveToParent(); + } + } while (navigator.MoveToNext()); + } + //ExEnd + + private void testNodeXPathNavigator(String navigatorResult, Document doc) + { + for (Run run : doc.getChildNodes(NodeType.RUN, true).toArray().OfType() !!Autoporter error: Undefined expression type ) + Assert.assertTrue(navigatorResult.contains(run.getText().trim())); + } + + //ExStart + //ExFor:NodeChangingAction + //ExFor:NodeChangingArgs.Action + //ExFor:NodeChangingArgs.NewParent + //ExFor:NodeChangingArgs.OldParent + //ExSummary:Shows how to use a NodeChangingCallback to monitor changes to the document tree in real-time as we edit it. + @Test //ExSkip + public void nodeChangingCallback() throws Exception + { + Document doc = new Document(); + doc.setNodeChangingCallback(new NodeChangingPrinter()); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + builder.startTable(); + builder.insertCell(); + builder.write("Cell 1"); + builder.insertCell(); + builder.write("Cell 2"); + builder.endTable(); + + builder.insertImage(getImageDir() + "Logo.jpg"); + + builder.getCurrentParagraph().getParentNode().removeAllChildren(); + } + + /// + /// Prints every node insertion/removal as it takes place in the document. + /// + private static class NodeChangingPrinter implements INodeChangingCallback + { + public void /*INodeChangingCallback.*/nodeInserting(NodeChangingArgs args) + { + Assert.assertEquals(NodeChangingAction.INSERT, args.getAction()); + Assert.assertEquals(null, args.getOldParent()); + } + + public void /*INodeChangingCallback.*/nodeInserted(NodeChangingArgs args) + { + Assert.assertEquals(NodeChangingAction.INSERT, args.getAction()); + Assert.Is.Not.Nullargs.getNewParent()); + + System.out.println("Inserted node:"); + System.out.println("\tType:\t{args.Node.NodeType}"); + + if (!"".equals(args.getNode().getText().trim())) + { + System.out.println("\tText:\t\"{args.Node.GetText().Trim()}\""); + } + + System.out.println("\tHash:\t{args.Node.GetHashCode()}"); + System.out.println("\tParent:\t{args.NewParent.NodeType} ({args.NewParent.GetHashCode()})"); + } + + public void /*INodeChangingCallback.*/nodeRemoving(NodeChangingArgs args) + { + Assert.assertEquals(NodeChangingAction.REMOVE, args.getAction()); + } + + public void /*INodeChangingCallback.*/nodeRemoved(NodeChangingArgs args) + { + Assert.assertEquals(NodeChangingAction.REMOVE, args.getAction()); + Assert.assertNull(args.getNewParent()); + + System.out.println("Removed node: {args.Node.NodeType} ({args.Node.GetHashCode()})"); + } + } + //ExEnd + + @Test + public void nodeCollection() throws Exception + { + //ExStart + //ExFor:NodeCollection.Contains(Node) + //ExFor:NodeCollection.Insert(Int32,Node) + //ExFor:NodeCollection.Remove(Node) + //ExSummary:Shows how to work with a NodeCollection. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Add text to the document by inserting Runs using a DocumentBuilder. + builder.write("Run 1. "); + builder.write("Run 2. "); + + // Every invocation of the "Write" method creates a new Run, + // which then appears in the parent Paragraph's RunCollection. + RunCollection runs = doc.getFirstSection().getBody().getFirstParagraph().getRuns(); + + Assert.assertEquals(2, runs.getCount()); + + // We can also insert a node into the RunCollection manually. + Run newRun = new Run(doc, "Run 3. "); + runs.insert(3, newRun); + + Assert.assertTrue(runs.contains(newRun)); + Assert.assertEquals("Run 1. Run 2. Run 3.", doc.getText().trim()); + + // Access individual runs and remove them to remove their text from the document. + Run run = runs.get(1); + runs.remove(run); + + Assert.assertEquals("Run 1. Run 3.", doc.getText().trim()); + Assert.Is.Not.Nullrun); + Assert.assertFalse(runs.contains(run)); + //ExEnd + } + + @Test + public void nodeList() throws Exception + { + //ExStart + //ExFor:NodeList.Count + //ExFor:NodeList.Item(Int32) + //ExSummary:Shows how to use XPaths to navigate a NodeList. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert some nodes with a DocumentBuilder. + builder.writeln("Hello world!"); + + builder.startTable(); + builder.insertCell(); + builder.write("Cell 1"); + builder.insertCell(); + builder.write("Cell 2"); + builder.endTable(); + + builder.insertImage(getImageDir() + "Logo.jpg"); + + // Our document contains three Run nodes. + NodeList nodeList = doc.selectNodes("//Run"); + + Assert.assertEquals(3, nodeList.getCount()); + Assert.That(nodeList.Any(n => n.GetText().Trim() == "Hello world!"), assertTrue(); + Assert.That(nodeList.Any(n => n.GetText().Trim() == "Cell 1"), assertTrue(); + Assert.That(nodeList.Any(n => n.GetText().Trim() == "Cell 2"), assertTrue(); + + // Use a double forward slash to select all Run nodes + // that are indirect descendants of a Table node, which would be the runs inside the two cells we inserted. + nodeList = doc.selectNodes("//Table//Run"); + + Assert.assertEquals(2, nodeList.getCount()); + Assert.That(nodeList.Any(n => n.GetText().Trim() == "Cell 1"), assertTrue(); + Assert.That(nodeList.Any(n => n.GetText().Trim() == "Cell 2"), assertTrue(); + + // Single forward slashes specify direct descendant relationships, + // which we skipped when we used double slashes. + Assert.assertEquals(doc.selectNodes("//Table//Run"), doc.selectNodes("//Table/Row/Cell/Paragraph/Run")); + + // Access the shape that contains the image we inserted. + nodeList = doc.selectNodes("//Shape"); + + Assert.assertEquals(1, nodeList.getCount()); + + Shape shape = (Shape)nodeList.get(0); + Assert.assertTrue(shape.hasImage()); + //ExEnd + } +} + diff --git a/Examples/ApiExamples/JavaPorting/ExNodeImporter.java b/Examples/ApiExamples/JavaPorting/ExNodeImporter.java new file mode 100644 index 00000000..08f6cbaa --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExNodeImporter.java @@ -0,0 +1,226 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.ImportFormatOptions; +import com.aspose.words.NodeImporter; +import com.aspose.words.ImportFormatMode; +import com.aspose.words.Paragraph; +import com.aspose.words.Node; +import org.testng.Assert; +import com.aspose.words.SaveFormat; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.Bookmark; +import com.aspose.words.NodeType; +import com.aspose.words.CompositeNode; +import com.aspose.words.Section; +import com.aspose.words.IFieldMergingCallback; +import com.aspose.words.FieldMergingArgs; +import com.aspose.words.ImageFieldMergingArgs; +import org.testng.annotations.DataProvider; + + +@Test +public class ExNodeImporter extends ApiExampleBase +{ + @Test (dataProvider = "keepSourceNumberingDataProvider") + public void keepSourceNumbering(boolean keepSourceNumbering) throws Exception + { + //ExStart + //ExFor:ImportFormatOptions.KeepSourceNumbering + //ExFor:NodeImporter.#ctor(DocumentBase, DocumentBase, ImportFormatMode, ImportFormatOptions) + //ExSummary:Shows how to resolve list numbering clashes in source and destination documents. + // Open a document with a custom list numbering scheme, and then clone it. + // Since both have the same numbering format, the formats will clash if we import one document into the other. + Document srcDoc = new Document(getMyDir() + "Custom list numbering.docx"); + Document dstDoc = srcDoc.deepClone(); + + // When we import the document's clone into the original and then append it, + // then the two lists with the same list format will join. + // If we set the "KeepSourceNumbering" flag to "false", then the list from the document clone + // that we append to the original will carry on the numbering of the list we append it to. + // This will effectively merge the two lists into one. + // If we set the "KeepSourceNumbering" flag to "true", then the document clone + // list will preserve its original numbering, making the two lists appear as separate lists. + ImportFormatOptions importFormatOptions = new ImportFormatOptions(); + importFormatOptions.setKeepSourceNumbering(keepSourceNumbering); + + NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.KEEP_DIFFERENT_STYLES, importFormatOptions); + for (Paragraph paragraph : (Iterable) srcDoc.getFirstSection().getBody().getParagraphs()) + { + Node importedNode = importer.importNode(paragraph, true); + dstDoc.getFirstSection().getBody().appendChild(importedNode); + } + + dstDoc.updateListLabels(); + + if (keepSourceNumbering) + { + Assert.assertEquals("6. Item 1\r\n" + + "7. Item 2 \r\n" + + "8. Item 3\r\n" + + "9. Item 4\r\n" + + "6. Item 1\r\n" + + "7. Item 2 \r\n" + + "8. Item 3\r\n" + + "9. Item 4", dstDoc.getFirstSection().getBody().toString(SaveFormat.TEXT).trim()); + } + else + { + Assert.assertEquals("6. Item 1\r\n" + + "7. Item 2 \r\n" + + "8. Item 3\r\n" + + "9. Item 4\r\n" + + "10. Item 1\r\n" + + "11. Item 2 \r\n" + + "12. Item 3\r\n" + + "13. Item 4", dstDoc.getFirstSection().getBody().toString(SaveFormat.TEXT).trim()); + } + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "keepSourceNumberingDataProvider") + public static Object[][] keepSourceNumberingDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + //ExStart + //ExFor:Paragraph.IsEndOfSection + //ExFor:NodeImporter + //ExFor:NodeImporter.#ctor(DocumentBase, DocumentBase, ImportFormatMode) + //ExFor:NodeImporter.ImportNode(Node, Boolean) + //ExSummary:Shows how to insert the contents of one document to a bookmark in another document. + @Test//ExSkip + public void insertAtBookmark() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startBookmark("InsertionPoint"); + builder.write("We will insert a document here: "); + builder.endBookmark("InsertionPoint"); + + Document docToInsert = new Document(); + builder = new DocumentBuilder(docToInsert); + + builder.write("Hello world!"); + + docToInsert.save(getArtifactsDir() + "NodeImporter.InsertAtMergeField.docx"); + + Bookmark bookmark = doc.getRange().getBookmarks().get("InsertionPoint"); + insertDocument(bookmark.getBookmarkStart().getParentNode(), docToInsert); + + Assert.assertEquals("We will insert a document here: " + + "\rHello world!", doc.getText().trim()); + } + + /// + /// Inserts the contents of a document after the specified node. + /// + static void insertDocument(Node insertionDestination, Document docToInsert) + { + if (insertionDestination.getNodeType() == NodeType.PARAGRAPH || insertionDestination.getNodeType() == NodeType.TABLE) + { + CompositeNode destinationParent = insertionDestination.getParentNode(); + + NodeImporter importer = + new NodeImporter(docToInsert, insertionDestination.getDocument(), ImportFormatMode.KEEP_SOURCE_FORMATTING); + + // Loop through all block-level nodes in the section's body, + // then clone and insert every node that is not the last empty paragraph of a section. + for (Section srcSection : docToInsert.getSections().
          OfType() !!Autoporter error: Undefined expression type ) + for (Node srcNode : (Iterable) srcSection.getBody()) + { + if (srcNode.getNodeType() == NodeType.PARAGRAPH) + { + Paragraph para = (Paragraph)srcNode; + if (para.isEndOfSection() && !para.hasChildNodes()) + continue; + } + + Node newNode = importer.importNode(srcNode, true); + + destinationParent.insertAfter(newNode, insertionDestination); + insertionDestination = newNode; + } + } + else + { + throw new IllegalArgumentException("The destination node should be either a paragraph or table."); + } + } + //ExEnd + + @Test + public void insertAtMergeField() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.write("A document will appear here: "); + builder.insertField(" MERGEFIELD Document_1 "); + + Document subDoc = new Document(); + builder = new DocumentBuilder(subDoc); + builder.write("Hello world!"); + + subDoc.save(getArtifactsDir() + "NodeImporter.InsertAtMergeField.docx"); + + doc.getMailMerge().setFieldMergingCallback(new InsertDocumentAtMailMergeHandler()); + + // The main document has a merge field in it called "Document_1". + // Execute a mail merge using a data source that contains a local system filename + // of the document that we wish to insert into the MERGEFIELD. + doc.getMailMerge().execute(new String[] { "Document_1" }, + new Object[] { getArtifactsDir() + "NodeImporter.InsertAtMergeField.docx" }); + + Assert.assertEquals("A document will appear here: \r" + + "Hello world!", doc.getText().trim()); + } + + /// + /// If the mail merge encounters a MERGEFIELD with a specified name, + /// this handler treats the current value of a mail merge data source as a local system filename of a document. + /// The handler will insert the document in its entirety into the MERGEFIELD instead of the current merge value. + /// + private static class InsertDocumentAtMailMergeHandler implements IFieldMergingCallback + { + public void /*IFieldMergingCallback.*/fieldMerging(FieldMergingArgs args) throws Exception + { + if ("Document_1".equals(args.getDocumentFieldName())) + { + DocumentBuilder builder = new DocumentBuilder(args.getDocument()); + builder.moveToMergeField(args.getDocumentFieldName()); + + Document subDoc = new Document((String)args.getFieldValue()); + + insertDocument(builder.getCurrentParagraph(), subDoc); + + if (!builder.getCurrentParagraph().hasChildNodes()) + builder.getCurrentParagraph().remove(); + + args.setText(null); + } + } + + public void /*IFieldMergingCallback.*/imageFieldMerging(ImageFieldMergingArgs args) + { + // Do nothing. + } + } +} diff --git a/Examples/ApiExamples/JavaPorting/ExOdtSaveOptions.java b/Examples/ApiExamples/JavaPorting/ExOdtSaveOptions.java new file mode 100644 index 00000000..ed14462e --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExOdtSaveOptions.java @@ -0,0 +1,173 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.OdtSaveOptions; +import com.aspose.words.OdtSaveMeasureUnit; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.FieldType; +import com.aspose.words.SaveFormat; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.FileFormatUtil; +import com.aspose.words.FileFormatInfo; +import com.aspose.words.LoadOptions; +import org.testng.annotations.DataProvider; + + +@Test +class ExOdtSaveOptions !Test class should be public in Java to run, please fix .Net source! extends ApiExampleBase +{ + @Test (dataProvider = "odt11SchemaDataProvider") + public void odt11Schema(boolean exportToOdt11Specs) throws Exception + { + //ExStart + //ExFor:OdtSaveOptions + //ExFor:OdtSaveOptions.#ctor + //ExFor:OdtSaveOptions.IsStrictSchema11 + //ExFor:OdtSaveOptions.MeasureUnit + //ExFor:MeasurementUnits + //ExSummary:Shows how to make a saved document conform to an older ODT schema. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + OdtSaveOptions saveOptions = new OdtSaveOptions(); + { + saveOptions.setMeasureUnit(OdtSaveMeasureUnit.CENTIMETERS); + saveOptions.isStrictSchema11(exportToOdt11Specs); + } + + doc.save(getArtifactsDir() + "OdtSaveOptions.Odt11Schema.odt", saveOptions); + + doc = new Document(getArtifactsDir() + "OdtSaveOptions.Odt11Schema.odt"); + Assert.assertEquals(com.aspose.words.MeasurementUnits.CENTIMETERS, doc.getLayoutOptions().getRevisionOptions().getMeasurementUnit()); + //ExEnd + + if (exportToOdt11Specs) + { + Assert.assertEquals(2, doc.getRange().getFormFields().getCount()); + Assert.assertEquals(FieldType.FIELD_FORM_TEXT_INPUT, doc.getRange().getFormFields().get(0).getType()); + Assert.assertEquals(FieldType.FIELD_FORM_CHECK_BOX, doc.getRange().getFormFields().get(1).getType()); + } + else + { + Assert.assertEquals(3, doc.getRange().getFormFields().getCount()); + Assert.assertEquals(FieldType.FIELD_FORM_TEXT_INPUT, doc.getRange().getFormFields().get(0).getType()); + Assert.assertEquals(FieldType.FIELD_FORM_CHECK_BOX, doc.getRange().getFormFields().get(1).getType()); + Assert.assertEquals(FieldType.FIELD_FORM_DROP_DOWN, doc.getRange().getFormFields().get(2).getType()); + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "odt11SchemaDataProvider") + public static Object[][] odt11SchemaDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "measurementUnitsDataProvider") + public void measurementUnits(/*OdtSaveMeasureUnit*/int odtSaveMeasureUnit) throws Exception + { + //ExStart + //ExFor:OdtSaveOptions + //ExFor:OdtSaveOptions.MeasureUnit + //ExFor:OdtSaveMeasureUnit + //ExSummary:Shows how to use different measurement units to define style parameters of a saved ODT document. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // When we export the document to .odt, we can use an OdtSaveOptions object to modify how we save the document. + // We can set the "MeasureUnit" property to "OdtSaveMeasureUnit.Centimeters" + // to define content such as style parameters using the metric system, which Open Office uses. + // We can set the "MeasureUnit" property to "OdtSaveMeasureUnit.Inches" + // to define content such as style parameters using the imperial system, which Microsoft Word uses. + OdtSaveOptions saveOptions = new OdtSaveOptions(); + { + saveOptions.setMeasureUnit(odtSaveMeasureUnit); + } + + doc.save(getArtifactsDir() + "OdtSaveOptions.Odt11Schema.odt", saveOptions); + //ExEnd + + switch (odtSaveMeasureUnit) + { + case OdtSaveMeasureUnit.CENTIMETERS: + TestUtil.docPackageFileContainsString("", + getArtifactsDir() + "OdtSaveOptions.Odt11Schema.odt", "styles.xml"); + break; + case OdtSaveMeasureUnit.INCHES: + TestUtil.docPackageFileContainsString("", + getArtifactsDir() + "OdtSaveOptions.Odt11Schema.odt", "styles.xml"); + break; + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "measurementUnitsDataProvider") + public static Object[][] measurementUnitsDataProvider() throws Exception + { + return new Object[][] + { + {OdtSaveMeasureUnit.CENTIMETERS}, + {OdtSaveMeasureUnit.INCHES}, + }; + } + + @Test (dataProvider = "encryptDataProvider") + public void encrypt(/*SaveFormat*/int saveFormat) throws Exception + { + //ExStart + //ExFor:OdtSaveOptions.#ctor(SaveFormat) + //ExFor:OdtSaveOptions.Password + //ExFor:OdtSaveOptions.SaveFormat + //ExSummary:Shows how to encrypt a saved ODT/OTT document with a password, and then load it using Aspose.Words. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + // Create a new OdtSaveOptions, and pass either "SaveFormat.Odt", + // or "SaveFormat.Ott" as the format to save the document in. + OdtSaveOptions saveOptions = new OdtSaveOptions(saveFormat); + saveOptions.setPassword("@sposeEncrypted_1145"); + + String extensionString = FileFormatUtil.saveFormatToExtension(saveFormat); + + // If we open this document with an appropriate editor, + // it will prompt us for the password we specified in the SaveOptions object. + doc.save(getArtifactsDir() + "OdtSaveOptions.Encrypt" + extensionString, saveOptions); + + FileFormatInfo docInfo = FileFormatUtil.detectFileFormat(getArtifactsDir() + "OdtSaveOptions.Encrypt" + extensionString); + + Assert.assertTrue(docInfo.isEncrypted()); + + // If we wish to open or edit this document again using Aspose.Words, + // we will have to provide a LoadOptions object with the correct password to the loading constructor. + doc = new Document(getArtifactsDir() + "OdtSaveOptions.Encrypt" + extensionString, + new LoadOptions("@sposeEncrypted_1145")); + + Assert.assertEquals("Hello world!", doc.getText().trim()); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "encryptDataProvider") + public static Object[][] encryptDataProvider() throws Exception + { + return new Object[][] + { + {SaveFormat.ODT}, + {SaveFormat.OTT}, + }; + } +} diff --git a/Examples/ApiExamples/JavaPorting/ExOoxmlSaveOptions.java b/Examples/ApiExamples/JavaPorting/ExOoxmlSaveOptions.java new file mode 100644 index 00000000..b4b53a67 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExOoxmlSaveOptions.java @@ -0,0 +1,539 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.OoxmlSaveOptions; +import org.testng.Assert; +import com.aspose.words.IncorrectPasswordException; +import com.aspose.words.LoadOptions; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.MsWordVersion; +import com.aspose.words.Shape; +import com.aspose.words.NodeType; +import com.aspose.words.ShapeMarkupLanguage; +import com.aspose.words.OoxmlCompliance; +import com.aspose.words.SaveFormat; +import com.aspose.words.ListTemplate; +import com.aspose.words.List; +import com.aspose.words.BreakType; +import com.aspose.ms.System.DateTime; +import java.util.Date; +import com.aspose.words.CompressionLevel; +import com.aspose.ms.System.Diagnostics.Stopwatch; +import com.aspose.ms.System.IO.FileInfo; +import com.aspose.ms.System.msConsole; +import com.aspose.ms.System.IO.MemoryStream; +import com.aspose.ms.System.IO.FileStream; +import com.aspose.ms.System.IO.File; +import com.aspose.ms.System.IO.FileMode; +import com.aspose.words.IDocumentSavingCallback; +import com.aspose.words.DocumentSavingArgs; +import com.aspose.ms.System.Random; +import java.awt.image.BufferedImage; +import java.awt.Graphics2D; +import java.awt.Color; +import com.aspose.words.Zip64Mode; +import com.aspose.words.CertificateHolder; +import com.aspose.words.DigitalSignatureDetails; +import com.aspose.words.SignOptions; +import com.aspose.words.Run; +import org.testng.annotations.DataProvider; + + +@Test +class ExOoxmlSaveOptions !Test class should be public in Java to run, please fix .Net source! extends ApiExampleBase +{ + @Test + public void password() throws Exception + { + //ExStart + //ExFor:OoxmlSaveOptions.Password + //ExSummary:Shows how to create a password encrypted Office Open XML document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + saveOptions.setPassword("MyPassword"); + + doc.save(getArtifactsDir() + "OoxmlSaveOptions.Password.docx", saveOptions); + + // We will not be able to open this document with Microsoft Word or + // Aspose.Words without providing the correct password. + Assert.Throws(() => + doc = new Document(getArtifactsDir() + "OoxmlSaveOptions.Password.docx")); + + // Open the encrypted document by passing the correct password in a LoadOptions object. + doc = new Document(getArtifactsDir() + "OoxmlSaveOptions.Password.docx", new LoadOptions("MyPassword")); + + Assert.assertEquals("Hello world!", doc.getText().trim()); + //ExEnd + } + + @Test + public void iso29500Strict() throws Exception + { + //ExStart + //ExFor:CompatibilityOptions + //ExFor:CompatibilityOptions.OptimizeFor(MsWordVersion) + //ExFor:OoxmlSaveOptions + //ExFor:OoxmlSaveOptions.#ctor + //ExFor:OoxmlSaveOptions.SaveFormat + //ExFor:OoxmlCompliance + //ExFor:OoxmlSaveOptions.Compliance + //ExFor:ShapeMarkupLanguage + //ExSummary:Shows how to set an OOXML compliance specification for a saved document to adhere to. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // If we configure compatibility options to comply with Microsoft Word 2003, + // inserting an image will define its shape using VML. + doc.getCompatibilityOptions().optimizeFor(MsWordVersion.WORD_2003); + builder.insertImage(getImageDir() + "Transparent background logo.png"); + + Assert.assertEquals(ShapeMarkupLanguage.VML, ((Shape)doc.getChild(NodeType.SHAPE, 0, true)).getMarkupLanguage()); + + // The "ISO/IEC 29500:2008" OOXML standard does not support VML shapes. + // If we set the "Compliance" property of the SaveOptions object to "OoxmlCompliance.Iso29500_2008_Strict", + // any document we save while passing this object will have to follow that standard. + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + { + saveOptions.setCompliance(OoxmlCompliance.ISO_29500_2008_STRICT); + saveOptions.setSaveFormat(SaveFormat.DOCX); + } + + doc.save(getArtifactsDir() + "OoxmlSaveOptions.Iso29500Strict.docx", saveOptions); + + // Our saved document defines the shape using DML to adhere to the "ISO/IEC 29500:2008" OOXML standard. + doc = new Document(getArtifactsDir() + "OoxmlSaveOptions.Iso29500Strict.docx"); + + Assert.assertEquals(ShapeMarkupLanguage.DML, ((Shape)doc.getChild(NodeType.SHAPE, 0, true)).getMarkupLanguage()); + //ExEnd + } + + @Test (dataProvider = "restartingDocumentListDataProvider") + public void restartingDocumentList(boolean restartListAtEachSection) throws Exception + { + //ExStart + //ExFor:List.IsRestartAtEachSection + //ExFor:OoxmlCompliance + //ExFor:OoxmlSaveOptions.Compliance + //ExSummary:Shows how to configure a list to restart numbering at each section. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + doc.getLists().add(ListTemplate.NUMBER_DEFAULT); + + List docList = doc.getLists().get(0); + docList.isRestartAtEachSection(restartListAtEachSection); + + // The "IsRestartAtEachSection" property will only be applicable when + // the document's OOXML compliance level is to a standard that is newer than "OoxmlComplianceCore.Ecma376". + OoxmlSaveOptions options = new OoxmlSaveOptions(); + { + options.setCompliance(OoxmlCompliance.ISO_29500_2008_TRANSITIONAL); + } + + builder.getListFormat().setList(docList); + + builder.writeln("List item 1"); + builder.writeln("List item 2"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.writeln("List item 3"); + builder.writeln("List item 4"); + + doc.save(getArtifactsDir() + "OoxmlSaveOptions.RestartingDocumentList.docx", options); + + doc = new Document(getArtifactsDir() + "OoxmlSaveOptions.RestartingDocumentList.docx"); + + Assert.assertEquals(restartListAtEachSection, doc.getLists().get(0).isRestartAtEachSection()); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "restartingDocumentListDataProvider") + public static Object[][] restartingDocumentListDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "lastSavedTimeDataProvider") + public void lastSavedTime(boolean updateLastSavedTimeProperty) throws Exception + { + //ExStart + //ExFor:SaveOptions.UpdateLastSavedTimeProperty + //ExSummary:Shows how to determine whether to preserve the document's "Last saved time" property when saving. + Document doc = new Document(getMyDir() + "Document.docx"); + + Assert.assertEquals(new DateTime(2021, 5, 11, 6, 32, 0), doc.getBuiltInDocumentProperties().getLastSavedTimeInternal()); + + // When we save the document to an OOXML format, we can create an OoxmlSaveOptions object + // and then pass it to the document's saving method to modify how we save the document. + // Set the "UpdateLastSavedTimeProperty" property to "true" to + // set the output document's "Last saved time" built-in property to the current date/time. + // Set the "UpdateLastSavedTimeProperty" property to "false" to + // preserve the original value of the input document's "Last saved time" built-in property. + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + saveOptions.setUpdateLastSavedTimeProperty(updateLastSavedTimeProperty); + + doc.save(getArtifactsDir() + "OoxmlSaveOptions.LastSavedTime.docx", saveOptions); + + doc = new Document(getArtifactsDir() + "OoxmlSaveOptions.LastSavedTime.docx"); + DateTime lastSavedTimeNew = doc.getBuiltInDocumentProperties().getLastSavedTimeInternal(); + + if (updateLastSavedTimeProperty) + Assert.assertTrue((DateTime.subtract(new Date, lastSavedTimeNew)).getDays() < 1); + else + Assert.assertEquals(new DateTime(2021, 5, 11, 6, 32, 0), lastSavedTimeNew); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "lastSavedTimeDataProvider") + public static Object[][] lastSavedTimeDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "keepLegacyControlCharsDataProvider") + public void keepLegacyControlChars(boolean keepLegacyControlChars) throws Exception + { + //ExStart + //ExFor:OoxmlSaveOptions.KeepLegacyControlChars + //ExFor:OoxmlSaveOptions.#ctor(SaveFormat) + //ExSummary:Shows how to support legacy control characters when converting to .docx. + Document doc = new Document(getMyDir() + "Legacy control character.doc"); + + // When we save the document to an OOXML format, we can create an OoxmlSaveOptions object + // and then pass it to the document's saving method to modify how we save the document. + // Set the "KeepLegacyControlChars" property to "true" to preserve + // the "ShortDateTime" legacy character while saving. + // Set the "KeepLegacyControlChars" property to "false" to remove + // the "ShortDateTime" legacy character from the output document. + OoxmlSaveOptions so = new OoxmlSaveOptions(SaveFormat.DOCX); + so.setKeepLegacyControlChars(keepLegacyControlChars); + + doc.save(getArtifactsDir() + "OoxmlSaveOptions.KeepLegacyControlChars.docx", so); + + doc = new Document(getArtifactsDir() + "OoxmlSaveOptions.KeepLegacyControlChars.docx"); + + Assert.assertEquals(keepLegacyControlChars ? "\u0013date \\@ \"MM/dd/yyyy\"\u0014\u0015\f" : "\u001e\f", doc.getFirstSection().getBody().getText()); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "keepLegacyControlCharsDataProvider") + public static Object[][] keepLegacyControlCharsDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "documentCompressionDataProvider") + public void documentCompression(/*CompressionLevel*/int compressionLevel) throws Exception + { + //ExStart + //ExFor:OoxmlSaveOptions.CompressionLevel + //ExFor:CompressionLevel + //ExSummary:Shows how to specify the compression level to use while saving an OOXML document. + Document doc = new Document(getMyDir() + "Big document.docx"); + + // When we save the document to an OOXML format, we can create an OoxmlSaveOptions object + // and then pass it to the document's saving method to modify how we save the document. + // Set the "CompressionLevel" property to "CompressionLevel.Maximum" to apply the strongest and slowest compression. + // Set the "CompressionLevel" property to "CompressionLevel.Normal" to apply + // the default compression that Aspose.Words uses while saving OOXML documents. + // Set the "CompressionLevel" property to "CompressionLevel.Fast" to apply a faster and weaker compression. + // Set the "CompressionLevel" property to "CompressionLevel.SuperFast" to apply + // the default compression that Microsoft Word uses. + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(SaveFormat.DOCX); + saveOptions.setCompressionLevel(compressionLevel); + + Stopwatch st = Stopwatch.startNew(); + doc.save(getArtifactsDir() + "OoxmlSaveOptions.DocumentCompression.docx", saveOptions); + st.stop(); + + FileInfo fileInfo = new FileInfo(getArtifactsDir() + "OoxmlSaveOptions.DocumentCompression.docx"); + + System.out.println("Saving operation done using the \"{compressionLevel}\" compression level:"); + System.out.println("\tDuration:\t{st.ElapsedMilliseconds} ms"); + System.out.println("\tFile Size:\t{fileInfo.Length} bytes"); + //ExEnd + + long testedFileLength = fileInfo.getLength(); + + switch (compressionLevel) + { + case CompressionLevel.MAXIMUM: + Assert.assertTrue(testedFileLength < 1269000); + break; + case CompressionLevel.NORMAL: + Assert.assertTrue(testedFileLength < 1271000); + break; + case CompressionLevel.FAST: + Assert.assertTrue(testedFileLength < 1280000); + break; + case CompressionLevel.SUPER_FAST: + Assert.assertTrue(testedFileLength < 1276000); + break; + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "documentCompressionDataProvider") + public static Object[][] documentCompressionDataProvider() throws Exception + { + return new Object[][] + { + {CompressionLevel.MAXIMUM}, + {CompressionLevel.FAST}, + {CompressionLevel.NORMAL}, + {CompressionLevel.SUPER_FAST}, + }; + } + + @Test + public void checkFileSignatures() throws Exception + { + /*CompressionLevel*/int[] compressionLevels = { + CompressionLevel.MAXIMUM, + CompressionLevel.NORMAL, + CompressionLevel.FAST, + CompressionLevel.SUPER_FAST + }; + + String[] fileSignatures = new String[] + { + "50 4B 03 04 14 00 08 08 08 00 ", + "50 4B 03 04 14 00 08 08 08 00 ", + "50 4B 03 04 14 00 08 08 08 00 ", + "50 4B 03 04 14 00 08 08 08 00 " + }; + + Document doc = new Document(); + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(SaveFormat.DOCX); + + long prevFileSize = 0; + for (int i = 0; i < fileSignatures.length; i++) + { + saveOptions.setCompressionLevel(compressionLevels[i]); + doc.save(getArtifactsDir() + "OoxmlSaveOptions.CheckFileSignatures.docx", saveOptions); + + MemoryStream stream = new MemoryStream(); + try /*JAVA: was using*/ + { + FileStream outputFileStream = File.open(getArtifactsDir() + "OoxmlSaveOptions.CheckFileSignatures.docx", FileMode.OPEN); + try /*JAVA: was using*/ + { + long fileSize = outputFileStream.getLength(); + Assert.assertTrue(prevFileSize < fileSize); + + TestUtil.copyStream(outputFileStream, stream); + Assert.assertEquals(fileSignatures[i], TestUtil.dumpArray(stream.toArray(), 0, 10)); + + prevFileSize = fileSize; + } + finally { if (outputFileStream != null) outputFileStream.close(); } + } + finally { if (stream != null) stream.close(); } + } + } + + @Test + public void exportGeneratorName() throws Exception + { + //ExStart + //ExFor:SaveOptions.ExportGeneratorName + //ExSummary:Shows how to disable adding name and version of Aspose.Words into produced files. + Document doc = new Document(); + + // Use https://docs.aspose.com/words/net/generator-or-producer-name-included-in-output-documents/ to know how to check the result. + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setExportGeneratorName(false); } + + doc.save(getArtifactsDir() + "OoxmlSaveOptions.ExportGeneratorName.docx", saveOptions); + //ExEnd + } + + @Test (dataProvider = "progressCallbackDataProvider") + //ExStart + //ExFor:SaveOptions.ProgressCallback + //ExFor:IDocumentSavingCallback + //ExFor:IDocumentSavingCallback.Notify(DocumentSavingArgs) + //ExFor:DocumentSavingArgs.EstimatedProgress + //ExSummary:Shows how to manage a document while saving to docx. + public void progressCallback(/*SaveFormat*/int saveFormat, String ext) throws Exception + { + Document doc = new Document(getMyDir() + "Big document.docx"); + + // Following formats are supported: Docx, FlatOpc, Docm, Dotm, Dotx. + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(saveFormat); + { + saveOptions.setProgressCallback(new SavingProgressCallback()); + } + + IllegalStateException exception = Assert.Throws(() => + doc.save(getArtifactsDir() + $"OoxmlSaveOptions.ProgressCallback.{ext}", saveOptions)); + Assert.That(exception?.Message.Contains("EstimatedProgress"), assertTrue(); + } + + //JAVA-added data provider for test method + @DataProvider(name = "progressCallbackDataProvider") + public static Object[][] progressCallbackDataProvider() throws Exception + { + return new Object[][] + { + {SaveFormat.DOCX, "docx"}, + {SaveFormat.DOCM, "docm"}, + {SaveFormat.DOTM, "dotm"}, + {SaveFormat.DOTX, "dotx"}, + {SaveFormat.FLAT_OPC, "flatopc"}, + }; + } + + /// + /// Saving progress callback. Cancel a document saving after the "MaxDuration" seconds. + /// + public static class SavingProgressCallback implements IDocumentSavingCallback + { + /// + /// Ctr. + /// + public SavingProgressCallback() + { + mSavingStartedAt = new Date; + } + + /// + /// Callback method which called during document saving. + /// + /// Saving arguments. + public void notify(DocumentSavingArgs args) + { + DateTime canceledAt = new Date; + double ellapsedSeconds = (DateTime.subtract(canceledAt, mSavingStartedAt)).getTotalSeconds(); + if (ellapsedSeconds > MAX_DURATION) + throw new IllegalStateException($"EstimatedProgress = {args.EstimatedProgress}; CanceledAt = {canceledAt}"); + } + + /// + /// Date and time when document saving is started. + /// + private /*final*/ DateTime mSavingStartedAt; + + /// + /// Maximum allowed duration in sec. + /// + private static final double MAX_DURATION = 0.01d; + } + //ExEnd + + @Test + public void zip64ModeOption() throws Exception + { + //ExStart:Zip64ModeOption + //GistId:e386727403c2341ce4018bca370a5b41 + //ExFor:OoxmlSaveOptions.Zip64Mode + //ExFor:Zip64Mode + //ExSummary:Shows how to use ZIP64 format extensions. + Random random = new Random(); + DocumentBuilder builder = new DocumentBuilder(); + + for (int i = 0; i < 10000; i++) + { + BufferedImage bmp = new BufferedImage(5, 5); + try /*JAVA: was using*/ + { + Graphics2D g = Graphics2D.FromImage(bmp); + try /*JAVA: was using*/ + { + g.Clear(new Color((random.next(0, 254)), (random.next(0, 254)), (random.next(0, 254)))); + MemoryStream ms = new MemoryStream(); + try /*JAVA: was using*/ + { + bmp.Save(ms, ImageFormat.Png); + builder.insertImage(ms.toArray()); + } + finally { if (ms != null) ms.close(); } + } + finally { if (g != null) g.close(); } + } + finally { if (bmp != null) bmp.close(); } + } + + builder.getDocument().save(getArtifactsDir() + "OoxmlSaveOptions.Zip64ModeOption.docx", + new OoxmlSaveOptions(); { .setZip64Mode(Zip64Mode.ALWAYS); }); + //ExEnd:Zip64ModeOption + } + + @Test + public void digitalSignature() throws Exception + { + //ExStart:DigitalSignature + //GistId:5f20ac02cb42c6b08481aa1c5b0cd3db + //ExFor:OoxmlSaveOptions.DigitalSignatureDetails + //ExFor:DigitalSignatureDetails + //ExFor:DigitalSignatureDetails.#ctor(CertificateHolder, SignOptions) + //ExFor:DigitalSignatureDetails.CertificateHolder + //ExFor:DigitalSignatureDetails.SignOptions + //ExSummary:Shows how to sign OOXML document. + Document doc = new Document(getMyDir() + "Document.docx"); + + CertificateHolder certificateHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + DigitalSignatureDetails digitalSignatureDetails = new DigitalSignatureDetails( + certificateHolder, + new SignOptions(); { digitalSignatureDetails.setComments("Some comments"); digitalSignatureDetails.setSignTime(new Date); }); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + saveOptions.setDigitalSignatureDetails(digitalSignatureDetails); + + Assert.assertEquals(certificateHolder, digitalSignatureDetails.getCertificateHolder()); + Assert.assertEquals("Some comments", digitalSignatureDetails.getSignOptions().getComments()); + + doc.save(getArtifactsDir() + "OoxmlSaveOptions.DigitalSignature.docx", saveOptions); + //ExEnd:DigitalSignature + } + + @Test + public void updateAmbiguousTextFont() throws Exception + { + //ExStart:UpdateAmbiguousTextFont + //GistId:1a265b92fa0019b26277ecfef3c20330 + //ExFor:SaveOptions.UpdateAmbiguousTextFont + //ExSummary:Shows how to update the font to match the character code being used. + Document doc = new Document(getMyDir() + "Special symbol.docx"); + Run run = doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0); + System.out.println(run.getText()); // ฿ + System.out.println(run.getFont().getName()); // Arial + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + saveOptions.setUpdateAmbiguousTextFont(true); + doc.save(getArtifactsDir() + "OoxmlSaveOptions.UpdateAmbiguousTextFont.docx", saveOptions); + + doc = new Document(getArtifactsDir() + "OoxmlSaveOptions.UpdateAmbiguousTextFont.docx"); + run = doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0); + System.out.println(run.getText()); // ฿ + System.out.println(run.getFont().getName()); // Angsana New + //ExEnd:UpdateAmbiguousTextFont + } +} diff --git a/Examples/ApiExamples/JavaPorting/ExPageSetup.java b/Examples/ApiExamples/JavaPorting/ExPageSetup.java new file mode 100644 index 00000000..6965da61 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExPageSetup.java @@ -0,0 +1,1232 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.Orientation; +import com.aspose.words.PageVerticalAlignment; +import com.aspose.words.BreakType; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.HeaderFooterType; +import com.aspose.words.SectionLayoutMode; +import com.aspose.words.Paragraph; +import com.aspose.words.SectionStart; +import com.aspose.words.TextColumnCollection; +import com.aspose.ms.System.Drawing.Printing.PrinterSettings; +import com.aspose.words.Section; +import com.aspose.words.PaperSize; +import com.aspose.words.ConvertUtil; +import com.aspose.words.PageSetup; +import com.aspose.words.TextColumn; +import com.aspose.words.LineNumberRestartMode; +import com.aspose.words.PageBorderDistanceFrom; +import com.aspose.words.PageBorderAppliesTo; +import com.aspose.words.Border; +import com.aspose.words.BorderType; +import com.aspose.words.LineStyle; +import java.awt.Color; +import com.aspose.ms.System.Drawing.msColor; +import com.aspose.words.NumberStyle; +import com.aspose.words.ParagraphAlignment; +import com.aspose.words.FootnoteType; +import com.aspose.words.FootnoteOptions; +import com.aspose.words.FootnotePosition; +import com.aspose.words.FootnoteNumberingRule; +import com.aspose.words.EndnoteOptions; +import com.aspose.words.EndnotePosition; +import com.aspose.words.MultiplePagesType; +import com.aspose.words.TextOrientation; +import com.aspose.words.Body; +import com.aspose.words.AsposeWordsPrintDocument; +import com.aspose.ms.System.msConsole; +import org.testng.annotations.DataProvider; + + +@Test +public class ExPageSetup extends ApiExampleBase +{ + @Test + public void clearFormatting() throws Exception + { + //ExStart + //ExFor:DocumentBuilder.PageSetup + //ExFor:DocumentBuilder.InsertBreak + //ExFor:DocumentBuilder.Document + //ExFor:PageSetup + //ExFor:PageSetup.Orientation + //ExFor:PageSetup.VerticalAlignment + //ExFor:PageSetup.ClearFormatting + //ExFor:Orientation + //ExFor:PageVerticalAlignment + //ExFor:BreakType + //ExSummary:Shows how to apply and revert page setup settings to sections in a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Modify the page setup properties for the builder's current section and add text. + builder.getPageSetup().setOrientation(Orientation.LANDSCAPE); + builder.getPageSetup().setVerticalAlignment(PageVerticalAlignment.CENTER); + builder.writeln("This is the first section, which landscape oriented with vertically centered text."); + + // If we start a new section using a document builder, + // it will inherit the builder's current page setup properties. + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + + Assert.assertEquals(Orientation.LANDSCAPE, doc.getSections().get(1).getPageSetup().getOrientation()); + Assert.assertEquals(PageVerticalAlignment.CENTER, doc.getSections().get(1).getPageSetup().getVerticalAlignment()); + + // We can revert its page setup properties to their default values using the "ClearFormatting" method. + builder.getPageSetup().clearFormatting(); + + Assert.assertEquals(Orientation.PORTRAIT, doc.getSections().get(1).getPageSetup().getOrientation()); + Assert.assertEquals(PageVerticalAlignment.TOP, doc.getSections().get(1).getPageSetup().getVerticalAlignment()); + + builder.writeln("This is the second section, which is in default Letter paper size, portrait orientation and top alignment."); + + doc.save(getArtifactsDir() + "PageSetup.ClearFormatting.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.ClearFormatting.docx"); + + Assert.assertEquals(Orientation.LANDSCAPE, doc.getSections().get(0).getPageSetup().getOrientation()); + Assert.assertEquals(PageVerticalAlignment.CENTER, doc.getSections().get(0).getPageSetup().getVerticalAlignment()); + + Assert.assertEquals(Orientation.PORTRAIT, doc.getSections().get(1).getPageSetup().getOrientation()); + Assert.assertEquals(PageVerticalAlignment.TOP, doc.getSections().get(1).getPageSetup().getVerticalAlignment()); + } + + @Test (dataProvider = "differentFirstPageHeaderFooterDataProvider") + public void differentFirstPageHeaderFooter(boolean differentFirstPageHeaderFooter) throws Exception + { + //ExStart + //ExFor:PageSetup.DifferentFirstPageHeaderFooter + //ExSummary:Shows how to enable or disable primary headers/footers. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are two types of header/footers. + // 1 - The "First" header/footer, which appears on the first page of the section. + builder.moveToHeaderFooter(HeaderFooterType.HEADER_FIRST); + builder.writeln("First page header."); + + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_FIRST); + builder.writeln("First page footer."); + + // 2 - The "Primary" header/footer, which appears on every page in the section. + // We can override the primary header/footer by a first and an even page header/footer. + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.writeln("Primary header."); + + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + builder.writeln("Primary footer."); + + builder.moveToSection(0); + builder.writeln("Page 1."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 2."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 3."); + + // Each section has a "PageSetup" object that specifies page appearance-related properties + // such as orientation, size, and borders. + // Set the "DifferentFirstPageHeaderFooter" property to "true" to apply the first header/footer to the first page. + // Set the "DifferentFirstPageHeaderFooter" property to "false" + // to make the first page display the primary header/footer. + builder.getPageSetup().setDifferentFirstPageHeaderFooter(differentFirstPageHeaderFooter); + + doc.save(getArtifactsDir() + "PageSetup.DifferentFirstPageHeaderFooter.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.DifferentFirstPageHeaderFooter.docx"); + + Assert.assertEquals(differentFirstPageHeaderFooter, doc.getFirstSection().getPageSetup().getDifferentFirstPageHeaderFooter()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "differentFirstPageHeaderFooterDataProvider") + public static Object[][] differentFirstPageHeaderFooterDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "oddAndEvenPagesHeaderFooterDataProvider") + public void oddAndEvenPagesHeaderFooter(boolean oddAndEvenPagesHeaderFooter) throws Exception + { + //ExStart + //ExFor:PageSetup.OddAndEvenPagesHeaderFooter + //ExSummary:Shows how to enable or disable even page headers/footers. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are two types of header/footers. + // 1 - The "Primary" header/footer, which appears on every page in the section. + // We can override the primary header/footer by a first and an even page header/footer. + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.writeln("Primary header."); + + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + builder.writeln("Primary footer."); + + // 2 - The "Even" header/footer, which appears on every even page of this section. + builder.moveToHeaderFooter(HeaderFooterType.HEADER_EVEN); + builder.writeln("Even page header."); + + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_EVEN); + builder.writeln("Even page footer."); + + builder.moveToSection(0); + builder.writeln("Page 1."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 2."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 3."); + + // Each section has a "PageSetup" object that specifies page appearance-related properties + // such as orientation, size, and borders. + // Set the "OddAndEvenPagesHeaderFooter" property to "true" + // to display the even page header/footer on even pages. + // Set the "OddAndEvenPagesHeaderFooter" property to "false" + // to display the primary header/footer on even pages. + builder.getPageSetup().setOddAndEvenPagesHeaderFooter(oddAndEvenPagesHeaderFooter); + + doc.save(getArtifactsDir() + "PageSetup.OddAndEvenPagesHeaderFooter.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.OddAndEvenPagesHeaderFooter.docx"); + + Assert.assertEquals(oddAndEvenPagesHeaderFooter, doc.getFirstSection().getPageSetup().getOddAndEvenPagesHeaderFooter()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "oddAndEvenPagesHeaderFooterDataProvider") + public static Object[][] oddAndEvenPagesHeaderFooterDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void charactersPerLine() throws Exception + { + //ExStart + //ExFor:PageSetup.CharactersPerLine + //ExFor:PageSetup.LayoutMode + //ExFor:SectionLayoutMode + //ExSummary:Shows how to specify a for the number of characters that each line may have. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Enable pitching, and then use it to set the number of characters per line in this section. + builder.getPageSetup().setLayoutMode(SectionLayoutMode.GRID); + builder.getPageSetup().setCharactersPerLine(10); + + // The number of characters also depends on the size of the font. + doc.getStyles().get("Normal").getFont().setSize(20.0); + + Assert.assertEquals(8, doc.getFirstSection().getPageSetup().getCharactersPerLine()); + + builder.writeln("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + + doc.save(getArtifactsDir() + "PageSetup.CharactersPerLine.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.CharactersPerLine.docx"); + + Assert.assertEquals(SectionLayoutMode.GRID, doc.getFirstSection().getPageSetup().getLayoutMode()); + Assert.assertEquals(8, doc.getFirstSection().getPageSetup().getCharactersPerLine()); + } + + @Test + public void linesPerPage() throws Exception + { + //ExStart + //ExFor:PageSetup.LinesPerPage + //ExFor:PageSetup.LayoutMode + //ExFor:ParagraphFormat.SnapToGrid + //ExFor:SectionLayoutMode + //ExSummary:Shows how to specify a limit for the number of lines that each page may have. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Enable pitching, and then use it to set the number of lines per page in this section. + // A large enough font size will push some lines down onto the next page to avoid overlapping characters. + builder.getPageSetup().setLayoutMode(SectionLayoutMode.LINE_GRID); + builder.getPageSetup().setLinesPerPage(15); + + builder.getParagraphFormat().setSnapToGrid(true); + + for (int i = 0; i < 30; i++) + builder.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "); + + doc.save(getArtifactsDir() + "PageSetup.LinesPerPage.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.LinesPerPage.docx"); + + Assert.assertEquals(SectionLayoutMode.LINE_GRID, doc.getFirstSection().getPageSetup().getLayoutMode()); + Assert.assertEquals(15, doc.getFirstSection().getPageSetup().getLinesPerPage()); + + for (Paragraph paragraph : (Iterable) doc.getFirstSection().getBody().getParagraphs()) + Assert.assertTrue(paragraph.getParagraphFormat().getSnapToGrid()); + } + + @Test + public void setSectionStart() throws Exception + { + //ExStart + //ExFor:SectionStart + //ExFor:PageSetup.SectionStart + //ExFor:Document.Sections + //ExSummary:Shows how to specify how a new section separates itself from the previous. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("This text is in section 1."); + + // Section break types determine how a new section separates itself from the previous section. + // Below are five types of section breaks. + // 1 - Starts the next section on a new page: + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.writeln("This text is in section 2."); + + Assert.assertEquals(SectionStart.NEW_PAGE, doc.getSections().get(1).getPageSetup().getSectionStart()); + + // 2 - Starts the next section on the current page: + builder.insertBreak(BreakType.SECTION_BREAK_CONTINUOUS); + builder.writeln("This text is in section 3."); + + Assert.assertEquals(SectionStart.CONTINUOUS, doc.getSections().get(2).getPageSetup().getSectionStart()); + + // 3 - Starts the next section on a new even page: + builder.insertBreak(BreakType.SECTION_BREAK_EVEN_PAGE); + builder.writeln("This text is in section 4."); + + Assert.assertEquals(SectionStart.EVEN_PAGE, doc.getSections().get(3).getPageSetup().getSectionStart()); + + // 4 - Starts the next section on a new odd page: + builder.insertBreak(BreakType.SECTION_BREAK_ODD_PAGE); + builder.writeln("This text is in section 5."); + + Assert.assertEquals(SectionStart.ODD_PAGE, doc.getSections().get(4).getPageSetup().getSectionStart()); + + // 5 - Starts the next section on a new column: + TextColumnCollection columns = builder.getPageSetup().getTextColumns(); + columns.setCount(2); + + builder.insertBreak(BreakType.SECTION_BREAK_NEW_COLUMN); + builder.writeln("This text is in section 6."); + + Assert.assertEquals(SectionStart.NEW_COLUMN, doc.getSections().get(5).getPageSetup().getSectionStart()); + + doc.save(getArtifactsDir() + "PageSetup.SetSectionStart.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.SetSectionStart.docx"); + + Assert.assertEquals(SectionStart.NEW_PAGE, doc.getSections().get(0).getPageSetup().getSectionStart()); + Assert.assertEquals(SectionStart.NEW_PAGE, doc.getSections().get(1).getPageSetup().getSectionStart()); + Assert.assertEquals(SectionStart.CONTINUOUS, doc.getSections().get(2).getPageSetup().getSectionStart()); + Assert.assertEquals(SectionStart.EVEN_PAGE, doc.getSections().get(3).getPageSetup().getSectionStart()); + Assert.assertEquals(SectionStart.ODD_PAGE, doc.getSections().get(4).getPageSetup().getSectionStart()); + Assert.assertEquals(SectionStart.NEW_COLUMN, doc.getSections().get(5).getPageSetup().getSectionStart()); + } + + @Test (enabled = false, description = "Run only when the printer driver is installed") + public void defaultPaperTray() throws Exception + { + //ExStart + //ExFor:PageSetup.FirstPageTray + //ExFor:PageSetup.OtherPagesTray + //ExSummary:Shows how to get all the sections in a document to use the default paper tray of the selected printer. + Document doc = new Document(); + + // Find the default printer that we will use for printing this document. + // You can define a specific printer using the "PrinterName" property of the PrinterSettings object. + PrinterSettings settings = new PrinterSettings(); + + // The paper tray value stored in documents is printer specific. + // This means the code below resets all page tray values to use the current printers default tray. + // You can enumerate PrinterSettings.PaperSources to find the other valid paper tray values of the selected printer. + for (Section section : doc.getSections().
          OfType() !!Autoporter error: Undefined expression type ) + { + section.getPageSetup().setFirstPageTray(settings.getDefaultPageSettings().PaperSource.RawKind); + section.getPageSetup().setOtherPagesTray(settings.getDefaultPageSettings().PaperSource.RawKind); + } + //ExEnd + + for (Section section : DocumentHelper.saveOpen(doc).getSections().
          OfType() !!Autoporter error: Undefined expression type ) + { + Assert.assertEquals(settings.getDefaultPageSettings().PaperSource.RawKind, section.getPageSetup().getFirstPageTray()); + Assert.assertEquals(settings.getDefaultPageSettings().PaperSource.RawKind, section.getPageSetup().getOtherPagesTray()); + } + } + + @Test (enabled = false, description = "Run only when the printer driver is installed") + public void paperTrayForDifferentPaperType() throws Exception + { + //ExStart + //ExFor:PageSetup.FirstPageTray + //ExFor:PageSetup.OtherPagesTray + //ExSummary:Shows how to set up printing using different printer trays for different paper sizes. + Document doc = new Document(); + + // Find the default printer that we will use for printing this document. + // You can define a specific printer using the "PrinterName" property of the PrinterSettings object. + PrinterSettings settings = new PrinterSettings(); + + // This is the tray we will use for pages in the "A4" paper size. + int printerTrayForA4 = settings.getPaperSources().get(0).RawKind; + + // This is the tray we will use for pages in the "Letter" paper size. + int printerTrayForLetter = settings.getPaperSources().get(1).RawKind; + + // Modify the PageSettings object of this section to get Microsoft Word to instruct the printer + // to use one of the trays we identified above, depending on this section's paper size. + for (Section section : doc.getSections().
          OfType() !!Autoporter error: Undefined expression type ) + { + if (section.getPageSetup().getPaperSize() == com.aspose.words.PaperSize.LETTER) + { + section.getPageSetup().setFirstPageTray(printerTrayForLetter); + section.getPageSetup().setOtherPagesTray(printerTrayForLetter); + } + else if (section.getPageSetup().getPaperSize() == com.aspose.words.PaperSize.A4) + { + section.getPageSetup().setFirstPageTray(printerTrayForA4); + section.getPageSetup().setOtherPagesTray(printerTrayForA4); + } + } + //ExEnd + + for (Section section : DocumentHelper.saveOpen(doc).getSections().
          OfType() !!Autoporter error: Undefined expression type ) + { + if (section.getPageSetup().getPaperSize() == com.aspose.words.PaperSize.LETTER) + { + Assert.assertEquals(printerTrayForLetter, section.getPageSetup().getFirstPageTray()); + Assert.assertEquals(printerTrayForLetter, section.getPageSetup().getOtherPagesTray()); + } + else if (section.getPageSetup().getPaperSize() == com.aspose.words.PaperSize.A4) + { + Assert.assertEquals(printerTrayForA4, section.getPageSetup().getFirstPageTray()); + Assert.assertEquals(printerTrayForA4, section.getPageSetup().getOtherPagesTray()); + } + } + } + + @Test + public void pageMargins() throws Exception + { + //ExStart + //ExFor:ConvertUtil + //ExFor:ConvertUtil.InchToPoint + //ExFor:PaperSize + //ExFor:PageSetup.PaperSize + //ExFor:PageSetup.Orientation + //ExFor:PageSetup.TopMargin + //ExFor:PageSetup.BottomMargin + //ExFor:PageSetup.LeftMargin + //ExFor:PageSetup.RightMargin + //ExFor:PageSetup.HeaderDistance + //ExFor:PageSetup.FooterDistance + //ExSummary:Shows how to adjust paper size, orientation, margins, along with other settings for a section. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getPageSetup().setPaperSize(PaperSize.LEGAL); + builder.getPageSetup().setOrientation(Orientation.LANDSCAPE); + builder.getPageSetup().setTopMargin(ConvertUtil.inchToPoint(1.0)); + builder.getPageSetup().setBottomMargin(ConvertUtil.inchToPoint(1.0)); + builder.getPageSetup().setLeftMargin(ConvertUtil.inchToPoint(1.5)); + builder.getPageSetup().setRightMargin(ConvertUtil.inchToPoint(1.5)); + builder.getPageSetup().setHeaderDistance(ConvertUtil.inchToPoint(0.2)); + builder.getPageSetup().setFooterDistance(ConvertUtil.inchToPoint(0.2)); + + builder.writeln("Hello world!"); + + doc.save(getArtifactsDir() + "PageSetup.PageMargins.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.PageMargins.docx"); + + Assert.assertEquals(PaperSize.LEGAL, doc.getFirstSection().getPageSetup().getPaperSize()); + Assert.assertEquals(1008.0d, doc.getFirstSection().getPageSetup().getPageWidth()); + Assert.assertEquals(612.0d, doc.getFirstSection().getPageSetup().getPageHeight()); + Assert.assertEquals(Orientation.LANDSCAPE, doc.getFirstSection().getPageSetup().getOrientation()); + Assert.assertEquals(72.0d, doc.getFirstSection().getPageSetup().getTopMargin()); + Assert.assertEquals(72.0d, doc.getFirstSection().getPageSetup().getBottomMargin()); + Assert.assertEquals(108.0d, doc.getFirstSection().getPageSetup().getLeftMargin()); + Assert.assertEquals(108.0d, doc.getFirstSection().getPageSetup().getRightMargin()); + Assert.assertEquals(14.4d, doc.getFirstSection().getPageSetup().getHeaderDistance()); + Assert.assertEquals(14.4d, doc.getFirstSection().getPageSetup().getFooterDistance()); + } + + @Test + public void paperSizes() throws Exception + { + //ExStart + //ExFor:PaperSize + //ExFor:PageSetup.PaperSize + //ExSummary:Shows how to set page sizes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // We can change the current page's size to a pre-defined size + // by using the "PaperSize" property of this section's PageSetup object. + builder.getPageSetup().setPaperSize(PaperSize.TABLOID); + + Assert.assertEquals(792.0d, builder.getPageSetup().getPageWidth()); + Assert.assertEquals(1224.0d, builder.getPageSetup().getPageHeight()); + + builder.writeln($"This page is {builder.PageSetup.PageWidth}x{builder.PageSetup.PageHeight}."); + + // Each section has its own PageSetup object. When we use a document builder to make a new section, + // that section's PageSetup object inherits all the previous section's PageSetup object's values. + builder.insertBreak(BreakType.SECTION_BREAK_EVEN_PAGE); + + Assert.assertEquals(PaperSize.TABLOID, builder.getPageSetup().getPaperSize()); + + builder.getPageSetup().setPaperSize(PaperSize.A5); + builder.writeln($"This page is {builder.PageSetup.PageWidth}x{builder.PageSetup.PageHeight}."); + + Assert.assertEquals(419.55d, builder.getPageSetup().getPageWidth()); + Assert.assertEquals(595.30d, builder.getPageSetup().getPageHeight()); + + builder.insertBreak(BreakType.SECTION_BREAK_EVEN_PAGE); + + // Set a custom size for this section's pages. + builder.getPageSetup().setPageWidth(620.0); + builder.getPageSetup().setPageHeight(480.0); + + Assert.assertEquals(PaperSize.CUSTOM, builder.getPageSetup().getPaperSize()); + + builder.writeln($"This page is {builder.PageSetup.PageWidth}x{builder.PageSetup.PageHeight}."); + + doc.save(getArtifactsDir() + "PageSetup.PaperSizes.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.PaperSizes.docx"); + + Assert.assertEquals(PaperSize.TABLOID, doc.getSections().get(0).getPageSetup().getPaperSize()); + Assert.assertEquals(792.0d, doc.getSections().get(0).getPageSetup().getPageWidth()); + Assert.assertEquals(1224.0d, doc.getSections().get(0).getPageSetup().getPageHeight()); + Assert.assertEquals(PaperSize.A5, doc.getSections().get(1).getPageSetup().getPaperSize()); + Assert.assertEquals(419.55d, doc.getSections().get(1).getPageSetup().getPageWidth()); + Assert.assertEquals(595.30d, doc.getSections().get(1).getPageSetup().getPageHeight()); + Assert.assertEquals(PaperSize.CUSTOM, doc.getSections().get(2).getPageSetup().getPaperSize()); + Assert.assertEquals(620.0d, doc.getSections().get(2).getPageSetup().getPageWidth()); + Assert.assertEquals(480.0d, doc.getSections().get(2).getPageSetup().getPageHeight()); + } + + @Test + public void columnsSameWidth() throws Exception + { + //ExStart + //ExFor:PageSetup.TextColumns + //ExFor:TextColumnCollection + //ExFor:TextColumnCollection.Spacing + //ExFor:TextColumnCollection.SetCount + //ExFor:TextColumnCollection.Count + //ExFor:TextColumnCollection.Width + //ExSummary:Shows how to create multiple evenly spaced columns in a section. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + TextColumnCollection columns = builder.getPageSetup().getTextColumns(); + columns.setSpacing(100.0); + columns.setCount(2); + + builder.writeln("Column 1."); + builder.insertBreak(BreakType.COLUMN_BREAK); + builder.writeln("Column 2."); + + doc.save(getArtifactsDir() + "PageSetup.ColumnsSameWidth.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.ColumnsSameWidth.docx"); + + Assert.assertEquals(100.0d, doc.getFirstSection().getPageSetup().getTextColumns().getSpacing()); + Assert.assertEquals(2, doc.getFirstSection().getPageSetup().getTextColumns().getCount()); + Assert.assertEquals(185.15, 0.01, doc.getFirstSection().getPageSetup().getTextColumns().getWidth()); + } + + @Test + public void customColumnWidth() throws Exception + { + //ExStart + //ExFor:TextColumnCollection.EvenlySpaced + //ExFor:TextColumnCollection.Item + //ExFor:TextColumn + //ExFor:TextColumn.Width + //ExFor:TextColumn.SpaceAfter + //ExSummary:Shows how to create unevenly spaced columns. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + PageSetup pageSetup = builder.getPageSetup(); + + TextColumnCollection columns = pageSetup.getTextColumns(); + columns.setEvenlySpaced(false); + columns.setCount(2); + + // Determine the amount of room that we have available for arranging columns. + double contentWidth = pageSetup.getPageWidth() - pageSetup.getLeftMargin() - pageSetup.getRightMargin(); + + Assert.assertEquals(470.30d, 0.01d, contentWidth); + + // Set the first column to be narrow. + TextColumn column = columns.get(0); + column.setWidth(100.0); + column.setSpaceAfter(20.0); + + // Set the second column to take the rest of the space available within the margins of the page. + column = columns.get(1); + column.setWidth(contentWidth - column.getWidth() - column.getSpaceAfter()); + + builder.writeln("Narrow column 1."); + builder.insertBreak(BreakType.COLUMN_BREAK); + builder.writeln("Wide column 2."); + + doc.save(getArtifactsDir() + "PageSetup.CustomColumnWidth.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.CustomColumnWidth.docx"); + pageSetup = doc.getFirstSection().getPageSetup(); + + Assert.assertFalse(pageSetup.getTextColumns().getEvenlySpaced()); + Assert.assertEquals(2, pageSetup.getTextColumns().getCount()); + Assert.assertEquals(100.0d, pageSetup.getTextColumns().get(0).getWidth()); + Assert.assertEquals(20.0d, pageSetup.getTextColumns().get(0).getSpaceAfter()); + Assert.assertEquals(470.3d, pageSetup.getTextColumns().get(1).getWidth()); + Assert.assertEquals(0.0d, pageSetup.getTextColumns().get(1).getSpaceAfter()); + } + + @Test (dataProvider = "verticalLineBetweenColumnsDataProvider") + public void verticalLineBetweenColumns(boolean lineBetween) throws Exception + { + //ExStart + //ExFor:TextColumnCollection.LineBetween + //ExSummary:Shows how to separate columns with a vertical line. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Configure the current section's PageSetup object to divide the text into several columns. + // Set the "LineBetween" property to "true" to put a dividing line between columns. + // Set the "LineBetween" property to "false" to leave the space between columns blank. + TextColumnCollection columns = builder.getPageSetup().getTextColumns(); + columns.setLineBetween(lineBetween); + columns.setCount(3); + + builder.writeln("Column 1."); + builder.insertBreak(BreakType.COLUMN_BREAK); + builder.writeln("Column 2."); + builder.insertBreak(BreakType.COLUMN_BREAK); + builder.writeln("Column 3."); + + doc.save(getArtifactsDir() + "PageSetup.VerticalLineBetweenColumns.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.VerticalLineBetweenColumns.docx"); + + Assert.assertEquals(lineBetween, doc.getFirstSection().getPageSetup().getTextColumns().getLineBetween()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "verticalLineBetweenColumnsDataProvider") + public static Object[][] verticalLineBetweenColumnsDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void lineNumbers() throws Exception + { + //ExStart + //ExFor:PageSetup.LineStartingNumber + //ExFor:PageSetup.LineNumberDistanceFromText + //ExFor:PageSetup.LineNumberCountBy + //ExFor:PageSetup.LineNumberRestartMode + //ExFor:ParagraphFormat.SuppressLineNumbers + //ExFor:LineNumberRestartMode + //ExSummary:Shows how to enable line numbering for a section. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // We can use the section's PageSetup object to display numbers to the left of the section's text lines. + // This is the same behavior as a List object, + // but it covers the entire section and does not modify the text in any way. + // Our section will restart the numbering on each new page from 1 and display the number, + // if it is a multiple of 3, at 50pt to the left of the line. + PageSetup pageSetup = builder.getPageSetup(); + pageSetup.setLineStartingNumber(1); + pageSetup.setLineNumberCountBy(3); + pageSetup.setLineNumberRestartMode(LineNumberRestartMode.RESTART_PAGE); + pageSetup.setLineNumberDistanceFromText(50.0d); + + for (int i = 1; i <= 25; i++) + builder.writeln($"Line {i}."); + + // The line counter will skip any paragraph with the "SuppressLineNumbers" flag set to "true". + // This paragraph is on the 15th line, which is a multiple of 3, and thus would normally display a line number. + // The section's line counter will also ignore this line, treat the next line as the 15th, + // and continue the count from that point onward. + doc.getFirstSection().getBody().getParagraphs().get(14).getParagraphFormat().setSuppressLineNumbers(true); + + doc.save(getArtifactsDir() + "PageSetup.LineNumbers.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.LineNumbers.docx"); + pageSetup = doc.getFirstSection().getPageSetup(); + + Assert.assertEquals(1, pageSetup.getLineStartingNumber()); + Assert.assertEquals(3, pageSetup.getLineNumberCountBy()); + Assert.assertEquals(LineNumberRestartMode.RESTART_PAGE, pageSetup.getLineNumberRestartMode()); + Assert.assertEquals(50.0d, pageSetup.getLineNumberDistanceFromText()); + } + + @Test + public void pageBorderProperties() throws Exception + { + //ExStart + //ExFor:Section.PageSetup + //ExFor:PageSetup.BorderAlwaysInFront + //ExFor:PageSetup.BorderDistanceFrom + //ExFor:PageSetup.BorderAppliesTo + //ExFor:PageBorderDistanceFrom + //ExFor:PageBorderAppliesTo + //ExFor:Border.DistanceFromText + //ExSummary:Shows how to create a wide blue band border at the top of the first page. + Document doc = new Document(); + + PageSetup pageSetup = doc.getSections().get(0).getPageSetup(); + pageSetup.setBorderAlwaysInFront(false); + pageSetup.setBorderDistanceFrom(PageBorderDistanceFrom.PAGE_EDGE); + pageSetup.setBorderAppliesTo(PageBorderAppliesTo.FIRST_PAGE); + + Border border = pageSetup.getBorders().getByBorderType(BorderType.TOP); + border.setLineStyle(LineStyle.SINGLE); + border.setLineWidth(30.0); + border.setColor(Color.BLUE); + border.setDistanceFromText(0.0); + + doc.save(getArtifactsDir() + "PageSetup.PageBorderProperties.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.PageBorderProperties.docx"); + pageSetup = doc.getFirstSection().getPageSetup(); + + Assert.assertFalse(pageSetup.getBorderAlwaysInFront()); + Assert.assertEquals(PageBorderDistanceFrom.PAGE_EDGE, pageSetup.getBorderDistanceFrom()); + Assert.assertEquals(PageBorderAppliesTo.FIRST_PAGE, pageSetup.getBorderAppliesTo()); + + border = pageSetup.getBorders().getByBorderType(BorderType.TOP); + + Assert.assertEquals(LineStyle.SINGLE, border.getLineStyle()); + Assert.assertEquals(30.0d, border.getLineWidth()); + Assert.assertEquals(Color.BLUE.getRGB(), border.getColor().getRGB()); + Assert.assertEquals(0.0d, border.getDistanceFromText()); + } + + @Test + public void pageBorders() throws Exception + { + //ExStart + //ExFor:PageSetup.Borders + //ExFor:Border.Shadow + //ExFor:BorderCollection.LineStyle + //ExFor:BorderCollection.LineWidth + //ExFor:BorderCollection.Color + //ExFor:BorderCollection.DistanceFromText + //ExFor:BorderCollection.Shadow + //ExSummary:Shows how to create green wavy page border with a shadow. + Document doc = new Document(); + PageSetup pageSetup = doc.getSections().get(0).getPageSetup(); + + pageSetup.getBorders().setLineStyle(LineStyle.DOUBLE_WAVE); + pageSetup.getBorders().setLineWidth(2.0); + pageSetup.getBorders().setColor(msColor.getGreen()); + pageSetup.getBorders().setDistanceFromText(24.0); + pageSetup.getBorders().setShadow(true); + + doc.save(getArtifactsDir() + "PageSetup.PageBorders.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.PageBorders.docx"); + pageSetup = doc.getFirstSection().getPageSetup(); + + for (Border border : pageSetup.getBorders()) + { + Assert.assertEquals(LineStyle.DOUBLE_WAVE, border.getLineStyle()); + Assert.assertEquals(2.0d, border.getLineWidth()); + Assert.assertEquals(msColor.getGreen().getRGB(), border.getColor().getRGB()); + Assert.assertEquals(24.0d, border.getDistanceFromText()); + Assert.assertTrue(border.getShadow()); + } + } + + @Test + public void pageNumbering() throws Exception + { + //ExStart + //ExFor:PageSetup.RestartPageNumbering + //ExFor:PageSetup.PageStartingNumber + //ExFor:PageSetup.PageNumberStyle + //ExFor:DocumentBuilder.InsertField(String, String) + //ExSummary:Shows how to set up page numbering in a section. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Section 1, page 1."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Section 1, page 2."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Section 1, page 3."); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.writeln("Section 2, page 1."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Section 2, page 2."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Section 2, page 3."); + + // Move the document builder to the first section's primary header, + // which every page in that section will display. + builder.moveToSection(0); + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + + // Insert a PAGE field, which will display the number of the current page. + builder.write("Page "); + builder.insertField("PAGE", ""); + + // Configure the section to have the page count that PAGE fields display start from 5. + // Also, configure all PAGE fields to display their page numbers using uppercase Roman numerals. + PageSetup pageSetup = doc.getSections().get(0).getPageSetup(); + pageSetup.setRestartPageNumbering(true); + pageSetup.setPageStartingNumber(5); + pageSetup.setPageNumberStyle(NumberStyle.UPPERCASE_ROMAN); + + // Create another primary header for the second section, with another PAGE field. + builder.moveToSection(1); + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.write(" - "); + builder.insertField("PAGE", ""); + builder.write(" - "); + + // Configure the section to have the page count that PAGE fields display start from 10. + // Also, configure all PAGE fields to display their page numbers using Arabic numbers. + pageSetup = doc.getSections().get(1).getPageSetup(); + pageSetup.setPageStartingNumber(10); + pageSetup.setRestartPageNumbering(true); + pageSetup.setPageNumberStyle(NumberStyle.ARABIC); + + doc.save(getArtifactsDir() + "PageSetup.PageNumbering.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.PageNumbering.docx"); + pageSetup = doc.getSections().get(0).getPageSetup(); + + Assert.assertTrue(pageSetup.getRestartPageNumbering()); + Assert.assertEquals(5, pageSetup.getPageStartingNumber()); + Assert.assertEquals(NumberStyle.UPPERCASE_ROMAN, pageSetup.getPageNumberStyle()); + + pageSetup = doc.getSections().get(1).getPageSetup(); + + Assert.assertTrue(pageSetup.getRestartPageNumbering()); + Assert.assertEquals(10, pageSetup.getPageStartingNumber()); + Assert.assertEquals(NumberStyle.ARABIC, pageSetup.getPageNumberStyle()); + } + + @Test + public void footnoteOptions() throws Exception + { + //ExStart + //ExFor:PageSetup.EndnoteOptions + //ExFor:PageSetup.FootnoteOptions + //ExSummary:Shows how to configure options affecting footnotes/endnotes in a section. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Hello world!"); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Footnote reference text."); + + // Configure all footnotes in the first section to restart the numbering from 1 + // at each new page and display themselves directly beneath the text on every page. + FootnoteOptions footnoteOptions = doc.getSections().get(0).getPageSetup().getFootnoteOptions(); + footnoteOptions.setPosition(FootnotePosition.BENEATH_TEXT); + footnoteOptions.setRestartRule(FootnoteNumberingRule.RESTART_PAGE); + footnoteOptions.setStartNumber(1); + + builder.write(" Hello again."); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Endnote reference text."); + + // Configure all endnotes in the first section to maintain a continuous count throughout the section, + // starting from 1. Also, set them all to appear collected at the end of the document. + EndnoteOptions endnoteOptions = doc.getSections().get(0).getPageSetup().getEndnoteOptions(); + endnoteOptions.setPosition(EndnotePosition.END_OF_DOCUMENT); + endnoteOptions.setRestartRule(FootnoteNumberingRule.CONTINUOUS); + endnoteOptions.setStartNumber(1); + + doc.save(getArtifactsDir() + "PageSetup.FootnoteOptions.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.FootnoteOptions.docx"); + footnoteOptions = doc.getFirstSection().getPageSetup().getFootnoteOptions(); + + Assert.assertEquals(FootnotePosition.BENEATH_TEXT, footnoteOptions.getPosition()); + Assert.assertEquals(FootnoteNumberingRule.RESTART_PAGE, footnoteOptions.getRestartRule()); + Assert.assertEquals(1, footnoteOptions.getStartNumber()); + + endnoteOptions = doc.getFirstSection().getPageSetup().getEndnoteOptions(); + + Assert.assertEquals(EndnotePosition.END_OF_DOCUMENT, endnoteOptions.getPosition()); + Assert.assertEquals(FootnoteNumberingRule.CONTINUOUS, endnoteOptions.getRestartRule()); + Assert.assertEquals(1, endnoteOptions.getStartNumber()); + } + + @Test (dataProvider = "bidiDataProvider") + public void bidi(boolean reverseColumns) throws Exception + { + //ExStart + //ExFor:PageSetup.Bidi + //ExSummary:Shows how to set the order of text columns in a section. + Document doc = new Document(); + + PageSetup pageSetup = doc.getSections().get(0).getPageSetup(); + pageSetup.getTextColumns().setCount(3); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.write("Column 1."); + builder.insertBreak(BreakType.COLUMN_BREAK); + builder.write("Column 2."); + builder.insertBreak(BreakType.COLUMN_BREAK); + builder.write("Column 3."); + + // Set the "Bidi" property to "true" to arrange the columns starting from the page's right side. + // The order of the columns will match the direction of the right-to-left text. + // Set the "Bidi" property to "false" to arrange the columns starting from the page's left side. + // The order of the columns will match the direction of the left-to-right text. + pageSetup.setBidi(reverseColumns); + + doc.save(getArtifactsDir() + "PageSetup.Bidi.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.Bidi.docx"); + pageSetup = doc.getFirstSection().getPageSetup(); + + Assert.assertEquals(3, pageSetup.getTextColumns().getCount()); + Assert.assertEquals(reverseColumns, pageSetup.getBidi()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "bidiDataProvider") + public static Object[][] bidiDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void pageBorder() throws Exception + { + //ExStart + //ExFor:PageSetup.BorderSurroundsFooter + //ExFor:PageSetup.BorderSurroundsHeader + //ExSummary:Shows how to apply a border to the page and header/footer. + Document doc = new Document(); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world! This is the main body text."); + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.write("This is the header."); + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + builder.write("This is the footer."); + builder.moveToDocumentEnd(); + + // Insert a blue double-line border. + PageSetup pageSetup = doc.getSections().get(0).getPageSetup(); + pageSetup.getBorders().setLineStyle(LineStyle.DOUBLE); + pageSetup.getBorders().setColor(Color.BLUE); + + // A section's PageSetup object has "BorderSurroundsHeader" and "BorderSurroundsFooter" flags that determine + // whether a page border surrounds the main body text, also includes the header or footer, respectively. + // Set the "BorderSurroundsHeader" flag to "true" to surround the header with our border, + // and then set the "BorderSurroundsFooter" flag to leave the footer outside of the border. + pageSetup.setBorderSurroundsHeader(true); + pageSetup.setBorderSurroundsFooter(false); + + doc.save(getArtifactsDir() + "PageSetup.PageBorder.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.PageBorder.docx"); + pageSetup = doc.getFirstSection().getPageSetup(); + + Assert.assertTrue(pageSetup.getBorderSurroundsHeader()); + Assert.assertFalse(pageSetup.getBorderSurroundsFooter()); + } + + @Test + public void gutter() throws Exception + { + //ExStart + //ExFor:PageSetup.Gutter + //ExFor:PageSetup.RtlGutter + //ExFor:PageSetup.MultiplePages + //ExSummary:Shows how to set gutter margins. + Document doc = new Document(); + + // Insert text that spans several pages. + DocumentBuilder builder = new DocumentBuilder(doc); + for (int i = 0; i < 6; i++) + { + builder.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + builder.insertBreak(BreakType.PAGE_BREAK); + } + + // A gutter adds whitespaces to either the left or right page margin, + // which makes up for the center folding of pages in a book encroaching on the page's layout. + PageSetup pageSetup = doc.getSections().get(0).getPageSetup(); + + // Determine how much space our pages have for text within the margins and then add an amount to pad a margin. + Assert.assertEquals(470.30d, 0.01d, pageSetup.getPageWidth() - pageSetup.getLeftMargin() - pageSetup.getRightMargin()); + + pageSetup.setGutter(100.0d); + + // Set the "RtlGutter" property to "true" to place the gutter in a more suitable position for right-to-left text. + pageSetup.setRtlGutter(true); + + // Set the "MultiplePages" property to "MultiplePagesType.MirrorMargins" to alternate + // the left/right page side position of margins every page. + pageSetup.setMultiplePages(MultiplePagesType.MIRROR_MARGINS); + + doc.save(getArtifactsDir() + "PageSetup.Gutter.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.Gutter.docx"); + pageSetup = doc.getFirstSection().getPageSetup(); + + Assert.assertEquals(100.0d, pageSetup.getGutter()); + Assert.assertTrue(pageSetup.getRtlGutter()); + Assert.assertEquals(MultiplePagesType.MIRROR_MARGINS, pageSetup.getMultiplePages()); + } + + @Test + public void booklet() throws Exception + { + //ExStart + //ExFor:PageSetup.Gutter + //ExFor:PageSetup.MultiplePages + //ExFor:PageSetup.SheetsPerBooklet + //ExFor:MultiplePagesType + //ExSummary:Shows how to configure a document that can be printed as a book fold. + Document doc = new Document(); + + // Insert text that spans 16 pages. + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("My Booklet:"); + + for (int i = 0; i < 15; i++) + { + builder.insertBreak(BreakType.PAGE_BREAK); + builder.write($"Booklet face #{i}"); + } + + // Configure the first section's "PageSetup" property to print the document in the form of a book fold. + // When we print this document on both sides, we can take the pages to stack them + // and fold them all down the middle at once. The contents of the document will line up into a book fold. + PageSetup pageSetup = doc.getSections().get(0).getPageSetup(); + pageSetup.setMultiplePages(MultiplePagesType.BOOK_FOLD_PRINTING); + + // We can only specify the number of sheets in multiples of 4. + pageSetup.setSheetsPerBooklet(4); + + doc.save(getArtifactsDir() + "PageSetup.Booklet.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.Booklet.docx"); + pageSetup = doc.getFirstSection().getPageSetup(); + + Assert.assertEquals(MultiplePagesType.BOOK_FOLD_PRINTING, pageSetup.getMultiplePages()); + Assert.assertEquals(4, pageSetup.getSheetsPerBooklet()); + } + + @Test + public void setTextOrientation() throws Exception + { + //ExStart + //ExFor:PageSetup.TextOrientation + //ExSummary:Shows how to set text orientation. + Document doc = new Document(); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + // Set the "TextOrientation" property to "TextOrientation.Upward" to rotate all the text 90 degrees + // to the right so that all left-to-right text now goes top-to-bottom. + PageSetup pageSetup = doc.getSections().get(0).getPageSetup(); + pageSetup.setTextOrientation(TextOrientation.UPWARD); + + doc.save(getArtifactsDir() + "PageSetup.SetTextOrientation.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "PageSetup.SetTextOrientation.docx"); + pageSetup = doc.getFirstSection().getPageSetup(); + + Assert.assertEquals(TextOrientation.UPWARD, pageSetup.getTextOrientation()); + } + + //ExStart + //ExFor:PageSetup.SuppressEndnotes + //ExFor:Body.ParentSection + //ExSummary:Shows how to store endnotes at the end of each section, and modify their positions. + @Test //ExSkip + public void suppressEndnotes() throws Exception + { + Document doc = new Document(); + doc.removeAllChildren(); + + // By default, a document compiles all endnotes at its end. + Assert.assertEquals(EndnotePosition.END_OF_DOCUMENT, doc.getEndnoteOptions().getPosition()); + + // We use the "Position" property of the document's "EndnoteOptions" object + // to collect endnotes at the end of each section instead. + doc.getEndnoteOptions().setPosition(EndnotePosition.END_OF_SECTION); + + insertSectionWithEndnote(doc, "Section 1", "Endnote 1, will stay in section 1"); + insertSectionWithEndnote(doc, "Section 2", "Endnote 2, will be pushed down to section 3"); + insertSectionWithEndnote(doc, "Section 3", "Endnote 3, will stay in section 3"); + + // While getting sections to display their respective endnotes, we can set the "SuppressEndnotes" flag + // of a section's "PageSetup" object to "true" to revert to the default behavior and pass its endnotes + // onto the next section. + PageSetup pageSetup = doc.getSections().get(1).getPageSetup(); + pageSetup.setSuppressEndnotes(true); + + doc.save(getArtifactsDir() + "PageSetup.SuppressEndnotes.docx"); + testSuppressEndnotes(new Document(getArtifactsDir() + "PageSetup.SuppressEndnotes.docx")); //ExSkip + } + + /// + /// Append a section with text and an endnote to a document. + /// + private static void insertSectionWithEndnote(Document doc, String sectionBodyText, String endnoteText) + { + Section section = new Section(doc); + + doc.appendChild(section); + + Body body = new Body(doc); + section.appendChild(body); + + Assert.assertEquals(section, body.getParentNode()); + + Paragraph para = new Paragraph(doc); + body.appendChild(para); + + Assert.assertEquals(body, para.getParentNode()); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.moveTo(para); + builder.write(sectionBodyText); + builder.insertFootnote(FootnoteType.ENDNOTE, endnoteText); + } + //ExEnd + + private static void testSuppressEndnotes(Document doc) + { + PageSetup pageSetup = doc.getSections().get(1).getPageSetup(); + + Assert.assertTrue(pageSetup.getSuppressEndnotes()); + } + + @Test + public void chapterPageSeparator() throws Exception + { + //ExStart + //ExFor:PageSetup.HeadingLevelForChapter + //ExFor:ChapterPageSeparator + //ExFor:PageSetup.ChapterPageSeparator + //ExSummary:Shows how to work with page chapters. + Document doc = new Document(getMyDir() + "Big document.docx"); + + PageSetup pageSetup = doc.getFirstSection().getPageSetup(); + + pageSetup.setPageNumberStyle(NumberStyle.UPPERCASE_ROMAN); + pageSetup.setChapterPageSeparator(com.aspose.words.ChapterPageSeparator.COLON); + pageSetup.setHeadingLevelForChapter(1); + //ExEnd + } + + @Test + public void jisbPaperSize() throws Exception + { + //ExStart:JisbPaperSize + //GistId:12a3a3cfe30f3145220db88428a9f814 + //ExFor:PageSetup.PaperSize + //ExSummary:Shows how to set the paper size of JisB4 or JisB5. + Document doc = new Document(getMyDir() + "Big document.docx"); + + PageSetup pageSetup = doc.getFirstSection().getPageSetup(); + // Set the paper size to JisB4 (257x364mm). + pageSetup.setPaperSize(PaperSize.JIS_B_4); + // Alternatively, set the paper size to JisB5. (182x257mm). + pageSetup.setPaperSize(PaperSize.JIS_B_5); + //ExEnd:JisbPaperSize + + doc = DocumentHelper.saveOpen(doc); + pageSetup = doc.getFirstSection().getPageSetup(); + + Assert.assertEquals(PaperSize.JIS_B_5, pageSetup.getPaperSize()); + } + + @Test (enabled = false, description = "Run only when the printer driver is installed") + public void printPagesRemaining() throws Exception + { + //ExStart:PrintPagesRemaining + //GistId:571cc6e23284a2ec075d15d4c32e3bbf + //ExFor:AsposeWordsPrintDocument + //ExFor:AsposeWordsPrintDocument.PagesRemaining + //ExSummary: Shows how to monitor printing progress. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // Initialize the printer settings. + PrinterSettings printerSettings = new PrinterSettings(); + printerSettings.setPrinterName("Microsoft Print to PDF"); + printerSettings.setPrintRange(PrintRange.AllPages); + + // Create a special Aspose.Words implementation of the .NET PrintDocument class. + // Pass the printer settings from the print dialog to the print document. + AsposeWordsPrintDocument printDoc = new AsposeWordsPrintDocument(doc); + printDoc.setPrinterSettings(printerSettings); + + // Initialize the custom printing tracker. + PrintTracker printTracker = new PrintTracker(printDoc); + + printDoc.print(); + + // Write the event log. + for (String eventString : printTracker.getEventLog()) + System.out.println(eventString); + //ExEnd:PrintPagesRemaining + } +} diff --git a/Examples/ApiExamples/JavaPorting/ExParagraph.java b/Examples/ApiExamples/JavaPorting/ExParagraph.java new file mode 100644 index 00000000..5cacc6c9 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExParagraph.java @@ -0,0 +1,672 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.Font; +import java.awt.Color; +import com.aspose.words.Underline; +import com.aspose.words.ParagraphFormat; +import com.aspose.words.ParagraphAlignment; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.Paragraph; +import com.aspose.words.FieldType; +import java.util.Date; +import com.aspose.ms.System.DateTime; +import com.aspose.ms.System.TimeSpan; +import com.aspose.words.Run; +import com.aspose.words.Field; +import java.text.MessageFormat; +import com.aspose.words.NodeType; +import com.aspose.words.ParagraphCollection; +import com.aspose.words.Revision; +import com.aspose.words.RevisionType; +import com.aspose.words.HeightRule; +import com.aspose.words.HorizontalAlignment; +import com.aspose.words.VerticalAlignment; +import com.aspose.words.RelativeHorizontalPosition; +import com.aspose.words.RelativeVerticalPosition; +import com.aspose.words.Node; +import com.aspose.words.Body; +import com.aspose.words.BreakType; +import com.aspose.words.StyleIdentifier; +import com.aspose.words.TabStopCollection; +import com.aspose.words.TabAlignment; +import com.aspose.words.TabLeader; + + +@Test +class ExParagraph !Test class should be public in Java to run, please fix .Net source! extends ApiExampleBase +{ + @Test + public void documentBuilderInsertParagraph() throws Exception + { + //ExStart + //ExFor:DocumentBuilder.InsertParagraph + //ExFor:ParagraphFormat.FirstLineIndent + //ExFor:ParagraphFormat.Alignment + //ExFor:ParagraphFormat.KeepTogether + //ExFor:ParagraphFormat.AddSpaceBetweenFarEastAndAlpha + //ExFor:ParagraphFormat.AddSpaceBetweenFarEastAndDigit + //ExFor:Paragraph.IsEndOfDocument + //ExSummary:Shows how to insert a paragraph into the document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Font font = builder.getFont(); + font.setSize(16.0); + font.setBold(true); + font.setColor(Color.BLUE); + font.setName("Arial"); + font.setUnderline(Underline.DASH); + + ParagraphFormat paragraphFormat = builder.getParagraphFormat(); + paragraphFormat.setFirstLineIndent(8.0); + paragraphFormat.setAlignment(ParagraphAlignment.JUSTIFY); + paragraphFormat.setAddSpaceBetweenFarEastAndAlpha(true); + paragraphFormat.setAddSpaceBetweenFarEastAndDigit(true); + paragraphFormat.setKeepTogether(true); + + // The "Writeln" method ends the paragraph after appending text + // and then starts a new line, adding a new paragraph. + builder.writeln("Hello world!"); + + Assert.assertTrue(builder.getCurrentParagraph().isEndOfDocument()); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + Paragraph paragraph = doc.getFirstSection().getBody().getFirstParagraph(); + + Assert.assertEquals(8, paragraph.getParagraphFormat().getFirstLineIndent()); + Assert.assertEquals(ParagraphAlignment.JUSTIFY, paragraph.getParagraphFormat().getAlignment()); + Assert.assertTrue(paragraph.getParagraphFormat().getAddSpaceBetweenFarEastAndAlpha()); + Assert.assertTrue(paragraph.getParagraphFormat().getAddSpaceBetweenFarEastAndDigit()); + Assert.assertTrue(paragraph.getParagraphFormat().getKeepTogether()); + Assert.assertEquals("Hello world!", paragraph.getText().trim()); + + Font runFont = paragraph.getRuns().get(0).getFont(); + + Assert.assertEquals(16.0d, runFont.getSize()); + Assert.assertTrue(runFont.getBold()); + Assert.assertEquals(Color.BLUE.getRGB(), runFont.getColor().getRGB()); + Assert.assertEquals("Arial", runFont.getName()); + Assert.assertEquals(Underline.DASH, runFont.getUnderline()); + } + + @Test + public void appendField() throws Exception + { + //ExStart + //ExFor:Paragraph.AppendField(FieldType, Boolean) + //ExFor:Paragraph.AppendField(String) + //ExFor:Paragraph.AppendField(String, String) + //ExSummary:Shows various ways of appending fields to a paragraph. + Document doc = new Document(); + Paragraph paragraph = doc.getFirstSection().getBody().getFirstParagraph(); + + // Below are three ways of appending a field to the end of a paragraph. + // 1 - Append a DATE field using a field type, and then update it: + paragraph.appendField(FieldType.FIELD_DATE, true); + + // 2 - Append a TIME field using a field code: + paragraph.appendField(" TIME \\@ \"HH:mm:ss\" "); + + // 3 - Append a QUOTE field using a field code, and get it to display a placeholder value: + paragraph.appendField(" QUOTE \"Real value\"", "Placeholder value"); + + Assert.assertEquals("Placeholder value", doc.getRange().getFields().get(2).getResult()); + + // This field will display its placeholder value until we update it. + doc.updateFields(); + + Assert.assertEquals("Real value", doc.getRange().getFields().get(2).getResult()); + + doc.save(getArtifactsDir() + "Paragraph.AppendField.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Paragraph.AppendField.docx"); + + TestUtil.verifyField(FieldType.FIELD_DATE, " DATE ", new Date, doc.getRange().getFields().get(0), new TimeSpan(0, 0, 0, 0)); + TestUtil.verifyField(FieldType.FIELD_TIME, " TIME \\@ \"HH:mm:ss\" ", new Date, doc.getRange().getFields().get(1), new TimeSpan(0, 0, 0, 5)); + TestUtil.verifyField(FieldType.FIELD_QUOTE, " QUOTE \"Real value\"", "Real value", doc.getRange().getFields().get(2)); + } + + @Test + public void insertField() throws Exception + { + //ExStart + //ExFor:Paragraph.InsertField(string, Node, bool) + //ExFor:Paragraph.InsertField(FieldType, bool, Node, bool) + //ExFor:Paragraph.InsertField(string, string, Node, bool) + //ExSummary:Shows various ways of adding fields to a paragraph. + Document doc = new Document(); + Paragraph para = doc.getFirstSection().getBody().getFirstParagraph(); + + // Below are three ways of inserting a field into a paragraph. + // 1 - Insert an AUTHOR field into a paragraph after one of the paragraph's child nodes: + Run run = new Run(doc); { run.setText("This run was written by "); } + para.appendChild(run); + + doc.getBuiltInDocumentProperties().get("Author").setValue("John Doe"); + para.insertField(FieldType.FIELD_AUTHOR, true, run, true); + + // 2 - Insert a QUOTE field after one of the paragraph's child nodes: + run = new Run(doc); { run.setText("."); } + para.appendChild(run); + + Field field = para.insertField(" QUOTE \" Real value\" ", run, true); + + // 3 - Insert a QUOTE field before one of the paragraph's child nodes, + // and get it to display a placeholder value: + para.insertField(" QUOTE \" Real value.\"", " Placeholder value.", field.getStart(), false); + + Assert.assertEquals(" Placeholder value.", doc.getRange().getFields().get(1).getResult()); + + // This field will display its placeholder value until we update it. + doc.updateFields(); + + Assert.assertEquals(" Real value.", doc.getRange().getFields().get(1).getResult()); + + doc.save(getArtifactsDir() + "Paragraph.InsertField.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Paragraph.InsertField.docx"); + + TestUtil.verifyField(FieldType.FIELD_AUTHOR, " AUTHOR ", "John Doe", doc.getRange().getFields().get(0)); + TestUtil.verifyField(FieldType.FIELD_QUOTE, " QUOTE \" Real value.\"", " Real value.", doc.getRange().getFields().get(1)); + TestUtil.verifyField(FieldType.FIELD_QUOTE, " QUOTE \" Real value\" ", " Real value", doc.getRange().getFields().get(2)); + } + + @Test + public void insertFieldBeforeTextInParagraph() throws Exception + { + Document doc = DocumentHelper.createDocumentFillWithDummyText(); + + insertFieldUsingFieldCode(doc, " AUTHOR ", null, false, 1); + + Assert.assertEquals("\u0013 AUTHOR \u0014Test Author\u0015Hello World!\r", DocumentHelper.getParagraphText(doc, 1)); + } + + @Test + public void insertFieldAfterTextInParagraph() throws Exception + { + String date = DateTime.getToday().toString("d"); + + Document doc = DocumentHelper.createDocumentFillWithDummyText(); + + insertFieldUsingFieldCode(doc, " DATE ", null, true, 1); + + Assert.assertEquals(MessageFormat.format("Hello World!\u0013 DATE \u0014{0}\u0015\r", date), DocumentHelper.getParagraphText(doc, 1)); + } + + @Test + public void insertFieldBeforeTextInParagraphWithoutUpdateField() throws Exception + { + Document doc = DocumentHelper.createDocumentFillWithDummyText(); + + insertFieldUsingFieldType(doc, FieldType.FIELD_AUTHOR, false, null, false, 1); + + Assert.assertEquals("\u0013 AUTHOR \u0014\u0015Hello World!\r", DocumentHelper.getParagraphText(doc, 1)); + } + + @Test + public void insertFieldAfterTextInParagraphWithoutUpdateField() throws Exception + { + Document doc = DocumentHelper.createDocumentFillWithDummyText(); + + insertFieldUsingFieldType(doc, FieldType.FIELD_AUTHOR, false, null, true, 1); + + Assert.assertEquals("Hello World!\u0013 AUTHOR \u0014\u0015\r", DocumentHelper.getParagraphText(doc, 1)); + } + + @Test + public void insertFieldWithoutSeparator() throws Exception + { + Document doc = DocumentHelper.createDocumentFillWithDummyText(); + + insertFieldUsingFieldType(doc, FieldType.FIELD_LIST_NUM, true, null, false, 1); + + Assert.assertEquals("\u0013 LISTNUM \u0015Hello World!\r", DocumentHelper.getParagraphText(doc, 1)); + } + + @Test + public void insertFieldBeforeParagraphWithoutDocumentAuthor() throws Exception + { + Document doc = DocumentHelper.createDocumentFillWithDummyText(); + doc.getBuiltInDocumentProperties().setAuthor(""); + + insertFieldUsingFieldCodeFieldString(doc, " AUTHOR ", null, null, false, 1); + + Assert.assertEquals("\u0013 AUTHOR \u0014\u0015Hello World!\r", DocumentHelper.getParagraphText(doc, 1)); + } + + @Test + public void insertFieldAfterParagraphWithoutChangingDocumentAuthor() throws Exception + { + Document doc = DocumentHelper.createDocumentFillWithDummyText(); + + insertFieldUsingFieldCodeFieldString(doc, " AUTHOR ", null, null, true, 1); + + Assert.assertEquals("Hello World!\u0013 AUTHOR \u0014\u0015\r", DocumentHelper.getParagraphText(doc, 1)); + } + + @Test + public void insertFieldBeforeRunText() throws Exception + { + Document doc = DocumentHelper.createDocumentFillWithDummyText(); + + //Add some text into the paragraph + Run run = DocumentHelper.insertNewRun(doc, " Hello World!", 1); + + insertFieldUsingFieldCodeFieldString(doc, " AUTHOR ", "Test Field Value", run, false, 1); + + Assert.assertEquals("Hello World!\u0013 AUTHOR \u0014Test Field Value\u0015 Hello World!\r", DocumentHelper.getParagraphText(doc, 1)); + } + + @Test + public void insertFieldAfterRunText() throws Exception + { + Document doc = DocumentHelper.createDocumentFillWithDummyText(); + + // Add some text into the paragraph + Run run = DocumentHelper.insertNewRun(doc, " Hello World!", 1); + + insertFieldUsingFieldCodeFieldString(doc, " AUTHOR ", "", run, true, 1); + + Assert.assertEquals("Hello World! Hello World!\u0013 AUTHOR \u0014\u0015\r", DocumentHelper.getParagraphText(doc, 1)); + } + + @Test (description = "WORDSNET-12396") + public void insertFieldEmptyParagraphWithoutUpdateField() throws Exception + { + Document doc = DocumentHelper.createDocumentWithoutDummyText(); + + insertFieldUsingFieldType(doc, FieldType.FIELD_AUTHOR, false, null, false, 1); + + Assert.assertEquals("\u0013 AUTHOR \u0014\u0015\f", DocumentHelper.getParagraphText(doc, 1)); + } + + @Test (description = "WORDSNET-12397") + public void insertFieldEmptyParagraphWithUpdateField() throws Exception + { + Document doc = DocumentHelper.createDocumentWithoutDummyText(); + + insertFieldUsingFieldType(doc, FieldType.FIELD_AUTHOR, true, null, false, 0); + + Assert.assertEquals("\u0013 AUTHOR \u0014Test Author\u0015\r", DocumentHelper.getParagraphText(doc, 0)); + } + + @Test + public void compositeNodeChildren() throws Exception + { + //ExStart + //ExFor:CompositeNode.Count + //ExFor:CompositeNode.GetChildNodes(NodeType, Boolean) + //ExFor:CompositeNode.InsertAfter``1(``0, Node) + //ExFor:CompositeNode.InsertBefore``1(``0, Node) + //ExFor:CompositeNode.PrependChild``1(``0) + //ExFor:Paragraph.GetText + //ExFor:Run + //ExSummary:Shows how to add, update and delete child nodes in a CompositeNode's collection of children. + Document doc = new Document(); + + // An empty document, by default, has one paragraph. + Assert.assertEquals(1, doc.getFirstSection().getBody().getParagraphs().getCount()); + + // Composite nodes such as our paragraph can contain other composite and inline nodes as children. + Paragraph paragraph = doc.getFirstSection().getBody().getFirstParagraph(); + Run paragraphText = new Run(doc, "Initial text. "); + paragraph.appendChild(paragraphText); + + // Create three more run nodes. + Run run1 = new Run(doc, "Run 1. "); + Run run2 = new Run(doc, "Run 2. "); + Run run3 = new Run(doc, "Run 3. "); + + // The document body will not display these runs until we insert them into a composite node + // that itself is a part of the document's node tree, as we did with the first run. + // We can determine where the text contents of nodes that we insert + // appears in the document by specifying an insertion location relative to another node in the paragraph. + Assert.assertEquals("Initial text.", paragraph.getText().trim()); + + // Insert the second run into the paragraph in front of the initial run. + paragraph.insertBefore(run2, paragraphText); + + Assert.assertEquals("Run 2. Initial text.", paragraph.getText().trim()); + + // Insert the third run after the initial run. + paragraph.insertAfter(run3, paragraphText); + + Assert.assertEquals("Run 2. Initial text. Run 3.", paragraph.getText().trim()); + + // Insert the first run to the start of the paragraph's child nodes collection. + paragraph.prependChild(run1); + + Assert.assertEquals("Run 1. Run 2. Initial text. Run 3.", paragraph.getText().trim()); + Assert.assertEquals(4, paragraph.getChildNodes(NodeType.ANY, true).getCount()); + + // We can modify the contents of the run by editing and deleting existing child nodes. + ((Run)paragraph.getChildNodes(NodeType.RUN, true).get(1)).setText("Updated run 2. "); + paragraph.getChildNodes(NodeType.RUN, true).remove(paragraphText); + + Assert.assertEquals("Run 1. Updated run 2. Run 3.", paragraph.getText().trim()); + Assert.assertEquals(3, paragraph.getChildNodes(NodeType.ANY, true).getCount()); + //ExEnd + } + + @Test + public void moveRevisions() throws Exception + { + //ExStart + //ExFor:Paragraph.IsMoveFromRevision + //ExFor:Paragraph.IsMoveToRevision + //ExFor:ParagraphCollection + //ExFor:ParagraphCollection.Item(Int32) + //ExFor:Story.Paragraphs + //ExSummary:Shows how to check whether a paragraph is a move revision. + Document doc = new Document(getMyDir() + "Revisions.docx"); + + // This document contains "Move" revisions, which appear when we highlight text with the cursor, + // and then drag it to move it to another location + // while tracking revisions in Microsoft Word via "Review" -> "Track changes". + Assert.That(doc.getRevisions().Count(r => r.RevisionType == RevisionType.Moving), assertEquals(6, ); + + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + // Move revisions consist of pairs of "Move from", and "Move to" revisions. + // These revisions are potential changes to the document that we can either accept or reject. + // Before we accept/reject a move revision, the document + // must keep track of both the departure and arrival destinations of the text. + // The second and the fourth paragraph define one such revision, and thus both have the same contents. + Assert.assertEquals(paragraphs.get(1).getText(), paragraphs.get(3).getText()); + + // The "Move from" revision is the paragraph where we dragged the text from. + // If we accept the revision, this paragraph will disappear, + // and the other will remain and no longer be a revision. + Assert.assertTrue(paragraphs.get(1).isMoveFromRevision()); + + // The "Move to" revision is the paragraph where we dragged the text to. + // If we reject the revision, this paragraph instead will disappear, and the other will remain. + Assert.assertTrue(paragraphs.get(3).isMoveToRevision()); + //ExEnd + } + + @Test + public void rangeRevisions() throws Exception + { + //ExStart + //ExFor:Range.Revisions + //ExSummary:Shows how to work with revisions in range. + Document doc = new Document(getMyDir() + "Revisions.docx"); + + Paragraph paragraph = doc.getFirstSection().getBody().getFirstParagraph(); + for (Revision revision : paragraph.getRange().getRevisions()) + { + if (revision.getRevisionType() == RevisionType.DELETION) + revision.accept(); + } + + // Reject the first section revisions. + doc.getFirstSection().getRange().getRevisions().rejectAll(); + //ExEnd + } + + @Test + public void getFormatRevision() throws Exception + { + //ExStart + //ExFor:Paragraph.IsFormatRevision + //ExSummary:Shows how to check whether a paragraph is a format revision. + Document doc = new Document(getMyDir() + "Format revision.docx"); + + // This paragraph is a "Format" revision, which occurs when we change the formatting of existing text + // while tracking revisions in Microsoft Word via "Review" -> "Track changes". + Assert.assertTrue(doc.getFirstSection().getBody().getFirstParagraph().isFormatRevision()); + //ExEnd + } + + @Test + public void getFrameProperties() throws Exception + { + //ExStart + //ExFor:Paragraph.FrameFormat + //ExFor:FrameFormat + //ExFor:FrameFormat.IsFrame + //ExFor:FrameFormat.Width + //ExFor:FrameFormat.Height + //ExFor:FrameFormat.HeightRule + //ExFor:FrameFormat.HorizontalAlignment + //ExFor:FrameFormat.VerticalAlignment + //ExFor:FrameFormat.HorizontalPosition + //ExFor:FrameFormat.RelativeHorizontalPosition + //ExFor:FrameFormat.HorizontalDistanceFromText + //ExFor:FrameFormat.VerticalPosition + //ExFor:FrameFormat.RelativeVerticalPosition + //ExFor:FrameFormat.VerticalDistanceFromText + //ExSummary:Shows how to get information about formatting properties of paragraphs that are frames. + Document doc = new Document(getMyDir() + "Paragraph frame.docx"); + + Paragraph paragraphFrame = doc.getFirstSection().getBody().getParagraphs().OfType().First(p => p.FrameFormat.IsFrame); + + Assert.assertEquals(233.3d, paragraphFrame.getFrameFormat().getWidth()); + Assert.assertEquals(138.8d, paragraphFrame.getFrameFormat().getHeight()); + Assert.assertEquals(HeightRule.AT_LEAST, paragraphFrame.getFrameFormat().getHeightRule()); + Assert.assertEquals(HorizontalAlignment.DEFAULT, paragraphFrame.getFrameFormat().getHorizontalAlignment()); + Assert.assertEquals(VerticalAlignment.DEFAULT, paragraphFrame.getFrameFormat().getVerticalAlignment()); + Assert.assertEquals(34.05d, paragraphFrame.getFrameFormat().getHorizontalPosition()); + Assert.assertEquals(RelativeHorizontalPosition.PAGE, paragraphFrame.getFrameFormat().getRelativeHorizontalPosition()); + Assert.assertEquals(9.0d, paragraphFrame.getFrameFormat().getHorizontalDistanceFromText()); + Assert.assertEquals(20.5d, paragraphFrame.getFrameFormat().getVerticalPosition()); + Assert.assertEquals(RelativeVerticalPosition.PARAGRAPH, paragraphFrame.getFrameFormat().getRelativeVerticalPosition()); + Assert.assertEquals(0.0d, paragraphFrame.getFrameFormat().getVerticalDistanceFromText()); + //ExEnd + } + + /// + /// Insert field into the first paragraph of the current document using field type. + /// + private static void insertFieldUsingFieldType(Document doc, /*FieldType*/int fieldType, boolean updateField, Node refNode, + boolean isAfter, int paraIndex) throws Exception + { + Paragraph para = DocumentHelper.getParagraph(doc, paraIndex); + para.insertField(fieldType, updateField, refNode, isAfter); + } + + /// + /// Insert field into the first paragraph of the current document using field code. + /// + private static void insertFieldUsingFieldCode(Document doc, String fieldCode, Node refNode, boolean isAfter, + int paraIndex) throws Exception + { + Paragraph para = DocumentHelper.getParagraph(doc, paraIndex); + para.insertField(fieldCode, refNode, isAfter); + } + + /// + /// Insert field into the first paragraph of the current document using field code and field String. + /// + private static void insertFieldUsingFieldCodeFieldString(Document doc, String fieldCode, String fieldValue, + Node refNode, boolean isAfter, int paraIndex) + { + Paragraph para = DocumentHelper.getParagraph(doc, paraIndex); + para.insertField(fieldCode, fieldValue, refNode, isAfter); + } + + @Test + public void isRevision() throws Exception + { + //ExStart + //ExFor:Paragraph.IsDeleteRevision + //ExFor:Paragraph.IsInsertRevision + //ExSummary:Shows how to work with revision paragraphs. + Document doc = new Document(); + Body body = doc.getFirstSection().getBody(); + Paragraph para = body.getFirstParagraph(); + + para.appendChild(new Run(doc, "Paragraph 1. ")); + body.appendParagraph("Paragraph 2. "); + body.appendParagraph("Paragraph 3. "); + + // The above paragraphs are not revisions. + // Paragraphs that we add after starting revision tracking will register as "Insert" revisions. + doc.startTrackRevisionsInternal("John Doe", new Date); + + para = body.appendParagraph("Paragraph 4. "); + + Assert.assertTrue(para.isInsertRevision()); + + // Paragraphs that we remove after starting revision tracking will register as "Delete" revisions. + ParagraphCollection paragraphs = body.getParagraphs(); + + Assert.assertEquals(4, paragraphs.getCount()); + + para = paragraphs.get(2); + para.remove(); + + // Such paragraphs will remain until we either accept or reject the delete revision. + // Accepting the revision will remove the paragraph for good, + // and rejecting the revision will leave it in the document as if we never deleted it. + Assert.assertEquals(4, paragraphs.getCount()); + Assert.assertTrue(para.isDeleteRevision()); + + // Accept the revision, and then verify that the paragraph is gone. + doc.acceptAllRevisions(); + + Assert.assertEquals(3, paragraphs.getCount()); + Assert.assertEquals(0, para.getCount()); + Assert.assertEquals("Paragraph 1. \r" + + "Paragraph 2. \r" + + "Paragraph 4.", doc.getText().trim()); + //ExEnd + } + + @Test + public void breakIsStyleSeparator() throws Exception + { + //ExStart + //ExFor:Paragraph.BreakIsStyleSeparator + //ExSummary:Shows how to write text to the same line as a TOC heading and have it not show up in the TOC. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertTableOfContents("\\o \\h \\z \\u"); + builder.insertBreak(BreakType.PAGE_BREAK); + + // Insert a paragraph with a style that the TOC will pick up as an entry. + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + + // Both these strings are in the same paragraph and will therefore show up on the same TOC entry. + builder.write("Heading 1. "); + builder.write("Will appear in the TOC. "); + + // If we insert a style separator, we can write more text in the same paragraph + // and use a different style without showing up in the TOC. + // If we use a heading type style after the separator, we can draw multiple TOC entries from one document text line. + builder.insertStyleSeparator(); + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.QUOTE); + builder.write("Won't appear in the TOC. "); + + Assert.assertTrue(doc.getFirstSection().getBody().getFirstParagraph().getBreakIsStyleSeparator()); + + doc.updateFields(); + doc.save(getArtifactsDir() + "Paragraph.BreakIsStyleSeparator.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Paragraph.BreakIsStyleSeparator.docx"); + + TestUtil.verifyField(FieldType.FIELD_TOC, "TOC \\o \\h \\z \\u", + "\u0013 HYPERLINK \\l \"_Toc256000000\" \u0014Heading 1. Will appear in the TOC.\t\u0013 PAGEREF _Toc256000000 \\h \u00142\u0015\u0015\r", doc.getRange().getFields().get(0)); + Assert.assertFalse(doc.getFirstSection().getBody().getFirstParagraph().getBreakIsStyleSeparator()); + } + + @Test + public void tabStops() throws Exception + { + //ExStart + //ExFor:TabLeader + //ExFor:TabAlignment + //ExFor:Paragraph.GetEffectiveTabStops + //ExSummary:Shows how to set custom tab stops for a paragraph. + Document doc = new Document(); + Paragraph para = doc.getFirstSection().getBody().getFirstParagraph(); + + // If we are in a paragraph with no tab stops in this collection, + // the cursor will jump 36 points each time we press the Tab key in Microsoft Word. + Assert.assertEquals(0, doc.getFirstSection().getBody().getFirstParagraph().getEffectiveTabStops().length); + + // We can add custom tab stops in Microsoft Word if we enable the ruler via the "View" tab. + // Each unit on this ruler is two default tab stops, which is 72 points. + // We can add custom tab stops programmatically like this. + TabStopCollection tabStops = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat().getTabStops(); + tabStops.add(72.0, TabAlignment.LEFT, TabLeader.DOTS); + tabStops.add(216.0, TabAlignment.CENTER, TabLeader.DASHES); + tabStops.add(360.0, TabAlignment.RIGHT, TabLeader.LINE); + + // We can see these tab stops in Microsoft Word by enabling the ruler via "View" -> "Show" -> "Ruler". + Assert.assertEquals(3, para.getEffectiveTabStops().length); + + // Any tab characters we add will make use of the tab stops on the ruler and may, + // depending on the tab leader's value, leave a line between the tab departure and arrival destinations. + para.appendChild(new Run(doc, "\tTab 1\tTab 2\tTab 3")); + + doc.save(getArtifactsDir() + "Paragraph.TabStops.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Paragraph.TabStops.docx"); + tabStops = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat().getTabStops(); + + TestUtil.verifyTabStop(72.0d, TabAlignment.LEFT, TabLeader.DOTS, false, tabStops.get(0)); + TestUtil.verifyTabStop(216.0d, TabAlignment.CENTER, TabLeader.DASHES, false, tabStops.get(1)); + TestUtil.verifyTabStop(360.0d, TabAlignment.RIGHT, TabLeader.LINE, false, tabStops.get(2)); + } + + @Test + public void joinRuns() throws Exception + { + //ExStart + //ExFor:Paragraph.JoinRunsWithSameFormatting + //ExSummary:Shows how to simplify paragraphs by merging superfluous runs. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert four runs of text into the paragraph. + builder.write("Run 1. "); + builder.write("Run 2. "); + builder.write("Run 3. "); + builder.write("Run 4. "); + + // If we open this document in Microsoft Word, the paragraph will look like one seamless text body. + // However, it will consist of four separate runs with the same formatting. Fragmented paragraphs like this + // may occur when we manually edit parts of one paragraph many times in Microsoft Word. + Paragraph para = builder.getCurrentParagraph(); + + Assert.assertEquals(4, para.getRuns().getCount()); + + // Change the style of the last run to set it apart from the first three. + para.getRuns().get(3).getFont().setStyleIdentifier(StyleIdentifier.EMPHASIS); + + // We can run the "JoinRunsWithSameFormatting" method to optimize the document's contents + // by merging similar runs into one, reducing their overall count. + // This method also returns the number of runs that this method merged. + // These two merges occurred to combine Runs #1, #2, and #3, + // while leaving out Run #4 because it has an incompatible style. + Assert.assertEquals(2, para.joinRunsWithSameFormatting()); + + // The number of runs left will equal the original count + // minus the number of run merges that the "JoinRunsWithSameFormatting" method carried out. + Assert.assertEquals(2, para.getRuns().getCount()); + Assert.assertEquals("Run 1. Run 2. Run 3. ", para.getRuns().get(0).getText()); + Assert.assertEquals("Run 4. ", para.getRuns().get(1).getText()); + //ExEnd + } +} diff --git a/Examples/ApiExamples/JavaPorting/ExParagraphFormat.java b/Examples/ApiExamples/JavaPorting/ExParagraphFormat.java new file mode 100644 index 00000000..064ee539 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExParagraphFormat.java @@ -0,0 +1,640 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.ParagraphFormat; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.DropCapPosition; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.LineSpacingRule; +import com.aspose.words.ParagraphCollection; +import com.aspose.words.Paragraph; +import com.aspose.words.OutlineLevel; +import com.aspose.words.LayoutCollector; +import com.aspose.words.Hyphenation; +import com.aspose.words.BaselineAlignment; +import org.testng.annotations.DataProvider; + + +@Test +class ExParagraphFormat !Test class should be public in Java to run, please fix .Net source! extends ApiExampleBase +{ + @Test + public void asianTypographyProperties() throws Exception + { + //ExStart + //ExFor:ParagraphFormat.FarEastLineBreakControl + //ExFor:ParagraphFormat.WordWrap + //ExFor:ParagraphFormat.HangingPunctuation + //ExSummary:Shows how to set special properties for Asian typography. + Document doc = new Document(getMyDir() + "Document.docx"); + + ParagraphFormat format = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat(); + format.setFarEastLineBreakControl(true); + format.setWordWrap(false); + format.setHangingPunctuation(true); + + doc.save(getArtifactsDir() + "ParagraphFormat.AsianTypographyProperties.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "ParagraphFormat.AsianTypographyProperties.docx"); + format = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat(); + + Assert.assertTrue(format.getFarEastLineBreakControl()); + Assert.assertFalse(format.getWordWrap()); + Assert.assertTrue(format.getHangingPunctuation()); + } + + @Test (dataProvider = "dropCapDataProvider") + public void dropCap(/*DropCapPosition*/int dropCapPosition) throws Exception + { + //ExStart + //ExFor:DropCapPosition + //ExSummary:Shows how to create a drop cap. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert one paragraph with a large letter that the text in the second and third paragraphs begins with. + builder.getFont().setSize(54.0); + builder.writeln("L"); + + builder.getFont().setSize(18.0); + builder.writeln("orem ipsum dolor sit amet, consectetur adipiscing elit, " + + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "); + builder.writeln("Ut enim ad minim veniam, quis nostrud exercitation " + + "ullamco laboris nisi ut aliquip ex ea commodo consequat."); + + // Currently, the second and third paragraphs will appear underneath the first. + // We can convert the first paragraph as a drop cap for the other paragraphs via its "ParagraphFormat" object. + // Set the "DropCapPosition" property to "DropCapPosition.Margin" to place the drop cap + // outside the left-hand side page margin if our text is left-to-right. + // Set the "DropCapPosition" property to "DropCapPosition.Normal" to place the drop cap within the page margins + // and to wrap the rest of the text around it. + // "DropCapPosition.None" is the default state for all paragraphs. + ParagraphFormat format = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat(); + format.setDropCapPosition(dropCapPosition); + + doc.save(getArtifactsDir() + "ParagraphFormat.DropCap.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "ParagraphFormat.DropCap.docx"); + + Assert.assertEquals(dropCapPosition, doc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat().getDropCapPosition()); + Assert.assertEquals(DropCapPosition.NONE, doc.getFirstSection().getBody().getParagraphs().get(1).getParagraphFormat().getDropCapPosition()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "dropCapDataProvider") + public static Object[][] dropCapDataProvider() throws Exception + { + return new Object[][] + { + {DropCapPosition.MARGIN}, + {DropCapPosition.NORMAL}, + {DropCapPosition.NONE}, + }; + } + + @Test + public void lineSpacing() throws Exception + { + //ExStart + //ExFor:ParagraphFormat.LineSpacing + //ExFor:ParagraphFormat.LineSpacingRule + //ExFor:LineSpacingRule + //ExSummary:Shows how to work with line spacing. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are three line spacing rules that we can define using the + // paragraph's "LineSpacingRule" property to configure spacing between paragraphs. + // 1 - Set a minimum amount of spacing. + // This will give vertical padding to lines of text of any size + // that is too small to maintain the minimum line-height. + builder.getParagraphFormat().setLineSpacingRule(LineSpacingRule.AT_LEAST); + builder.getParagraphFormat().setLineSpacing(20.0); + + builder.writeln("Minimum line spacing of 20."); + builder.writeln("Minimum line spacing of 20."); + + // 2 - Set exact spacing. + // Using font sizes that are too large for the spacing will truncate the text. + builder.getParagraphFormat().setLineSpacingRule(LineSpacingRule.EXACTLY); + builder.getParagraphFormat().setLineSpacing(5.0); + + builder.writeln("Line spacing of exactly 5."); + builder.writeln("Line spacing of exactly 5."); + + // 3 - Set spacing as a multiple of default line spacing, which is 12 points by default. + // This kind of spacing will scale to different font sizes. + builder.getParagraphFormat().setLineSpacingRule(LineSpacingRule.MULTIPLE); + builder.getParagraphFormat().setLineSpacing(18.0); + + builder.writeln("Line spacing of 1.5 default lines."); + builder.writeln("Line spacing of 1.5 default lines."); + + doc.save(getArtifactsDir() + "ParagraphFormat.LineSpacing.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "ParagraphFormat.LineSpacing.docx"); + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + Assert.assertEquals(LineSpacingRule.AT_LEAST, paragraphs.get(0).getParagraphFormat().getLineSpacingRule()); + Assert.assertEquals(20.0d, paragraphs.get(0).getParagraphFormat().getLineSpacing()); + Assert.assertEquals(LineSpacingRule.AT_LEAST, paragraphs.get(1).getParagraphFormat().getLineSpacingRule()); + Assert.assertEquals(20.0d, paragraphs.get(1).getParagraphFormat().getLineSpacing()); + + Assert.assertEquals(LineSpacingRule.EXACTLY, paragraphs.get(2).getParagraphFormat().getLineSpacingRule()); + Assert.assertEquals(5.0d, paragraphs.get(2).getParagraphFormat().getLineSpacing()); + Assert.assertEquals(LineSpacingRule.EXACTLY, paragraphs.get(3).getParagraphFormat().getLineSpacingRule()); + Assert.assertEquals(5.0d, paragraphs.get(3).getParagraphFormat().getLineSpacing()); + + Assert.assertEquals(LineSpacingRule.MULTIPLE, paragraphs.get(4).getParagraphFormat().getLineSpacingRule()); + Assert.assertEquals(18.0d, paragraphs.get(4).getParagraphFormat().getLineSpacing()); + Assert.assertEquals(LineSpacingRule.MULTIPLE, paragraphs.get(5).getParagraphFormat().getLineSpacingRule()); + Assert.assertEquals(18.0d, paragraphs.get(5).getParagraphFormat().getLineSpacing()); + } + + @Test (dataProvider = "paragraphSpacingAutoDataProvider") + public void paragraphSpacingAuto(boolean autoSpacing) throws Exception + { + //ExStart + //ExFor:ParagraphFormat.SpaceAfter + //ExFor:ParagraphFormat.SpaceAfterAuto + //ExFor:ParagraphFormat.SpaceBefore + //ExFor:ParagraphFormat.SpaceBeforeAuto + //ExSummary:Shows how to set automatic paragraph spacing. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Apply a large amount of spacing before and after paragraphs that this builder will create. + builder.getParagraphFormat().setSpaceBefore(24.0); + builder.getParagraphFormat().setSpaceAfter(24.0); + + // Set these flags to "true" to apply automatic spacing, + // effectively ignoring the spacing in the properties we set above. + // Leave them as "false" will apply our custom paragraph spacing. + builder.getParagraphFormat().setSpaceAfterAuto(autoSpacing); + builder.getParagraphFormat().setSpaceBeforeAuto(autoSpacing); + + // Insert two paragraphs that will have spacing above and below them and save the document. + builder.writeln("Paragraph 1."); + builder.writeln("Paragraph 2."); + + doc.save(getArtifactsDir() + "ParagraphFormat.ParagraphSpacingAuto.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "ParagraphFormat.ParagraphSpacingAuto.docx"); + ParagraphFormat format = doc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat(); + + Assert.assertEquals(24.0d, format.getSpaceBefore()); + Assert.assertEquals(24.0d, format.getSpaceAfter()); + Assert.assertEquals(autoSpacing, format.getSpaceAfterAuto()); + Assert.assertEquals(autoSpacing, format.getSpaceBeforeAuto()); + + format = doc.getFirstSection().getBody().getParagraphs().get(1).getParagraphFormat(); + + Assert.assertEquals(24.0d, format.getSpaceBefore()); + Assert.assertEquals(24.0d, format.getSpaceAfter()); + Assert.assertEquals(autoSpacing, format.getSpaceAfterAuto()); + Assert.assertEquals(autoSpacing, format.getSpaceBeforeAuto()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "paragraphSpacingAutoDataProvider") + public static Object[][] paragraphSpacingAutoDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "paragraphSpacingSameStyleDataProvider") + public void paragraphSpacingSameStyle(boolean noSpaceBetweenParagraphsOfSameStyle) throws Exception + { + //ExStart + //ExFor:ParagraphFormat.SpaceAfter + //ExFor:ParagraphFormat.SpaceBefore + //ExFor:ParagraphFormat.NoSpaceBetweenParagraphsOfSameStyle + //ExSummary:Shows how to apply no spacing between paragraphs with the same style. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Apply a large amount of spacing before and after paragraphs that this builder will create. + builder.getParagraphFormat().setSpaceBefore(24.0); + builder.getParagraphFormat().setSpaceAfter(24.0); + + // Set the "NoSpaceBetweenParagraphsOfSameStyle" flag to "true" to apply + // no spacing between paragraphs with the same style, which will group similar paragraphs. + // Leave the "NoSpaceBetweenParagraphsOfSameStyle" flag as "false" + // to evenly apply spacing to every paragraph. + builder.getParagraphFormat().setNoSpaceBetweenParagraphsOfSameStyle(noSpaceBetweenParagraphsOfSameStyle); + + builder.getParagraphFormat().setStyle(doc.getStyles().get("Normal")); + builder.writeln($"Paragraph in the \"{builder.ParagraphFormat.Style.Name}\" style."); + builder.writeln($"Paragraph in the \"{builder.ParagraphFormat.Style.Name}\" style."); + builder.writeln($"Paragraph in the \"{builder.ParagraphFormat.Style.Name}\" style."); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Quote")); + builder.writeln($"Paragraph in the \"{builder.ParagraphFormat.Style.Name}\" style."); + builder.writeln($"Paragraph in the \"{builder.ParagraphFormat.Style.Name}\" style."); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Normal")); + builder.writeln($"Paragraph in the \"{builder.ParagraphFormat.Style.Name}\" style."); + builder.writeln($"Paragraph in the \"{builder.ParagraphFormat.Style.Name}\" style."); + + doc.save(getArtifactsDir() + "ParagraphFormat.ParagraphSpacingSameStyle.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "ParagraphFormat.ParagraphSpacingSameStyle.docx"); + + for (Paragraph paragraph : (Iterable) doc.getFirstSection().getBody().getParagraphs()) + { + ParagraphFormat format = paragraph.getParagraphFormat(); + + Assert.assertEquals(24.0d, format.getSpaceBefore()); + Assert.assertEquals(24.0d, format.getSpaceAfter()); + Assert.assertEquals(noSpaceBetweenParagraphsOfSameStyle, format.getNoSpaceBetweenParagraphsOfSameStyle()); + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "paragraphSpacingSameStyleDataProvider") + public static Object[][] paragraphSpacingSameStyleDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void paragraphOutlineLevel() throws Exception + { + //ExStart + //ExFor:ParagraphFormat.OutlineLevel + //ExFor:OutlineLevel + //ExSummary:Shows how to configure paragraph outline levels to create collapsible text. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Each paragraph has an OutlineLevel, which could be any number from 1 to 9, or at the default "BodyText" value. + // Setting the property to one of the numbered values will show an arrow to the left + // of the beginning of the paragraph. + builder.getParagraphFormat().setOutlineLevel(OutlineLevel.LEVEL_1); + builder.writeln("Paragraph outline level 1."); + + // Level 1 is the topmost level. If there is a paragraph with a lower level below a paragraph with a higher level, + // collapsing the higher-level paragraph will collapse the lower level paragraph. + builder.getParagraphFormat().setOutlineLevel(OutlineLevel.LEVEL_2); + builder.writeln("Paragraph outline level 2."); + + // Two paragraphs of the same level will not collapse each other, + // and the arrows do not collapse the paragraphs they point to. + builder.getParagraphFormat().setOutlineLevel(OutlineLevel.LEVEL_3); + builder.writeln("Paragraph outline level 3."); + builder.writeln("Paragraph outline level 3."); + + // The default "BodyText" value is the lowest, which a paragraph of any level can collapse. + builder.getParagraphFormat().setOutlineLevel(OutlineLevel.BODY_TEXT); + builder.writeln("Paragraph at main text level."); + + doc.save(getArtifactsDir() + "ParagraphFormat.ParagraphOutlineLevel.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "ParagraphFormat.ParagraphOutlineLevel.docx"); + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + Assert.assertEquals(OutlineLevel.LEVEL_1, paragraphs.get(0).getParagraphFormat().getOutlineLevel()); + Assert.assertEquals(OutlineLevel.LEVEL_2, paragraphs.get(1).getParagraphFormat().getOutlineLevel()); + Assert.assertEquals(OutlineLevel.LEVEL_3, paragraphs.get(2).getParagraphFormat().getOutlineLevel()); + Assert.assertEquals(OutlineLevel.LEVEL_3, paragraphs.get(3).getParagraphFormat().getOutlineLevel()); + Assert.assertEquals(OutlineLevel.BODY_TEXT, paragraphs.get(4).getParagraphFormat().getOutlineLevel()); + } + + @Test (dataProvider = "pageBreakBeforeDataProvider") + public void pageBreakBefore(boolean pageBreakBefore) throws Exception + { + //ExStart + //ExFor:ParagraphFormat.PageBreakBefore + //ExSummary:Shows how to create paragraphs with page breaks at the beginning. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Set this flag to "true" to apply a page break to each paragraph's beginning + // that the document builder will create under this ParagraphFormat configuration. + // The first paragraph will not receive a page break. + // Leave this flag as "false" to start each new paragraph on the same page + // as the previous, provided there is sufficient space. + builder.getParagraphFormat().setPageBreakBefore(pageBreakBefore); + + builder.writeln("Paragraph 1."); + builder.writeln("Paragraph 2."); + + LayoutCollector layoutCollector = new LayoutCollector(doc); + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + if (pageBreakBefore) + { + Assert.assertEquals(1, layoutCollector.getStartPageIndex(paragraphs.get(0))); + Assert.assertEquals(2, layoutCollector.getStartPageIndex(paragraphs.get(1))); + } + else + { + Assert.assertEquals(1, layoutCollector.getStartPageIndex(paragraphs.get(0))); + Assert.assertEquals(1, layoutCollector.getStartPageIndex(paragraphs.get(1))); + } + + doc.save(getArtifactsDir() + "ParagraphFormat.PageBreakBefore.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "ParagraphFormat.PageBreakBefore.docx"); + paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + Assert.assertEquals(pageBreakBefore, paragraphs.get(0).getParagraphFormat().getPageBreakBefore()); + Assert.assertEquals(pageBreakBefore, paragraphs.get(1).getParagraphFormat().getPageBreakBefore()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "pageBreakBeforeDataProvider") + public static Object[][] pageBreakBeforeDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "widowControlDataProvider") + public void widowControl(boolean widowControl) throws Exception + { + //ExStart + //ExFor:ParagraphFormat.WidowControl + //ExSummary:Shows how to enable widow/orphan control for a paragraph. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // When we write the text that does not fit onto one page, one line may spill over onto the next page. + // The single line that ends up on the next page is called an "Orphan", + // and the previous line where the orphan broke off is called a "Widow". + // We can fix orphans and widows by rearranging text via font size, spacing, or page margins. + // If we wish to preserve our document's dimensions, we can set this flag to "true" + // to push widows onto the same page as their respective orphans. + // Leave this flag as "false" will leave widow/orphan pairs in text. + // Every paragraph has this setting accessible in Microsoft Word via Home -> Paragraph -> Paragraph Settings + // (button on bottom right hand corner of "Paragraph" tab) -> "Widow/Orphan control". + builder.getParagraphFormat().setWidowControl(widowControl); + + // Insert text that produces an orphan and a widow. + builder.getFont().setSize(68.0); + builder.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + + doc.save(getArtifactsDir() + "ParagraphFormat.WidowControl.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "ParagraphFormat.WidowControl.docx"); + + Assert.assertEquals(widowControl, doc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat().getWidowControl()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "widowControlDataProvider") + public static Object[][] widowControlDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void linesToDrop() throws Exception + { + //ExStart + //ExFor:ParagraphFormat.LinesToDrop + //ExSummary:Shows how to set the size of a drop cap. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Modify the "LinesToDrop" property to designate a paragraph as a drop cap, + // which will turn it into a large capital letter that will decorate the next paragraph. + // Give this property a value of 4 to give the drop cap the height of four text lines. + builder.getParagraphFormat().setLinesToDrop(4); + builder.writeln("H"); + + // Reset the "LinesToDrop" property to 0 to turn the next paragraph into an ordinary paragraph. + // The text in this paragraph will wrap around the drop cap. + builder.getParagraphFormat().setLinesToDrop(0); + builder.writeln("ello world!"); + + doc.save(getArtifactsDir() + "ParagraphFormat.LinesToDrop.odt"); + //ExEnd + + doc = new Document(getArtifactsDir() + "ParagraphFormat.LinesToDrop.odt"); + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + Assert.assertEquals(4, paragraphs.get(0).getParagraphFormat().getLinesToDrop()); + Assert.assertEquals(0, paragraphs.get(1).getParagraphFormat().getLinesToDrop()); + } + + @Test (dataProvider = "suppressHyphensDataProvider") + public void suppressHyphens(boolean suppressAutoHyphens) throws Exception + { + //ExStart + //ExFor:ParagraphFormat.SuppressAutoHyphens + //ExSummary:Shows how to suppress hyphenation for a paragraph. + Hyphenation.registerDictionary("de-CH", getMyDir() + "hyph_de_CH.dic"); + + Assert.assertTrue(Hyphenation.isDictionaryRegistered("de-CH")); + + // Open a document containing text with a locale matching that of our dictionary. + // When we save this document to a fixed page save format, its text will have hyphenation. + Document doc = new Document(getMyDir() + "German text.docx"); + + // We can set the "SuppressAutoHyphens" property to "true" to disable hyphenation + // for a specific paragraph while keeping it enabled for the rest of the document. + // The default value for this property is "false", + // which means every paragraph by default uses hyphenation if any is available. + doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat().setSuppressAutoHyphens(suppressAutoHyphens); + + doc.save(getArtifactsDir() + "ParagraphFormat.SuppressHyphens.pdf"); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "suppressHyphensDataProvider") + public static Object[][] suppressHyphensDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "usePdfDocumentForSuppressHyphensDataProvider") + public void usePdfDocumentForSuppressHyphens(boolean suppressAutoHyphens) throws Exception + { + final String UNICODE_OPTIONAL_HYPHEN = "\u00ad"; + + suppressHyphens(suppressAutoHyphens); + + Aspose.Pdf.Document pdfDoc = new Aspose.Pdf.Document(getArtifactsDir() + "ParagraphFormat.SuppressHyphens.pdf"); + TextAbsorber textAbsorber = new TextAbsorber(); + textAbsorber.Visit(pdfDoc); + + if (suppressAutoHyphens) + Assert.That(textAbsorber.Text.Replace(" ", " ").Contains($"La ob storen an deinen am sachen. {Environment.NewLine}" + + $"Doppelte um da am spateren verlogen {Environment.NewLine}" + + $"gekommen achtzehn blaulich."), assertTrue(); + else + Assert.That(textAbsorber.Text.Replace(" ", " ").Contains($"La ob storen an deinen am sachen. Dop{unicodeOptionalHyphen}{Environment.NewLine}" + + $"pelte um da am spateren verlogen ge{unicodeOptionalHyphen}{Environment.NewLine}" + + $"kommen achtzehn blaulich."), assertTrue(); + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForSuppressHyphensDataProvider") + public static Object[][] usePdfDocumentForSuppressHyphensDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void paragraphSpacingAndIndents() throws Exception + { + //ExStart + //ExFor:ParagraphFormat.CharacterUnitLeftIndent + //ExFor:ParagraphFormat.CharacterUnitRightIndent + //ExFor:ParagraphFormat.CharacterUnitFirstLineIndent + //ExFor:ParagraphFormat.LineUnitBefore + //ExFor:ParagraphFormat.LineUnitAfter + //ExSummary:Shows how to change paragraph spacing and indents. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + ParagraphFormat format = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat(); + + // Below are five different spacing options, along with the properties that their configuration indirectly affects. + // 1 - Left indent: + Assert.assertEquals(format.getLeftIndent(), 0.0d); + + format.setCharacterUnitLeftIndent(10.0); + + Assert.assertEquals(format.getLeftIndent(), 120.0d); + + // 2 - Right indent: + Assert.assertEquals(format.getRightIndent(), 0.0d); + + format.setCharacterUnitRightIndent(-5.5); + + Assert.assertEquals(format.getRightIndent(), -66.0d); + + // 3 - Hanging indent: + Assert.assertEquals(format.getFirstLineIndent(), 0.0d); + + format.setCharacterUnitFirstLineIndent(20.3); + + Assert.assertEquals(format.getFirstLineIndent(), 0.1d, 243.59d); + + // 4 - Line spacing before paragraphs: + Assert.assertEquals(format.getSpaceBefore(), 0.0d); + + format.setLineUnitBefore(5.1); + + Assert.assertEquals(format.getSpaceBefore(), 0.1d, 61.1d); + + // 5 - Line spacing after paragraphs: + Assert.assertEquals(format.getSpaceAfter(), 0.0d); + + format.setLineUnitAfter(10.9); + + Assert.assertEquals(format.getSpaceAfter(), 0.1d, 130.8d); + + builder.writeln("Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + builder.write("测试文档测试文档测试文档测试文档测试文档测试文档测试文档测试文档测试" + + "文档测试文档测试文档测试文档测试文档测试文档测试文档测试文档测试文档测试文档"); + //ExEnd + + doc = DocumentHelper.saveOpen(doc); + format = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat(); + + Assert.assertEquals(format.getCharacterUnitLeftIndent(), 10.0d); + Assert.assertEquals(format.getLeftIndent(), 120.0d); + + Assert.assertEquals(format.getCharacterUnitRightIndent(), -5.5d); + Assert.assertEquals(format.getRightIndent(), -66.0d); + + Assert.assertEquals(format.getCharacterUnitFirstLineIndent(), 20.3d); + Assert.assertEquals(format.getFirstLineIndent(), 0.1d, 243.59d); + + Assert.assertEquals(format.getLineUnitBefore(), 0.1d, 5.1d); + Assert.assertEquals(format.getSpaceBefore(), 0.1d, 61.1d); + + Assert.assertEquals(format.getLineUnitAfter(), 10.9d); + Assert.assertEquals(format.getSpaceAfter(), 0.1d, 130.8d); + } + + @Test + public void paragraphBaselineAlignment() throws Exception + { + //ExStart + //ExFor:BaselineAlignment + //ExFor:ParagraphFormat.BaselineAlignment + //ExSummary:Shows how to set fonts vertical position on a line. + Document doc = new Document(getMyDir() + "Office math.docx"); + + ParagraphFormat format = doc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat(); + if (format.getBaselineAlignment() == BaselineAlignment.AUTO) + { + format.setBaselineAlignment(BaselineAlignment.TOP); + } + + doc.save(getArtifactsDir() + "ParagraphFormat.ParagraphBaselineAlignment.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "ParagraphFormat.ParagraphBaselineAlignment.docx"); + format = doc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat(); + Assert.assertEquals(BaselineAlignment.TOP, format.getBaselineAlignment()); + } + + @Test + public void mirrorIndents() throws Exception + { + //ExStart:MirrorIndents + //GistId:5f20ac02cb42c6b08481aa1c5b0cd3db + //ExFor:ParagraphFormat.MirrorIndents + //ExSummary:Show how to make left and right indents the same. + Document doc = new Document(getMyDir() + "Document.docx"); + ParagraphFormat format = doc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat(); + + format.setMirrorIndents(true); + + doc.save(getArtifactsDir() + "ParagraphFormat.MirrorIndents.docx"); + //ExEnd:MirrorIndents + + doc = new Document(getArtifactsDir() + "ParagraphFormat.MirrorIndents.docx"); + format = doc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat(); + + Assert.assertEquals(true, format.getMirrorIndents()); + } +} + diff --git a/Examples/ApiExamples/JavaPorting/ExPclSaveOptions.java b/Examples/ApiExamples/JavaPorting/ExPclSaveOptions.java new file mode 100644 index 00000000..595b0157 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExPclSaveOptions.java @@ -0,0 +1,100 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.PclSaveOptions; +import com.aspose.words.SaveFormat; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.Section; + + +@Test +class ExPclSaveOptions !Test class should be public in Java to run, please fix .Net source! extends ApiExampleBase +{ + @Test + public void rasterizeElements() throws Exception + { + //ExStart + //ExFor:PclSaveOptions + //ExFor:PclSaveOptions.SaveFormat + //ExFor:PclSaveOptions.RasterizeTransformedElements + //ExSummary:Shows how to rasterize complex elements while saving a document to PCL. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PclSaveOptions saveOptions = new PclSaveOptions(); + { + saveOptions.setSaveFormat(SaveFormat.PCL); + saveOptions.setRasterizeTransformedElements(true); + } + + doc.save(getArtifactsDir() + "PclSaveOptions.RasterizeElements.pcl", saveOptions); + //ExEnd + } + + @Test + public void fallbackFontName() throws Exception + { + //ExStart + //ExFor:PclSaveOptions.FallbackFontName + //ExSummary:Shows how to declare a font that a printer will apply to printed text as a substitute should its original font be unavailable. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Non-existent font"); + builder.write("Hello world!"); + + PclSaveOptions saveOptions = new PclSaveOptions(); + saveOptions.setFallbackFontName("Times New Roman"); + + // This document will instruct the printer to apply "Times New Roman" to the text with the missing font. + // Should "Times New Roman" also be unavailable, the printer will default to the "Arial" font. + doc.save(getArtifactsDir() + "PclSaveOptions.SetPrinterFont.pcl", saveOptions); + //ExEnd + } + + @Test + public void addPrinterFont() throws Exception + { + //ExStart + //ExFor:PclSaveOptions.AddPrinterFont(string, string) + //ExSummary:Shows how to get a printer to substitute all instances of a specific font with a different font. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Courier"); + builder.write("Hello world!"); + + PclSaveOptions saveOptions = new PclSaveOptions(); + saveOptions.addPrinterFont("Courier New", "Courier"); + + // When printing this document, the printer will use the "Courier New" font + // to access places where our document used the "Courier" font. + doc.save(getArtifactsDir() + "PclSaveOptions.AddPrinterFont.pcl", saveOptions); + //ExEnd + } + + @Test (description = "This test is a manual check that PaperTray information is preserved in the output pcl document.") + public void getPreservedPaperTrayInformation() throws Exception + { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // Paper tray information is now preserved when saving document to PCL format. + // Following information is transferred from document's model to PCL file. + for (Section section : (Iterable
          ) doc.getSections()) + { + section.getPageSetup().setFirstPageTray(15); + section.getPageSetup().setOtherPagesTray(12); + } + + doc.save(getArtifactsDir() + "PclSaveOptions.GetPreservedPaperTrayInformation.pcl"); + } +} diff --git a/Examples/ApiExamples/JavaPorting/ExPdfLoadOptions.java b/Examples/ApiExamples/JavaPorting/ExPdfLoadOptions.java new file mode 100644 index 00000000..d7abe83d --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExPdfLoadOptions.java @@ -0,0 +1,60 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.PdfLoadOptions; +import com.aspose.words.Document; +import com.aspose.words.NodeCollection; +import com.aspose.words.NodeType; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import org.testng.annotations.DataProvider; + + +@Test +class ExPdfLoadOptions !Test class should be public in Java to run, please fix .Net source! extends ApiExampleBase +{ + @Test (dataProvider = "skipPdfImagesDataProvider") + public void skipPdfImages(boolean isSkipPdfImages) throws Exception + { + //ExStart + //ExFor:PdfLoadOptions + //ExFor:PdfLoadOptions.SkipPdfImages + //ExFor:PdfLoadOptions.PageIndex + //ExFor:PdfLoadOptions.PageCount + //ExSummary:Shows how to skip images during loading PDF files. + PdfLoadOptions options = new PdfLoadOptions(); + options.setSkipPdfImages(isSkipPdfImages); + options.setPageIndex(0); + options.setPageCount(1); + + Document doc = new Document(getMyDir() + "Images.pdf", options); + NodeCollection shapeCollection = doc.getChildNodes(NodeType.SHAPE, true); + + if (isSkipPdfImages) + Assert.assertEquals(shapeCollection.getCount(), 0); + else + Assert.Is.Not.EqualTo(shapeCollection.getCount())0); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "skipPdfImagesDataProvider") + public static Object[][] skipPdfImagesDataProvider() throws Exception + { + return new Object[][] + { + {true}, + {false}, + }; + } +} + diff --git a/Examples/ApiExamples/JavaPorting/ExPdfSaveOptions.java b/Examples/ApiExamples/JavaPorting/ExPdfSaveOptions.java new file mode 100644 index 00000000..266767d6 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExPdfSaveOptions.java @@ -0,0 +1,3270 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import com.aspose.ms.System.ms; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.BreakType; +import com.aspose.ms.System.IO.Stream; +import com.aspose.ms.System.IO.File; +import com.aspose.words.PdfSaveOptions; +import com.aspose.words.PageSet; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.StyleIdentifier; +import com.aspose.words.SaveFormat; +import com.aspose.words.PdfCompliance; +import com.aspose.words.PdfTextCompression; +import com.aspose.ms.System.IO.FileInfo; +import com.aspose.words.PdfImageCompression; +import com.aspose.ms.System.IO.FileStream; +import com.aspose.ms.System.IO.FileMode; +import com.aspose.words.PdfImageColorSpaceExportMode; +import com.aspose.words.ColorMode; +import com.aspose.words.SaveOptions; +import com.aspose.words.MetafileRenderingOptions; +import com.aspose.words.MetafileRenderingMode; +import com.aspose.words.IWarningCallback; +import com.aspose.words.WarningInfo; +import com.aspose.words.WarningType; +import com.aspose.ms.System.msConsole; +import com.aspose.words.WarningInfoCollection; +import com.aspose.words.HeaderFooterBookmarksExportMode; +import com.aspose.words.PdfPageMode; +import com.aspose.ms.System.Globalization.msCultureInfo; +import com.aspose.words.FontSourceBase; +import com.aspose.words.FontSettings; +import com.aspose.words.FolderFontSource; +import com.aspose.words.PdfFontEmbeddingMode; +import com.aspose.words.Section; +import com.aspose.words.MultiplePagesType; +import com.aspose.ms.System.StringComparison; +import com.aspose.words.PdfZoomBehavior; +import java.util.ArrayList; +import com.aspose.words.PdfCustomPropertiesExport; +import com.aspose.words.DmlEffectsRenderingMode; +import com.aspose.words.DmlRenderingMode; +import com.aspose.ms.System.IO.MemoryStream; +import com.aspose.words.Dml3DEffectsRenderingMode; +import com.aspose.words.WarningSource; +import com.aspose.words.CertificateHolder; +import com.aspose.ms.System.DateTime; +import com.aspose.words.PdfDigitalSignatureDetails; +import com.aspose.words.PdfDigitalSignatureHashAlgorithm; +import com.aspose.words.FileFormatUtil; +import java.util.Date; +import com.aspose.words.PdfDigitalSignatureTimestampSettings; +import com.aspose.ms.System.TimeSpan; +import com.aspose.words.EmfPlusDualRenderingMode; +import com.aspose.words.PdfEncryptionDetails; +import com.aspose.words.PdfPermissions; +import com.aspose.words.NumeralFormat; +import com.aspose.words.PdfAttachmentsEmbeddingMode; +import com.aspose.words.PdfPageLayout; +import org.testng.annotations.DataProvider; + + +@Test +class ExPdfSaveOptions !Test class should be public in Java to run, please fix .Net source! extends ApiExampleBase +{ + @Test + public void onePage() throws Exception + { + //ExStart + //ExFor:FixedPageSaveOptions.PageSet + //ExFor:Document.Save(Stream, SaveOptions) + //ExSummary:Shows how to convert only some of the pages in a document to PDF. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Page 1."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 2."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 3."); + + Stream stream = File.create(getArtifactsDir() + "PdfSaveOptions.OnePage.pdf"); + try /*JAVA: was using*/ + { + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "PageIndex" to "1" to render a portion of the document starting from the second page. + options.setPageSet(new PageSet(1)); + + // This document will contain one page starting from page two, which will only contain the second page. + doc.save(stream, options); + } + finally { if (stream != null) stream.close(); } + //ExEnd + } + + @Test + public void usePdfDocumentForOnePage() throws Exception + { + onePage(); + + Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.OnePage.pdf"); + + Assert.That(pdfDocument.Pages.Count, assertEquals(1, ); + + TextFragmentAbsorber textFragmentAbsorber = new TextFragmentAbsorber(); + pdfDocument.Pages.Accept(textFragmentAbsorber); + + Assert.That(textFragmentAbsorber.Text, assertEquals("Page 2.", ); + } + + @Test + public void headingsOutlineLevels() throws Exception + { + //ExStart + //ExFor:ParagraphFormat.IsHeading + //ExFor:PdfSaveOptions.OutlineOptions + //ExFor:PdfSaveOptions.SaveFormat + //ExSummary:Shows how to limit the headings' level that will appear in the outline of a saved PDF document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert headings that can serve as TOC entries of levels 1, 2, and then 3. + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + + Assert.assertTrue(builder.getParagraphFormat().isHeading()); + + builder.writeln("Heading 1"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); + + builder.writeln("Heading 1.1"); + builder.writeln("Heading 1.2"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_3); + + builder.writeln("Heading 1.2.1"); + builder.writeln("Heading 1.2.2"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setSaveFormat(SaveFormat.PDF); + + // The output PDF document will contain an outline, which is a table of contents that lists headings in the document body. + // Clicking on an entry in this outline will take us to the location of its respective heading. + // Set the "HeadingsOutlineLevels" property to "2" to exclude all headings whose levels are above 2 from the outline. + // The last two headings we have inserted above will not appear. + saveOptions.getOutlineOptions().setHeadingsOutlineLevels(2); + + doc.save(getArtifactsDir() + "PdfSaveOptions.HeadingsOutlineLevels.pdf", saveOptions); + //ExEnd + } + + @Test + public void usePdfBookmarkEditorForHeadingsOutlineLevels() throws Exception + { + headingsOutlineLevels(); + + PdfBookmarkEditor bookmarkEditor = new PdfBookmarkEditor(); + bookmarkEditor.BindPdf(getArtifactsDir() + "PdfSaveOptions.HeadingsOutlineLevels.pdf"); + + Bookmarks bookmarks = bookmarkEditor.ExtractBookmarks(); + + Assert.That(bookmarks.Count, assertEquals(3, ); + } + + @Test (dataProvider = "createMissingOutlineLevelsDataProvider") + public void createMissingOutlineLevels(boolean createMissingOutlineLevels) throws Exception + { + //ExStart + //ExFor:OutlineOptions.CreateMissingOutlineLevels + //ExFor:PdfSaveOptions.OutlineOptions + //ExSummary:Shows how to work with outline levels that do not contain any corresponding headings when saving a PDF document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert headings that can serve as TOC entries of levels 1 and 5. + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + + Assert.assertTrue(builder.getParagraphFormat().isHeading()); + + builder.writeln("Heading 1"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_5); + + builder.writeln("Heading 1.1.1.1.1"); + builder.writeln("Heading 1.1.1.1.2"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + + // The output PDF document will contain an outline, which is a table of contents that lists headings in the document body. + // Clicking on an entry in this outline will take us to the location of its respective heading. + // Set the "HeadingsOutlineLevels" property to "5" to include all headings of levels 5 and below in the outline. + saveOptions.getOutlineOptions().setHeadingsOutlineLevels(5); + + // This document contains headings of levels 1 and 5, and no headings with levels of 2, 3, and 4. + // The output PDF document will treat outline levels 2, 3, and 4 as "missing". + // Set the "CreateMissingOutlineLevels" property to "true" to include all missing levels in the outline, + // leaving blank outline entries since there are no usable headings. + // Set the "CreateMissingOutlineLevels" property to "false" to ignore missing outline levels, + // and treat the outline level 5 headings as level 2. + saveOptions.getOutlineOptions().setCreateMissingOutlineLevels(createMissingOutlineLevels); + + doc.save(getArtifactsDir() + "PdfSaveOptions.CreateMissingOutlineLevels.pdf", saveOptions); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "createMissingOutlineLevelsDataProvider") + public static Object[][] createMissingOutlineLevelsDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "usePdfBookmarkEditorForCreateMissingOutlineLevelsDataProvider") + public void usePdfBookmarkEditorForCreateMissingOutlineLevels(boolean createMissingOutlineLevels) throws Exception + { + createMissingOutlineLevels(createMissingOutlineLevels); + + PdfBookmarkEditor bookmarkEditor = new PdfBookmarkEditor(); + bookmarkEditor.BindPdf(getArtifactsDir() + "PdfSaveOptions.CreateMissingOutlineLevels.pdf"); + + Bookmarks bookmarks = bookmarkEditor.ExtractBookmarks(); + + Assert.That(bookmarks.Count, assertEquals(createMissingOutlineLevels ? 6 : 3, ); + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfBookmarkEditorForCreateMissingOutlineLevelsDataProvider") + public static Object[][] usePdfBookmarkEditorForCreateMissingOutlineLevelsDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "tableHeadingOutlinesDataProvider") + public void tableHeadingOutlines(boolean createOutlinesForHeadingsInTables) throws Exception + { + //ExStart + //ExFor:OutlineOptions.CreateOutlinesForHeadingsInTables + //ExSummary:Shows how to create PDF document outline entries for headings inside tables. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a table with three rows. The first row, + // whose text we will format in a heading-type style, will serve as the column header. + builder.startTable(); + builder.insertCell(); + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + builder.write("Customers"); + builder.endRow(); + builder.insertCell(); + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.NORMAL); + builder.write("John Doe"); + builder.endRow(); + builder.insertCell(); + builder.write("Jane Doe"); + builder.endTable(); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions pdfSaveOptions = new PdfSaveOptions(); + + // The output PDF document will contain an outline, which is a table of contents that lists headings in the document body. + // Clicking on an entry in this outline will take us to the location of its respective heading. + // Set the "HeadingsOutlineLevels" property to "1" to get the outline + // to only register headings with heading levels that are no larger than 1. + pdfSaveOptions.getOutlineOptions().setHeadingsOutlineLevels(1); + + // Set the "CreateOutlinesForHeadingsInTables" property to "false" to exclude all headings within tables, + // such as the one we have created above from the outline. + // Set the "CreateOutlinesForHeadingsInTables" property to "true" to include all headings within tables + // in the outline, provided that they have a heading level that is no larger than the value of the "HeadingsOutlineLevels" property. + pdfSaveOptions.getOutlineOptions().setCreateOutlinesForHeadingsInTables(createOutlinesForHeadingsInTables); + + doc.save(getArtifactsDir() + "PdfSaveOptions.TableHeadingOutlines.pdf", pdfSaveOptions); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "tableHeadingOutlinesDataProvider") + public static Object[][] tableHeadingOutlinesDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "usePdfDocumentForTableHeadingOutlinesDataProvider") + public void usePdfDocumentForTableHeadingOutlines(boolean createOutlinesForHeadingsInTables) throws Exception + { + tableHeadingOutlines(createOutlinesForHeadingsInTables); + + Aspose.Pdf.Document pdfDoc = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.TableHeadingOutlines.pdf"); + + if (createOutlinesForHeadingsInTables) + { + Assert.That(pdfDoc.Outlines.Count, assertEquals(1, ); + Assert.That(pdfDoc.Outlines[1].Title, assertEquals("Customers", ); + } + else + Assert.That(pdfDoc.Outlines.Count, assertEquals(0, ); + + TableAbsorber tableAbsorber = new TableAbsorber(); + tableAbsorber.Visit(pdfDoc.Pages[1]); + + Assert.That(tableAbsorber.TableList[0].RowList[0].CellList[0].TextFragments[1].Text, assertEquals("Customers", ); + Assert.That(tableAbsorber.TableList[0].RowList[1].CellList[0].TextFragments[1].Text, assertEquals("John Doe", ); + Assert.That(tableAbsorber.TableList[0].RowList[2].CellList[0].TextFragments[1].Text, assertEquals("Jane Doe", ); + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForTableHeadingOutlinesDataProvider") + public static Object[][] usePdfDocumentForTableHeadingOutlinesDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void expandedOutlineLevels() throws Exception + { + //ExStart + //ExFor:Document.Save(String, SaveOptions) + //ExFor:PdfSaveOptions + //ExFor:OutlineOptions.HeadingsOutlineLevels + //ExFor:OutlineOptions.ExpandedOutlineLevels + //ExSummary:Shows how to convert a whole document to PDF with three levels in the document outline. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert headings of levels 1 to 5. + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + + Assert.assertTrue(builder.getParagraphFormat().isHeading()); + + builder.writeln("Heading 1"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); + + builder.writeln("Heading 1.1"); + builder.writeln("Heading 1.2"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_3); + + builder.writeln("Heading 1.2.1"); + builder.writeln("Heading 1.2.2"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_4); + + builder.writeln("Heading 1.2.2.1"); + builder.writeln("Heading 1.2.2.2"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_5); + + builder.writeln("Heading 1.2.2.2.1"); + builder.writeln("Heading 1.2.2.2.2"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // The output PDF document will contain an outline, which is a table of contents that lists headings in the document body. + // Clicking on an entry in this outline will take us to the location of its respective heading. + // Set the "HeadingsOutlineLevels" property to "4" to exclude all headings whose levels are above 4 from the outline. + options.getOutlineOptions().setHeadingsOutlineLevels(4); + + // If an outline entry has subsequent entries of a higher level inbetween itself and the next entry of the same or lower level, + // an arrow will appear to the left of the entry. This entry is the "owner" of several such "sub-entries". + // In our document, the outline entries from the 5th heading level are sub-entries of the second 4th level outline entry, + // the 4th and 5th heading level entries are sub-entries of the second 3rd level entry, and so on. + // In the outline, we can click on the arrow of the "owner" entry to collapse/expand all its sub-entries. + // Set the "ExpandedOutlineLevels" property to "2" to automatically expand all heading level 2 and lower outline entries + // and collapse all level and 3 and higher entries when we open the document. + options.getOutlineOptions().setExpandedOutlineLevels(2); + + doc.save(getArtifactsDir() + "PdfSaveOptions.ExpandedOutlineLevels.pdf", options); + //ExEnd + } + + @Test + public void usePdfDocumentForExpandedOutlineLevels() throws Exception + { + expandedOutlineLevels(); + + Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.ExpandedOutlineLevels.pdf"); + + Assert.That(pdfDocument.Outlines.Count, assertEquals(1, ); + Assert.That(pdfDocument.Outlines.VisibleCount, assertEquals(5, ); + + Assert.That(pdfDocument.Outlines[1].Open, assertTrue(); + Assert.That(pdfDocument.Outlines[1].Level, assertEquals(1, ); + + Assert.That(pdfDocument.Outlines[1][1].Open, assertFalse(); + Assert.That(pdfDocument.Outlines[1][1].Level, assertEquals(2, ); + + Assert.That(pdfDocument.Outlines[1][2].Open, assertTrue(); + Assert.That(pdfDocument.Outlines[1][2].Level, assertEquals(2, ); + } + + @Test (dataProvider = "updateFieldsDataProvider") + public void updateFields(boolean updateFields) throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.Clone + //ExFor:SaveOptions.UpdateFields + //ExSummary:Shows how to update all the fields in a document immediately before saving it to PDF. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert text with PAGE and NUMPAGES fields. These fields do not display the correct value in real time. + // We will need to manually update them using updating methods such as "Field.Update()", and "Document.UpdateFields()" + // each time we need them to display accurate values. + builder.write("Page "); + builder.insertField("PAGE", ""); + builder.write(" of "); + builder.insertField("NUMPAGES", ""); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Hello World!"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "UpdateFields" property to "false" to not update all the fields in a document right before a save operation. + // This is the preferable option if we know that all our fields will be up to date before saving. + // Set the "UpdateFields" property to "true" to iterate through all the document + // fields and update them before we save it as a PDF. This will make sure that all the fields will display + // the most accurate values in the PDF. + options.setUpdateFields(updateFields); + + // We can clone PdfSaveOptions objects. + Assert.Is.Not.SameAs(options)options.deepClone()); + + doc.save(getArtifactsDir() + "PdfSaveOptions.UpdateFields.pdf", options); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "updateFieldsDataProvider") + public static Object[][] updateFieldsDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "usePdfDocumentForUpdateFieldsDataProvider") + public void usePdfDocumentForUpdateFields(boolean updateFields) throws Exception + { + updateFields(updateFields); + + Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.UpdateFields.pdf"); + + TextFragmentAbsorber textFragmentAbsorber = new TextFragmentAbsorber(); + pdfDocument.Pages.Accept(textFragmentAbsorber); + + Assert.That(textFragmentAbsorber.TextFragments[1].Text, assertEquals(updateFields ? "Page 1 of 2" : "Page of ", ); + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForUpdateFieldsDataProvider") + public static Object[][] usePdfDocumentForUpdateFieldsDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "preserveFormFieldsDataProvider") + public void preserveFormFields(boolean preserveFormFields) throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.PreserveFormFields + //ExSummary:Shows how to save a document to the PDF format using the Save method and the PdfSaveOptions class. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Please select a fruit: "); + + // Insert a combo box which will allow a user to choose an option from a collection of strings. + builder.insertComboBox("MyComboBox", new String[] { "Apple", "Banana", "Cherry" }, 0); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions pdfOptions = new PdfSaveOptions(); + + // Set the "PreserveFormFields" property to "true" to save form fields as interactive objects in the output PDF. + // Set the "PreserveFormFields" property to "false" to freeze all form fields in the document at + // their current values and display them as plain text in the output PDF. + pdfOptions.setPreserveFormFields(preserveFormFields); + + doc.save(getArtifactsDir() + "PdfSaveOptions.PreserveFormFields.pdf", pdfOptions); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "preserveFormFieldsDataProvider") + public static Object[][] preserveFormFieldsDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "usePdfDocumentForPreserveFormFieldsDataProvider") + public void usePdfDocumentForPreserveFormFields(boolean preserveFormFields) throws Exception + { + preserveFormFields(preserveFormFields); + + Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.PreserveFormFields.pdf"); + + Assert.That(pdfDocument.Pages.Count, assertEquals(1, ); + + TextFragmentAbsorber textFragmentAbsorber = new TextFragmentAbsorber(); + pdfDocument.Pages.Accept(textFragmentAbsorber); + + if (preserveFormFields) + { + Assert.That(textFragmentAbsorber.Text, assertEquals("Please select a fruit: ", ); + TestUtil.fileContainsString("<Throws(() => + { + TestUtil.fileContainsString("/Widget", + getArtifactsDir() + "PdfSaveOptions.PreserveFormFields.pdf"); + }); + + Assert.That(pdfDocument.Form.Count, assertEquals(0, ); + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForPreserveFormFieldsDataProvider") + public static Object[][] usePdfDocumentForPreserveFormFieldsDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "complianceDataProvider") + public void compliance(/*PdfCompliance*/int pdfCompliance) throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.Compliance + //ExFor:PdfCompliance + //ExSummary:Shows how to set the PDF standards compliance level of saved PDF documents. + Document doc = new Document(getMyDir() + "Images.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + // Note that some PdfSaveOptions are prohibited when saving to one of the standards and automatically fixed. + // Use IWarningCallback to know which options are automatically fixed. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + + // Set the "Compliance" property to "PdfCompliance.PdfA1b" to comply with the "PDF/A-1b" standard, + // which aims to preserve the visual appearance of the document as Aspose.Words convert it to PDF. + // Set the "Compliance" property to "PdfCompliance.Pdf17" to comply with the "1.7" standard. + // Set the "Compliance" property to "PdfCompliance.PdfA1a" to comply with the "PDF/A-1a" standard, + // which complies with "PDF/A-1b" as well as preserving the document structure of the original document. + // Set the "Compliance" property to "PdfCompliance.PdfUa1" to comply with the "PDF/UA-1" (ISO 14289-1) standard, + // which aims to define represent electronic documents in PDF that allow the file to be accessible. + // Set the "Compliance" property to "PdfCompliance.Pdf20" to comply with the "PDF 2.0" (ISO 32000-2) standard. + // Set the "Compliance" property to "PdfCompliance.PdfA4" to comply with the "PDF/A-4" (ISO 19004:2020) standard, + // which preserving document static visual appearance over time. + // Set the "Compliance" property to "PdfCompliance.PdfA4Ua2" to comply with both PDF/A-4 (ISO 19005-4:2020) + // and PDF/UA-2 (ISO 14289-2:2024) standards. + // Set the "Compliance" property to "PdfCompliance.PdfUa2" to comply with the PDF/UA-2 (ISO 14289-2:2024) standard. + // This helps with making documents searchable but may significantly increase the size of already large documents. + saveOptions.setCompliance(pdfCompliance); + + doc.save(getArtifactsDir() + "PdfSaveOptions.Compliance.pdf", saveOptions); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "complianceDataProvider") + public static Object[][] complianceDataProvider() throws Exception + { + return new Object[][] + { + {PdfCompliance.PDF_A_2_U}, + {PdfCompliance.PDF_A_3_A}, + {PdfCompliance.PDF_A_3_U}, + {PdfCompliance.PDF_17}, + {PdfCompliance.PDF_A_2_A}, + {PdfCompliance.PDF_UA_1}, + {PdfCompliance.PDF_20}, + {PdfCompliance.PDF_A_4}, + {PdfCompliance.PDF_A_4_F}, + {PdfCompliance.PDF_A_4_UA_2}, + {PdfCompliance.PDF_UA_2}, + }; + } + + @Test (dataProvider = "usePdfDocumentForComplianceDataProvider") + public void usePdfDocumentForCompliance(/*PdfCompliance*/int pdfCompliance) throws Exception + { + compliance(pdfCompliance); + + Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.Compliance.pdf"); + + switch (pdfCompliance) + { + case PdfCompliance.PDF_17: + Assert.That(pdfDocument.PdfFormat, Is.EqualTo(PdfFormat.v_1_7)); + Assert.That(pdfDocument.Version, assertEquals("1.7", ); + break; + case PdfCompliance.PDF_A_2_A: + Assert.That(pdfDocument.PdfFormat, Is.EqualTo(PdfFormat.PDF_A_2A)); + Assert.That(pdfDocument.Version, assertEquals("1.7", ); + break; + case PdfCompliance.PDF_A_2_U: + Assert.That(pdfDocument.PdfFormat, Is.EqualTo(PdfFormat.PDF_A_2U)); + Assert.That(pdfDocument.Version, assertEquals("1.7", ); + break; + case PdfCompliance.PDF_A_3_A: + Assert.That(pdfDocument.PdfFormat, Is.EqualTo(PdfFormat.PDF_A_3A)); + Assert.That(pdfDocument.Version, assertEquals("1.7", ); + break; + case PdfCompliance.PDF_A_3_U: + Assert.That(pdfDocument.PdfFormat, Is.EqualTo(PdfFormat.PDF_A_3U)); + Assert.That(pdfDocument.Version, assertEquals("1.7", ); + break; + case PdfCompliance.PDF_UA_1: + Assert.That(pdfDocument.PdfFormat, Is.EqualTo(PdfFormat.PDF_UA_1)); + Assert.That(pdfDocument.Version, assertEquals("1.7", ); + break; + case PdfCompliance.PDF_20: + Assert.That(pdfDocument.PdfFormat, Is.EqualTo(PdfFormat.v_2_0)); + Assert.That(pdfDocument.Version, assertEquals("2.0", ); + break; + case PdfCompliance.PDF_A_4: + Assert.That(pdfDocument.PdfFormat, Is.EqualTo(PdfFormat.PDF_A_4)); + Assert.That(pdfDocument.Version, assertEquals("2.0", ); + break; + case PdfCompliance.PDF_A_4_F: + Assert.That(pdfDocument.PdfFormat, Is.EqualTo(PdfFormat.PDF_A_4F)); + Assert.That(pdfDocument.Version, assertEquals("2.0", ); + break; + case PdfCompliance.PDF_A_4_UA_2: + Assert.That(pdfDocument.PdfFormat, Is.EqualTo(PdfFormat.PDF_UA_1)); + Assert.That(pdfDocument.Version, assertEquals("2.0", ); + break; + case PdfCompliance.PDF_UA_2: + Assert.That(pdfDocument.PdfFormat, Is.EqualTo(PdfFormat.PDF_UA_1)); + Assert.That(pdfDocument.Version, assertEquals("2.0", ); + break; + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForComplianceDataProvider") + public static Object[][] usePdfDocumentForComplianceDataProvider() throws Exception + { + return new Object[][] + { + {PdfCompliance.PDF_A_2_U}, + {PdfCompliance.PDF_A_3_A}, + {PdfCompliance.PDF_A_3_U}, + {PdfCompliance.PDF_17}, + {PdfCompliance.PDF_A_2_A}, + {PdfCompliance.PDF_UA_1}, + {PdfCompliance.PDF_20}, + {PdfCompliance.PDF_A_4}, + {PdfCompliance.PDF_A_4_F}, + {PdfCompliance.PDF_A_4_UA_2}, + {PdfCompliance.PDF_UA_2}, + }; + } + + @Test (dataProvider = "textCompressionDataProvider") + public void textCompression(/*PdfTextCompression*/int pdfTextCompression) throws Exception + { + //ExStart + //ExFor:PdfSaveOptions + //ExFor:PdfSaveOptions.TextCompression + //ExFor:PdfTextCompression + //ExSummary:Shows how to apply text compression when saving a document to PDF. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + for (int i = 0; i < 100; i++) + builder.writeln("Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "TextCompression" property to "PdfTextCompression.None" to not apply any + // compression to text when we save the document to PDF. + // Set the "TextCompression" property to "PdfTextCompression.Flate" to apply ZIP compression + // to text when we save the document to PDF. The larger the document, the bigger the impact that this will have. + options.setTextCompression(pdfTextCompression); + + doc.save(getArtifactsDir() + "PdfSaveOptions.TextCompression.pdf", options); + //ExEnd + + String filePath = getArtifactsDir() + "PdfSaveOptions.TextCompression.pdf"; + long testedFileLength = new FileInfo(getArtifactsDir() + "PdfSaveOptions.TextCompression.pdf").getLength(); + + switch (pdfTextCompression) + { + case PdfTextCompression.NONE: + Assert.assertTrue(testedFileLength < 69000); + TestUtil.fileContainsString("<>stream", filePath); + break; + case PdfTextCompression.FLATE: + Assert.assertTrue(testedFileLength < 27000); + TestUtil.fileContainsString("<>stream", filePath); + break; + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "textCompressionDataProvider") + public static Object[][] textCompressionDataProvider() throws Exception + { + return new Object[][] + { + {PdfTextCompression.NONE}, + {PdfTextCompression.FLATE}, + }; + } + + @Test (dataProvider = "imageCompressionDataProvider") + public void imageCompression(/*PdfImageCompression*/int pdfImageCompression) throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.ImageCompression + //ExFor:PdfSaveOptions.JpegQuality + //ExFor:PdfImageCompression + //ExSummary:Shows how to specify a compression type for all images in a document that we are converting to PDF. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Jpeg image:"); + builder.insertImage(getImageDir() + "Logo.jpg"); + builder.insertParagraph(); + builder.writeln("Png image:"); + builder.insertImage(getImageDir() + "Transparent background logo.png"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions pdfSaveOptions = new PdfSaveOptions(); + // Set the "ImageCompression" property to "PdfImageCompression.Auto" to use the + // "ImageCompression" property to control the quality of the Jpeg images that end up in the output PDF. + // Set the "ImageCompression" property to "PdfImageCompression.Jpeg" to use the + // "ImageCompression" property to control the quality of all images that end up in the output PDF. + pdfSaveOptions.setImageCompression(pdfImageCompression); + // Set the "JpegQuality" property to "10" to strengthen compression at the cost of image quality. + pdfSaveOptions.setJpegQuality(10); + + doc.save(getArtifactsDir() + "PdfSaveOptions.ImageCompression.pdf", pdfSaveOptions); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "imageCompressionDataProvider") + public static Object[][] imageCompressionDataProvider() throws Exception + { + return new Object[][] + { + {PdfImageCompression.AUTO}, + {PdfImageCompression.JPEG}, + }; + } + + @Test (dataProvider = "usePdfDocumentForImageCompressionDataProvider") + public void usePdfDocumentForImageCompression(/*PdfImageCompression*/int pdfImageCompression) throws Exception + { + imageCompression(pdfImageCompression); + + + Aspose.Pdf.Document pdfDocument = + new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.ImageCompression.pdf"); + XImage image = pdfDocument.Pages[1].Resources.Images[1]; + String imagePath = getArtifactsDir() + $"PdfSaveOptions.ImageCompression.Image1.{image.FilterType}"; + FileStream stream = new FileStream(imagePath, FileMode.CREATE); + try /*JAVA: was using*/ + { + image.Save(stream); + } + finally { if (stream != null) stream.close(); } + + TestUtil.verifyImage(400, 400, imagePath); + + image = pdfDocument.Pages[1].Resources.Images[2]; + imagePath = getArtifactsDir() + $"PdfSaveOptions.ImageCompression.Image2.{image.FilterType}"; + FileStream stream1 = new FileStream(imagePath, FileMode.CREATE); + try /*JAVA: was using*/ + { + image.Save(stream1); + } + finally { if (stream1 != null) stream1.close(); } + + long testedFileLength = new FileInfo(getArtifactsDir() + "PdfSaveOptions.ImageCompression.pdf").getLength(); + switch (pdfImageCompression) + { + case PdfImageCompression.AUTO: + Assert.assertTrue(testedFileLength < 54000); + TestUtil.verifyImage(400, 400, imagePath); + break; + case PdfImageCompression.JPEG: + Assert.assertTrue(testedFileLength < 40000); + TestUtil.verifyImage(400, 400, imagePath); + break; + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForImageCompressionDataProvider") + public static Object[][] usePdfDocumentForImageCompressionDataProvider() throws Exception + { + return new Object[][] + { + {PdfImageCompression.AUTO}, + {PdfImageCompression.JPEG}, + }; + } + + @Test (dataProvider = "imageColorSpaceExportModeDataProvider") + public void imageColorSpaceExportMode(/*PdfImageColorSpaceExportMode*/int pdfImageColorSpaceExportMode) throws Exception + { + //ExStart + //ExFor:PdfImageColorSpaceExportMode + //ExFor:PdfSaveOptions.ImageColorSpaceExportMode + //ExSummary:Shows how to set a different color space for images in a document as we export it to PDF. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Jpeg image:"); + builder.insertImage(getImageDir() + "Logo.jpg"); + builder.insertParagraph(); + builder.writeln("Png image:"); + builder.insertImage(getImageDir() + "Transparent background logo.png"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions pdfSaveOptions = new PdfSaveOptions(); + + // Set the "ImageColorSpaceExportMode" property to "PdfImageColorSpaceExportMode.Auto" to get Aspose.Words to + // automatically select the color space for images in the document that it converts to PDF. + // In most cases, the color space will be RGB. + // Set the "ImageColorSpaceExportMode" property to "PdfImageColorSpaceExportMode.SimpleCmyk" + // to use the CMYK color space for all images in the saved PDF. + // Aspose.Words will also apply Flate compression to all images and ignore the "ImageCompression" property's value. + pdfSaveOptions.setImageColorSpaceExportMode(pdfImageColorSpaceExportMode); + + doc.save(getArtifactsDir() + "PdfSaveOptions.ImageColorSpaceExportMode.pdf", pdfSaveOptions); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "imageColorSpaceExportModeDataProvider") + public static Object[][] imageColorSpaceExportModeDataProvider() throws Exception + { + return new Object[][] + { + {PdfImageColorSpaceExportMode.AUTO}, + {PdfImageColorSpaceExportMode.SIMPLE_CMYK}, + }; + } + + @Test (dataProvider = "usePdfDocumentForImageColorSpaceExportModeDataProvider") + public void usePdfDocumentForImageColorSpaceExportMode(/*PdfImageColorSpaceExportMode*/int pdfImageColorSpaceExportMode) throws Exception + { + imageColorSpaceExportMode(pdfImageColorSpaceExportMode); + + Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.ImageColorSpaceExportMode.pdf"); + XImage pdfDocImage = pdfDocument.Pages[1].Resources.Images[1]; + + var testedImageLength = pdfDocImage.ToStream().Length; + switch (pdfImageColorSpaceExportMode) + { + case PdfImageColorSpaceExportMode.AUTO: + Assert.That(testedImageLength < 20500, assertTrue(); + break; + case PdfImageColorSpaceExportMode.SIMPLE_CMYK: + Assert.That(testedImageLength < 140000, assertTrue(); + break; + } + + Assert.That(pdfDocImage.Width, assertEquals(400, ); + Assert.That(pdfDocImage.Height, assertEquals(400, ); + Assert.That(pdfDocImage.GetColorType(), Is.EqualTo(ColorType.Rgb)); + + pdfDocImage = pdfDocument.Pages[1].Resources.Images[2]; + + testedImageLength = pdfDocImage.ToStream().Length; + switch (pdfImageColorSpaceExportMode) + { + case PdfImageColorSpaceExportMode.AUTO: + Assert.That(testedImageLength < 20500, assertTrue(); + break; + case PdfImageColorSpaceExportMode.SIMPLE_CMYK: + Assert.That(testedImageLength < 21500, assertTrue(); + break; + } + + Assert.That(pdfDocImage.Width, assertEquals(400, ); + Assert.That(pdfDocImage.Height, assertEquals(400, ); + Assert.That(pdfDocImage.GetColorType(), Is.EqualTo(ColorType.Rgb)); + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForImageColorSpaceExportModeDataProvider") + public static Object[][] usePdfDocumentForImageColorSpaceExportModeDataProvider() throws Exception + { + return new Object[][] + { + {PdfImageColorSpaceExportMode.AUTO}, + {PdfImageColorSpaceExportMode.SIMPLE_CMYK}, + }; + } + + @Test + public void downsampleOptions() throws Exception + { + //ExStart + //ExFor:DownsampleOptions + //ExFor:DownsampleOptions.DownsampleImages + //ExFor:DownsampleOptions.Resolution + //ExFor:DownsampleOptions.ResolutionThreshold + //ExFor:PdfSaveOptions.DownsampleOptions + //ExSummary:Shows how to change the resolution of images in the PDF document. + Document doc = new Document(getMyDir() + "Images.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // By default, Aspose.Words downsample all images in a document that we save to PDF to 220 ppi. + Assert.assertTrue(options.getDownsampleOptions().getDownsampleImages()); + Assert.assertEquals(220, options.getDownsampleOptions().getResolution()); + Assert.assertEquals(0, options.getDownsampleOptions().getResolutionThreshold()); + + doc.save(getArtifactsDir() + "PdfSaveOptions.DownsampleOptions.Default.pdf", options); + + // Set the "Resolution" property to "36" to downsample all images to 36 ppi. + options.getDownsampleOptions().setResolution(36); + + // Set the "ResolutionThreshold" property to only apply the downsampling to + // images with a resolution that is above 128 ppi. + options.getDownsampleOptions().setResolutionThreshold(128); + + // Only the first two images from the document will be downsampled at this stage. + doc.save(getArtifactsDir() + "PdfSaveOptions.DownsampleOptions.LowerResolution.pdf", options); + //ExEnd + } + + @Test + public void usePdfDocumentForDownsampleOptions() throws Exception + { + downsampleOptions(); + + Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.DownsampleOptions.Default.pdf"); + XImage pdfDocImage = pdfDocument.Pages[1].Resources.Images[1]; + + Assert.That(pdfDocImage.ToStream().Length < 400000, assertTrue(); + Assert.That(pdfDocImage.GetColorType(), Is.EqualTo(ColorType.Rgb)); + } + + @Test (dataProvider = "colorRenderingDataProvider") + public void colorRendering(/*ColorMode*/int colorMode) throws Exception + { + //ExStart + //ExFor:PdfSaveOptions + //ExFor:ColorMode + //ExFor:FixedPageSaveOptions.ColorMode + //ExSummary:Shows how to change image color with saving options property. + Document doc = new Document(getMyDir() + "Images.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + // Set the "ColorMode" property to "Grayscale" to render all images from the document in black and white. + // The size of the output document may be larger with this setting. + // Set the "ColorMode" property to "Normal" to render all images in color. + PdfSaveOptions pdfSaveOptions = new PdfSaveOptions(); { pdfSaveOptions.setColorMode(colorMode); } + + doc.save(getArtifactsDir() + "PdfSaveOptions.ColorRendering.pdf", pdfSaveOptions); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "colorRenderingDataProvider") + public static Object[][] colorRenderingDataProvider() throws Exception + { + return new Object[][] + { + {ColorMode.GRAYSCALE}, + {ColorMode.NORMAL}, + }; + } + + @Test (dataProvider = "usePdfDocumentForColorRenderingDataProvider") + public void usePdfDocumentForColorRendering(/*ColorMode*/int colorMode) throws Exception + { + colorRendering(colorMode); + + Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.ColorRendering.pdf"); + XImage pdfDocImage = pdfDocument.Pages[1].Resources.Images[1]; + + var testedImageLength = pdfDocImage.ToStream().Length; + switch (colorMode) + { + case ColorMode.NORMAL: + Assert.That(testedImageLength < 400000, assertTrue(); + Assert.That(pdfDocImage.GetColorType(), Is.EqualTo(ColorType.Rgb)); + break; + case ColorMode.GRAYSCALE: + Assert.That(testedImageLength < 1450000, assertTrue(); + Assert.That(pdfDocImage.GetColorType(), Is.EqualTo(ColorType.Grayscale)); + break; + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForColorRenderingDataProvider") + public static Object[][] usePdfDocumentForColorRenderingDataProvider() throws Exception + { + return new Object[][] + { + {ColorMode.GRAYSCALE}, + {ColorMode.NORMAL}, + }; + } + + @Test (dataProvider = "docTitleDataProvider") + public void docTitle(boolean displayDocTitle) throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.DisplayDocTitle + //ExSummary:Shows how to display the title of the document as the title bar. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + doc.getBuiltInDocumentProperties().setTitle("Windows bar pdf title"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + // Set the "DisplayDocTitle" to "true" to get some PDF readers, such as Adobe Acrobat Pro, + // to display the value of the document's "Title" built-in property in the tab that belongs to this document. + // Set the "DisplayDocTitle" to "false" to get such readers to display the document's filename. + PdfSaveOptions pdfSaveOptions = new PdfSaveOptions(); { pdfSaveOptions.setDisplayDocTitle(displayDocTitle); } + + doc.save(getArtifactsDir() + "PdfSaveOptions.DocTitle.pdf", pdfSaveOptions); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "docTitleDataProvider") + public static Object[][] docTitleDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "usePdfDocumentForDocTitleDataProvider") + public void usePdfDocumentForDocTitle(boolean displayDocTitle) throws Exception + { + docTitle(displayDocTitle); + + Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.DocTitle.pdf"); + + Assert.That(pdfDocument.DisplayDocTitle, assertEquals(displayDocTitle, ); + Assert.That(pdfDocument.Info.Title, assertEquals("Windows bar pdf title", ); + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForDocTitleDataProvider") + public static Object[][] usePdfDocumentForDocTitleDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "memoryOptimizationDataProvider") + public void memoryOptimization(boolean memoryOptimization) throws Exception + { + //ExStart + //ExFor:SaveOptions.CreateSaveOptions(SaveFormat) + //ExFor:SaveOptions.MemoryOptimization + //ExSummary:Shows an option to optimize memory consumption when rendering large documents to PDF. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + SaveOptions saveOptions = SaveOptions.createSaveOptions(SaveFormat.PDF); + + // Set the "MemoryOptimization" property to "true" to lower the memory footprint of large documents' saving operations + // at the cost of increasing the duration of the operation. + // Set the "MemoryOptimization" property to "false" to save the document as a PDF normally. + saveOptions.setMemoryOptimization(memoryOptimization); + + doc.save(getArtifactsDir() + "PdfSaveOptions.MemoryOptimization.pdf", saveOptions); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "memoryOptimizationDataProvider") + public static Object[][] memoryOptimizationDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "escapeUriDataProvider") + public void escapeUri(String uri, String result) throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertHyperlink("Testlink", uri, false); + + doc.save(getArtifactsDir() + "PdfSaveOptions.EscapedUri.pdf"); + } + + //JAVA-added data provider for test method + @DataProvider(name = "escapeUriDataProvider") + public static Object[][] escapeUriDataProvider() throws Exception + { + return new Object[][] + { + {"https://www.google.com/search?q= aspose", "https://www.google.com/search?q=%20aspose"}, + {"https://www.google.com/search?q=%20aspose", "https://www.google.com/search?q=%20aspose"}, + }; + } + + @Test (dataProvider = "usePdfDocumentForEscapeUriDataProvider") + public void usePdfDocumentForEscapeUri(String uri, String result) throws Exception + { + escapeUri(uri, result); + + Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.EscapedUri.pdf"); + + Aspose.Pdf.Page page = pdfDocument.Pages[1]; + LinkAnnotation linkAnnot = (LinkAnnotation)page.Annotations[1]; + + GoToURIAction action = (GoToURIAction)linkAnnot.Action; + + Assert.That(action.URI, assertEquals(result, ); + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForEscapeUriDataProvider") + public static Object[][] usePdfDocumentForEscapeUriDataProvider() throws Exception + { + return new Object[][] + { + {"https://www.google.com/search?q= aspose", "https://www.google.com/search?q=%20aspose"}, + {"https://www.google.com/search?q=%20aspose", "https://www.google.com/search?q=%20aspose"}, + }; + } + + @Test (dataProvider = "openHyperlinksInNewWindowDataProvider") + public void openHyperlinksInNewWindow(boolean openHyperlinksInNewWindow) throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.OpenHyperlinksInNewWindow + //ExSummary:Shows how to save hyperlinks in a document we convert to PDF so that they open new pages when we click on them. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertHyperlink("Testlink", "https://www.google.com/search?q=%20aspose", false); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "OpenHyperlinksInNewWindow" property to "true" to save all hyperlinks using Javascript code + // that forces readers to open these links in new windows/browser tabs. + // Set the "OpenHyperlinksInNewWindow" property to "false" to save all hyperlinks normally. + options.setOpenHyperlinksInNewWindow(openHyperlinksInNewWindow); + + doc.save(getArtifactsDir() + "PdfSaveOptions.OpenHyperlinksInNewWindow.pdf", options); + //ExEnd + + if (openHyperlinksInNewWindow) + TestUtil.fileContainsString( + "<>/A<>>>", + getArtifactsDir() + "PdfSaveOptions.OpenHyperlinksInNewWindow.pdf"); + else + TestUtil.fileContainsString( + "<>/A<>>>", + getArtifactsDir() + "PdfSaveOptions.OpenHyperlinksInNewWindow.pdf"); + } + + //JAVA-added data provider for test method + @DataProvider(name = "openHyperlinksInNewWindowDataProvider") + public static Object[][] openHyperlinksInNewWindowDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "usePdfDocumentForOpenHyperlinksInNewWindowDataProvider") + public void usePdfDocumentForOpenHyperlinksInNewWindow(boolean openHyperlinksInNewWindow) throws Exception + { + openHyperlinksInNewWindow(openHyperlinksInNewWindow); + + Aspose.Pdf.Document pdfDocument = + new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.OpenHyperlinksInNewWindow.pdf"); + + Aspose.Pdf.Page page = pdfDocument.Pages[1]; + LinkAnnotation linkAnnot = (LinkAnnotation)page.Annotations[1]; + + Assert.That(linkAnnot.Action.GetType(), assertEquals(openHyperlinksInNewWindow ? JavascriptAction.class : GoToURIAction.class, ); + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForOpenHyperlinksInNewWindowDataProvider") + public static Object[][] usePdfDocumentForOpenHyperlinksInNewWindowDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + //ExStart + //ExFor:MetafileRenderingMode + //ExFor:MetafileRenderingOptions + //ExFor:MetafileRenderingOptions.EmulateRasterOperations + //ExFor:MetafileRenderingOptions.RenderingMode + //ExFor:IWarningCallback + //ExFor:FixedPageSaveOptions.MetafileRenderingOptions + //ExSummary:Shows added a fallback to bitmap rendering and changing type of warnings about unsupported metafile records. + @Test (groups = "SkipMono") //ExSkip + public void handleBinaryRasterWarnings() throws Exception + { + Document doc = new Document(getMyDir() + "WMF with image.docx"); + + MetafileRenderingOptions metafileRenderingOptions = new MetafileRenderingOptions(); + + // Set the "EmulateRasterOperations" property to "false" to fall back to bitmap when + // it encounters a metafile, which will require raster operations to render in the output PDF. + metafileRenderingOptions.setEmulateRasterOperations(false); + + // Set the "RenderingMode" property to "VectorWithFallback" to try to render every metafile using vector graphics. + metafileRenderingOptions.setRenderingMode(MetafileRenderingMode.VECTOR_WITH_FALLBACK); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF and applies the configuration + // in our MetafileRenderingOptions object to the saving operation. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setMetafileRenderingOptions(metafileRenderingOptions); + + HandleDocumentWarnings callback = new HandleDocumentWarnings(); + doc.setWarningCallback(callback); + + doc.save(getArtifactsDir() + "PdfSaveOptions.HandleBinaryRasterWarnings.pdf", saveOptions); + + Assert.assertEquals(1, callback.Warnings.getCount()); + Assert.assertEquals("'R2_XORPEN' binary raster operation is not supported.", callback.Warnings.get(0).getDescription()); + } + + /// + /// Prints and collects formatting loss-related warnings that occur upon saving a document. + /// + public static class HandleDocumentWarnings implements IWarningCallback + { + public void warning(WarningInfo info) + { + if (info.getWarningType() == WarningType.MINOR_FORMATTING_LOSS) + { + System.out.println("Unsupported operation: " + info.getDescription()); + Warnings.warning(info); + } + } + + public WarningInfoCollection Warnings = new WarningInfoCollection(); + } + //ExEnd + + @Test (dataProvider = "headerFooterBookmarksExportModeDataProvider") + public void headerFooterBookmarksExportMode(/*HeaderFooterBookmarksExportMode*/int headerFooterBookmarksExportMode) throws Exception + { + //ExStart + //ExFor:HeaderFooterBookmarksExportMode + //ExFor:OutlineOptions + //ExFor:OutlineOptions.DefaultBookmarksOutlineLevel + //ExFor:PdfSaveOptions.HeaderFooterBookmarksExportMode + //ExFor:PdfSaveOptions.PageMode + //ExFor:PdfPageMode + //ExSummary:Shows to process bookmarks in headers/footers in a document that we are rendering to PDF. + Document doc = new Document(getMyDir() + "Bookmarks in headers and footers.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + + // Set the "PageMode" property to "PdfPageMode.UseOutlines" to display the outline navigation pane in the output PDF. + saveOptions.setPageMode(PdfPageMode.USE_OUTLINES); + + // Set the "DefaultBookmarksOutlineLevel" property to "1" to display all + // bookmarks at the first level of the outline in the output PDF. + saveOptions.getOutlineOptions().setDefaultBookmarksOutlineLevel(1); + + // Set the "HeaderFooterBookmarksExportMode" property to "HeaderFooterBookmarksExportMode.None" to + // not export any bookmarks that are inside headers/footers. + // Set the "HeaderFooterBookmarksExportMode" property to "HeaderFooterBookmarksExportMode.First" to + // only export bookmarks in the first section's header/footers. + // Set the "HeaderFooterBookmarksExportMode" property to "HeaderFooterBookmarksExportMode.All" to + // export bookmarks that are in all headers/footers. + saveOptions.setHeaderFooterBookmarksExportMode(headerFooterBookmarksExportMode); + + doc.save(getArtifactsDir() + "PdfSaveOptions.HeaderFooterBookmarksExportMode.pdf", saveOptions); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "headerFooterBookmarksExportModeDataProvider") + public static Object[][] headerFooterBookmarksExportModeDataProvider() throws Exception + { + return new Object[][] + { + {com.aspose.words.HeaderFooterBookmarksExportMode.NONE}, + {com.aspose.words.HeaderFooterBookmarksExportMode.FIRST}, + {com.aspose.words.HeaderFooterBookmarksExportMode.ALL}, + }; + } + + @Test (dataProvider = "usePdfDocumentForHeaderFooterBookmarksExportModeDataProvider") + public void usePdfDocumentForHeaderFooterBookmarksExportMode(/*HeaderFooterBookmarksExportMode*/int headerFooterBookmarksExportMode) throws Exception + { + Document doc = new Document(getMyDir() + "Bookmarks in headers and footers.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + + // Set the "PageMode" property to "PdfPageMode.UseOutlines" to display the outline navigation pane in the output PDF. + saveOptions.setPageMode(PdfPageMode.USE_OUTLINES); + + // Set the "DefaultBookmarksOutlineLevel" property to "1" to display all + // bookmarks at the first level of the outline in the output PDF. + saveOptions.getOutlineOptions().setDefaultBookmarksOutlineLevel(1); + + // Set the "HeaderFooterBookmarksExportMode" property to "HeaderFooterBookmarksExportMode.None" to + // not export any bookmarks that are inside headers/footers. + // Set the "HeaderFooterBookmarksExportMode" property to "HeaderFooterBookmarksExportMode.First" to + // only export bookmarks in the first section's header/footers. + // Set the "HeaderFooterBookmarksExportMode" property to "HeaderFooterBookmarksExportMode.All" to + // export bookmarks that are in all headers/footers. + saveOptions.setHeaderFooterBookmarksExportMode(headerFooterBookmarksExportMode); + + doc.save(getArtifactsDir() + "PdfSaveOptions.HeaderFooterBookmarksExportMode.pdf", saveOptions); + + Aspose.Pdf.Document pdfDoc = + new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.HeaderFooterBookmarksExportMode.pdf"); + String inputDocLocaleName = new msCultureInfo(doc.getStyles().getDefaultFont().getLocaleId()).getName(); + + TextFragmentAbsorber textFragmentAbsorber = new TextFragmentAbsorber(); + pdfDoc.Pages.Accept(textFragmentAbsorber); + switch (headerFooterBookmarksExportMode) + { + case com.aspose.words.HeaderFooterBookmarksExportMode.NONE: + TestUtil.fileContainsString($"<>\r\n", + getArtifactsDir() + "PdfSaveOptions.HeaderFooterBookmarksExportMode.pdf"); + + Assert.That(pdfDoc.Outlines.Count, assertEquals(0, ); + break; + case com.aspose.words.HeaderFooterBookmarksExportMode.FIRST: + case com.aspose.words.HeaderFooterBookmarksExportMode.ALL: + TestUtil.fileContainsString( + $"<>", + getArtifactsDir() + "PdfSaveOptions.HeaderFooterBookmarksExportMode.pdf"); + + OutlineCollection outlineItemCollection = pdfDoc.Outlines; + + Assert.That(outlineItemCollection.Count, assertEquals(4, ); + Assert.That(outlineItemCollection[1].Title, assertEquals("Bookmark_1", ); + Assert.That(outlineItemCollection[1].Destination.ToString(), assertEquals("1 XYZ 233 806 0", ); + + Assert.That(outlineItemCollection[2].Title, assertEquals("Bookmark_2", ); + Assert.That(outlineItemCollection[2].Destination.ToString(), assertEquals("1 XYZ 84 47 0", ); + + Assert.That(outlineItemCollection[3].Title, assertEquals("Bookmark_3", ); + Assert.That(outlineItemCollection[3].Destination.ToString(), assertEquals("2 XYZ 85 806 0", ); + + Assert.That(outlineItemCollection[4].Title, assertEquals("Bookmark_4", ); + Assert.That(outlineItemCollection[4].Destination.ToString(), assertEquals("2 XYZ 85 48 0", ); + break; + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForHeaderFooterBookmarksExportModeDataProvider") + public static Object[][] usePdfDocumentForHeaderFooterBookmarksExportModeDataProvider() throws Exception + { + return new Object[][] + { + {com.aspose.words.HeaderFooterBookmarksExportMode.NONE}, + {com.aspose.words.HeaderFooterBookmarksExportMode.FIRST}, + {com.aspose.words.HeaderFooterBookmarksExportMode.ALL}, + }; + } + + @Test + public void unsupportedImageFormatWarning() throws Exception + { + Document doc = new Document(getMyDir() + "Corrupted image.docx"); + + SaveWarningCallback saveWarningCallback = new SaveWarningCallback(); + doc.setWarningCallback(saveWarningCallback); + + doc.save(getArtifactsDir() + "PdfSaveOption.UnsupportedImageFormatWarning.pdf", SaveFormat.PDF); + + Assert.assertEquals("Image can not be processed. Possibly unsupported image format.", saveWarningCallback.SaveWarnings.get(0).getDescription()); + } + + public static class SaveWarningCallback implements IWarningCallback + { + public void warning(WarningInfo info) + { + if (info.getWarningType() == WarningType.MINOR_FORMATTING_LOSS) + { + System.out.println("{info.WarningType}: {info.Description}."); + SaveWarnings.warning(info); + } + } + + WarningInfoCollection SaveWarnings = new WarningInfoCollection(); + } + + @Test (dataProvider = "emulateRenderingToSizeOnPageDataProvider") + public void emulateRenderingToSizeOnPage(boolean renderToSize) throws Exception + { + //ExStart + //ExFor:MetafileRenderingOptions.EmulateRenderingToSizeOnPage + //ExFor:MetafileRenderingOptions.EmulateRenderingToSizeOnPageResolution + //ExSummary:Shows how to display of the metafile according to the size on page. + Document doc = new Document(getMyDir() + "WMF with text.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + + + // Set the "EmulateRenderingToSizeOnPage" property to "true" + // to emulate rendering according to the metafile size on page. + // Set the "EmulateRenderingToSizeOnPage" property to "false" + // to emulate metafile rendering to its default size in pixels. + saveOptions.getMetafileRenderingOptions().setEmulateRenderingToSizeOnPage(renderToSize); + saveOptions.getMetafileRenderingOptions().setEmulateRenderingToSizeOnPageResolution(50); + + doc.save(getArtifactsDir() + "PdfSaveOptions.EmulateRenderingToSizeOnPage.pdf", saveOptions); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "emulateRenderingToSizeOnPageDataProvider") + public static Object[][] emulateRenderingToSizeOnPageDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "usePdfDocumentForEmulateRenderingToSizeOnPageDataProvider") + public void usePdfDocumentForEmulateRenderingToSizeOnPage(boolean renderToSize) throws Exception + { + emulateRenderingToSizeOnPage(renderToSize); + + Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.EmulateRenderingToSizeOnPage.pdf"); + TextFragmentAbsorber textAbsorber = new TextFragmentAbsorber(); + + pdfDocument.Pages[1].Accept(textAbsorber); + Rectangle textFragmentRectangle = textAbsorber.TextFragments[3].Rectangle; + + Assert.That(textFragmentRectangle.Width, assertEquals(renderToSize ? 1.585d : 5.045d, 0.001d, ); + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForEmulateRenderingToSizeOnPageDataProvider") + public static Object[][] usePdfDocumentForEmulateRenderingToSizeOnPageDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "embedFullFontsDataProvider") + public void embedFullFonts(boolean embedFullFonts) throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.#ctor + //ExFor:PdfSaveOptions.EmbedFullFonts + //ExSummary:Shows how to enable or disable subsetting when embedding fonts while rendering a document to PDF. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Arial"); + builder.writeln("Hello world!"); + builder.getFont().setName("Arvo"); + builder.writeln("The quick brown fox jumps over the lazy dog."); + + // Configure our font sources to ensure that we have access to both the fonts in this document. + FontSourceBase[] originalFontsSources = FontSettings.getDefaultInstance().getFontsSources(); + FolderFontSource folderFontSource = + new FolderFontSource(getFontsDir(), true); + FontSettings.getDefaultInstance().setFontsSources(new FontSourceBase[] { originalFontsSources[0], folderFontSource }); + + FontSourceBase[] fontSources = FontSettings.getDefaultInstance().getFontsSources(); + Assert.That(fontSources[0].getAvailableFonts().Any(f => f.FullFontName == "Arial"), assertTrue(); + Assert.That(fontSources[1].getAvailableFonts().Any(f => f.FullFontName == "Arvo"), assertTrue(); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Since our document contains a custom font, embedding in the output document may be desirable. + // Set the "EmbedFullFonts" property to "true" to embed every glyph of every embedded font in the output PDF. + // The document's size may become very large, but we will have full use of all fonts if we edit the PDF. + // Set the "EmbedFullFonts" property to "false" to apply subsetting to fonts, saving only the glyphs + // that the document is using. The file will be considerably smaller, + // but we may need access to any custom fonts if we edit the document. + options.setEmbedFullFonts(embedFullFonts); + + doc.save(getArtifactsDir() + "PdfSaveOptions.EmbedFullFonts.pdf", options); + + // Restore the original font sources. + FontSettings.getDefaultInstance().setFontsSources(originalFontsSources); + //ExEnd + + long testedFileLength = new FileInfo(getArtifactsDir() + "PdfSaveOptions.EmbedFullFonts.pdf").getLength(); + if (embedFullFonts) + Assert.assertTrue(testedFileLength < 571000); + else + Assert.assertTrue(testedFileLength < 24000); + } + + //JAVA-added data provider for test method + @DataProvider(name = "embedFullFontsDataProvider") + public static Object[][] embedFullFontsDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "usePdfDocumentForEmbedFullFontsDataProvider") + public void usePdfDocumentForEmbedFullFonts(boolean embedFullFonts) throws Exception + { + embedFullFonts(embedFullFonts); + + Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.EmbedFullFonts.pdf"); + Aspose.Pdf.Text.Font[] pdfDocFonts = pdfDocument.FontUtilities.GetAllFonts(); + + Assert.That(pdfDocFonts[0].FontName, assertEquals("ArialMT", ); + Assert.That(pdfDocFonts[0].IsSubset, Is.Not.EqualTo(embedFullFonts)); + + Assert.That(pdfDocFonts[1].FontName, assertEquals("Arvo", ); + Assert.That(pdfDocFonts[1].IsSubset, Is.Not.EqualTo(embedFullFonts)); + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForEmbedFullFontsDataProvider") + public static Object[][] usePdfDocumentForEmbedFullFontsDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "embedWindowsFontsDataProvider") + public void embedWindowsFonts(/*PdfFontEmbeddingMode*/int pdfFontEmbeddingMode) throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.FontEmbeddingMode + //ExFor:PdfFontEmbeddingMode + //ExSummary:Shows how to set Aspose.Words to skip embedding Arial and Times New Roman fonts into a PDF document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // "Arial" is a standard font, and "Courier New" is a nonstandard font. + builder.getFont().setName("Arial"); + builder.writeln("Hello world!"); + builder.getFont().setName("Courier New"); + builder.writeln("The quick brown fox jumps over the lazy dog."); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + // Set the "EmbedFullFonts" property to "true" to embed every glyph of every embedded font in the output PDF. + options.setEmbedFullFonts(true); + // Set the "FontEmbeddingMode" property to "EmbedAll" to embed all fonts in the output PDF. + // Set the "FontEmbeddingMode" property to "EmbedNonstandard" to only allow nonstandard fonts' embedding in the output PDF. + // Set the "FontEmbeddingMode" property to "EmbedNone" to not embed any fonts in the output PDF. + options.setFontEmbeddingMode(pdfFontEmbeddingMode); + + doc.save(getArtifactsDir() + "PdfSaveOptions.EmbedWindowsFonts.pdf", options); + //ExEnd + + long testedFileLength = new FileInfo(getArtifactsDir() + "PdfSaveOptions.EmbedWindowsFonts.pdf").getLength(); + switch (pdfFontEmbeddingMode) + { + case PdfFontEmbeddingMode.EMBED_ALL: + Assert.assertTrue(testedFileLength < 1040000); + break; + case PdfFontEmbeddingMode.EMBED_NONSTANDARD: + Assert.assertTrue(testedFileLength < 492000); + break; + case PdfFontEmbeddingMode.EMBED_NONE: + Assert.assertTrue(testedFileLength < 4300); + break; + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "embedWindowsFontsDataProvider") + public static Object[][] embedWindowsFontsDataProvider() throws Exception + { + return new Object[][] + { + {PdfFontEmbeddingMode.EMBED_ALL}, + {PdfFontEmbeddingMode.EMBED_NONE}, + {PdfFontEmbeddingMode.EMBED_NONSTANDARD}, + }; + } + + @Test (dataProvider = "usePdfDocumentForEmbedWindowsFontsDataProvider") + public void usePdfDocumentForEmbedWindowsFonts(/*PdfFontEmbeddingMode*/int pdfFontEmbeddingMode) throws Exception + { + embedWindowsFonts(pdfFontEmbeddingMode); + + Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.EmbedWindowsFonts.pdf"); + Aspose.Pdf.Text.Font[] pdfDocFonts = pdfDocument.FontUtilities.GetAllFonts(); + + Assert.That(pdfDocFonts[0].FontName, assertEquals("ArialMT", ); + Assert.That(pdfDocFonts[0].IsEmbedded, assertEquals(pdfFontEmbeddingMode == PdfFontEmbeddingMode.EMBED_ALL, ); + + Assert.That(pdfDocFonts[1].FontName, assertEquals("CourierNewPSMT", ); + Assert.That(pdfDocFonts[1].IsEmbedded, assertEquals(pdfFontEmbeddingMode == PdfFontEmbeddingMode.EMBED_ALL || pdfFontEmbeddingMode == PdfFontEmbeddingMode.EMBED_NONSTANDARD, ); + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForEmbedWindowsFontsDataProvider") + public static Object[][] usePdfDocumentForEmbedWindowsFontsDataProvider() throws Exception + { + return new Object[][] + { + {PdfFontEmbeddingMode.EMBED_ALL}, + {PdfFontEmbeddingMode.EMBED_NONE}, + {PdfFontEmbeddingMode.EMBED_NONSTANDARD}, + }; + } + + @Test (dataProvider = "embedCoreFontsDataProvider") + public void embedCoreFonts(boolean useCoreFonts) throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.UseCoreFonts + //ExSummary:Shows how enable/disable PDF Type 1 font substitution. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Arial"); + builder.writeln("Hello world!"); + builder.getFont().setName("Courier New"); + builder.writeln("The quick brown fox jumps over the lazy dog."); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + // Set the "UseCoreFonts" property to "true" to replace some fonts, + // including the two fonts in our document, with their PDF Type 1 equivalents. + // Set the "UseCoreFonts" property to "false" to not apply PDF Type 1 fonts. + options.setUseCoreFonts(useCoreFonts); + + doc.save(getArtifactsDir() + "PdfSaveOptions.EmbedCoreFonts.pdf", options); + //ExEnd + + long testedFileLength = new FileInfo(getArtifactsDir() + "PdfSaveOptions.EmbedCoreFonts.pdf").getLength(); + if (useCoreFonts) + Assert.assertTrue(testedFileLength < 2000); + else + Assert.assertTrue(testedFileLength < 33500); + } + + //JAVA-added data provider for test method + @DataProvider(name = "embedCoreFontsDataProvider") + public static Object[][] embedCoreFontsDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "usePdfDocumentForEmbedCoreFontsDataProvider") + public void usePdfDocumentForEmbedCoreFonts(boolean useCoreFonts) throws Exception + { + embedCoreFonts(useCoreFonts); + + Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.EmbedCoreFonts.pdf"); + Aspose.Pdf.Text.Font[] pdfDocFonts = pdfDocument.FontUtilities.GetAllFonts(); + + if (useCoreFonts) + { + Assert.That(pdfDocFonts[0].FontName, assertEquals("Helvetica", ); + Assert.That(pdfDocFonts[1].FontName, assertEquals("Courier", ); + } + else + { + Assert.That(pdfDocFonts[0].FontName, assertEquals("ArialMT", ); + Assert.That(pdfDocFonts[1].FontName, assertEquals("CourierNewPSMT", ); + } + + Assert.That(pdfDocFonts[0].IsEmbedded, Is.Not.EqualTo(useCoreFonts)); + Assert.That(pdfDocFonts[1].IsEmbedded, Is.Not.EqualTo(useCoreFonts)); + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForEmbedCoreFontsDataProvider") + public static Object[][] usePdfDocumentForEmbedCoreFontsDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "additionalTextPositioningDataProvider") + public void additionalTextPositioning(boolean applyAdditionalTextPositioning) throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.AdditionalTextPositioning + //ExSummary:Show how to write additional text positioning operators. + Document doc = new Document(getMyDir() + "Text positioning operators.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + { + saveOptions.setTextCompression(PdfTextCompression.NONE); + + // Set the "AdditionalTextPositioning" property to "true" to attempt to fix incorrect + // element positioning in the output PDF, should there be any, at the cost of increased file size. + // Set the "AdditionalTextPositioning" property to "false" to render the document as usual. + saveOptions.setAdditionalTextPositioning(applyAdditionalTextPositioning); + } + + doc.save(getArtifactsDir() + "PdfSaveOptions.AdditionalTextPositioning.pdf", saveOptions); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "additionalTextPositioningDataProvider") + public static Object[][] additionalTextPositioningDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "usePdfDocumentForAdditionalTextPositioningDataProvider") + public void usePdfDocumentForAdditionalTextPositioning(boolean applyAdditionalTextPositioning) throws Exception + { + additionalTextPositioning(applyAdditionalTextPositioning); + + Aspose.Pdf.Document pdfDocument = + new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.AdditionalTextPositioning.pdf"); + TextFragmentAbsorber textAbsorber = new TextFragmentAbsorber(); + + pdfDocument.Pages[1].Accept(textAbsorber); + + SetGlyphsPositionShowText tjOperator = (SetGlyphsPositionShowText) textAbsorber.TextFragments[1].Page.Contents[71]; + + long testedFileLength = new FileInfo(getArtifactsDir() + "PdfSaveOptions.AdditionalTextPositioning.pdf").getLength(); + if (applyAdditionalTextPositioning) + { + Assert.assertTrue(testedFileLength < 102000); + Assert.That(tjOperator.ToString(), assertEquals("[0 (S) 0 (a) 0 (m) 0 (s) 0 (t) 0 (a) -1 (g) 1 (,) 0 ( ) 0 (1) 0 (0) 0 (.) 0 ( ) 0 (N) 0 (o) 0 (v) 0 (e) 0 (m) 0 (b) 0 (e) 0 (r) -1 ( ) 1 (2) -1 (0) 0 (1) 0 (8)] TJ", ); + } + else + { + Assert.assertTrue(testedFileLength < 99500); + Assert.That(tjOperator.ToString(), assertEquals("[(Samsta) -1 (g) 1 (, 10. November) -1 ( ) 1 (2) -1 (018)] TJ", ); + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForAdditionalTextPositioningDataProvider") + public static Object[][] usePdfDocumentForAdditionalTextPositioningDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "saveAsPdfBookFoldDataProvider") + public void saveAsPdfBookFold(boolean renderTextAsBookfold) throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.UseBookFoldPrintingSettings + //ExSummary:Shows how to save a document to the PDF format in the form of a book fold. + Document doc = new Document(getMyDir() + "Paragraphs.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "UseBookFoldPrintingSettings" property to "true" to arrange the contents + // in the output PDF in a way that helps us use it to make a booklet. + // Set the "UseBookFoldPrintingSettings" property to "false" to render the PDF normally. + options.setUseBookFoldPrintingSettings(renderTextAsBookfold); + + // If we are rendering the document as a booklet, we must set the "MultiplePages" + // properties of the page setup objects of all sections to "MultiplePagesType.BookFoldPrinting". + if (renderTextAsBookfold) + for (Section s : (Iterable
          ) doc.getSections()) + { + s.getPageSetup().setMultiplePages(MultiplePagesType.BOOK_FOLD_PRINTING); + } + + // Once we print this document on both sides of the pages, we can fold all the pages down the middle at once, + // and the contents will line up in a way that creates a booklet. + doc.save(getArtifactsDir() + "PdfSaveOptions.SaveAsPdfBookFold.pdf", options); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "saveAsPdfBookFoldDataProvider") + public static Object[][] saveAsPdfBookFoldDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "usePdfDocumentForSaveAsPdfBookFoldDataProvider") + public void usePdfDocumentForSaveAsPdfBookFold(boolean renderTextAsBookfold) throws Exception + { + saveAsPdfBookFold(renderTextAsBookfold); + + Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.SaveAsPdfBookFold.pdf"); + TextAbsorber textAbsorber = new TextAbsorber(); + + pdfDocument.Pages.Accept(textAbsorber); + + if (renderTextAsBookfold) + { + Assert.That(textAbsorber.Text.IndexOf("Heading #1", StringComparison.ORDINAL) < textAbsorber.Text.IndexOf("Heading #2", StringComparison.ORDINAL), assertTrue(); + Assert.That(textAbsorber.Text.IndexOf("Heading #2", StringComparison.ORDINAL) < textAbsorber.Text.IndexOf("Heading #3", StringComparison.ORDINAL), assertTrue(); + Assert.That(textAbsorber.Text.IndexOf("Heading #3", StringComparison.ORDINAL) < textAbsorber.Text.IndexOf("Heading #4", StringComparison.ORDINAL), assertTrue(); + Assert.That(textAbsorber.Text.IndexOf("Heading #4", StringComparison.ORDINAL) < textAbsorber.Text.IndexOf("Heading #5", StringComparison.ORDINAL), assertTrue(); + Assert.That(textAbsorber.Text.IndexOf("Heading #5", StringComparison.ORDINAL) < textAbsorber.Text.IndexOf("Heading #6", StringComparison.ORDINAL), assertTrue(); + Assert.That(textAbsorber.Text.IndexOf("Heading #6", StringComparison.ORDINAL) < textAbsorber.Text.IndexOf("Heading #7", StringComparison.ORDINAL), assertTrue(); + Assert.That(textAbsorber.Text.IndexOf("Heading #7", StringComparison.ORDINAL) < textAbsorber.Text.IndexOf("Heading #8", StringComparison.ORDINAL), assertFalse(); + Assert.That(textAbsorber.Text.IndexOf("Heading #8", StringComparison.ORDINAL) < textAbsorber.Text.IndexOf("Heading #9", StringComparison.ORDINAL), assertTrue(); + Assert.That(textAbsorber.Text.IndexOf("Heading #9", StringComparison.ORDINAL) < textAbsorber.Text.IndexOf("Heading #10", StringComparison.ORDINAL), assertFalse(); + } + else + { + Assert.That(textAbsorber.Text.IndexOf("Heading #1", StringComparison.ORDINAL) < textAbsorber.Text.IndexOf("Heading #2", StringComparison.ORDINAL), assertTrue(); + Assert.That(textAbsorber.Text.IndexOf("Heading #2", StringComparison.ORDINAL) < textAbsorber.Text.IndexOf("Heading #3", StringComparison.ORDINAL), assertTrue(); + Assert.That(textAbsorber.Text.IndexOf("Heading #3", StringComparison.ORDINAL) < textAbsorber.Text.IndexOf("Heading #4", StringComparison.ORDINAL), assertTrue(); + Assert.That(textAbsorber.Text.IndexOf("Heading #4", StringComparison.ORDINAL) < textAbsorber.Text.IndexOf("Heading #5", StringComparison.ORDINAL), assertTrue(); + Assert.That(textAbsorber.Text.IndexOf("Heading #5", StringComparison.ORDINAL) < textAbsorber.Text.IndexOf("Heading #6", StringComparison.ORDINAL), assertTrue(); + Assert.That(textAbsorber.Text.IndexOf("Heading #6", StringComparison.ORDINAL) < textAbsorber.Text.IndexOf("Heading #7", StringComparison.ORDINAL), assertTrue(); + Assert.That(textAbsorber.Text.IndexOf("Heading #7", StringComparison.ORDINAL) < textAbsorber.Text.IndexOf("Heading #8", StringComparison.ORDINAL), assertTrue(); + Assert.That(textAbsorber.Text.IndexOf("Heading #8", StringComparison.ORDINAL) < textAbsorber.Text.IndexOf("Heading #9", StringComparison.ORDINAL), assertTrue(); + Assert.That(textAbsorber.Text.IndexOf("Heading #9", StringComparison.ORDINAL) < textAbsorber.Text.IndexOf("Heading #10", StringComparison.ORDINAL), assertTrue(); + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForSaveAsPdfBookFoldDataProvider") + public static Object[][] usePdfDocumentForSaveAsPdfBookFoldDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void zoomBehaviour() throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.ZoomBehavior + //ExFor:PdfSaveOptions.ZoomFactor + //ExFor:PdfZoomBehavior + //ExSummary:Shows how to set the default zooming that a reader applies when opening a rendered PDF document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + // Set the "ZoomBehavior" property to "PdfZoomBehavior.ZoomFactor" to get a PDF reader to + // apply a percentage-based zoom factor when we open the document with it. + // Set the "ZoomFactor" property to "25" to give the zoom factor a value of 25%. + PdfSaveOptions options = new PdfSaveOptions(); + { + options.setZoomBehavior(PdfZoomBehavior.ZOOM_FACTOR); + options.setZoomFactor(25); + } + + // When we open this document using a reader such as Adobe Acrobat, we will see the document scaled at 1/4 of its actual size. + doc.save(getArtifactsDir() + "PdfSaveOptions.ZoomBehaviour.pdf", options); + //ExEnd + } + + @Test + public void usePdfDocumentForZoomBehaviour() throws Exception + { + zoomBehaviour(); + + Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.ZoomBehaviour.pdf"); + GoToAction action = (GoToAction)pdfDocument.OpenAction; + + Assert.That((ms.as(action.Destination, XYZExplicitDestination.class)).Zoom, assertEquals(0.25d, ); + } + + @Test (dataProvider = "pageModeDataProvider") + public void pageMode(/*PdfPageMode*/int pageMode) throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.PageMode + //ExFor:PdfPageMode + //ExSummary:Shows how to set instructions for some PDF readers to follow when opening an output document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "PageMode" property to "PdfPageMode.FullScreen" to get the PDF reader to open the saved + // document in full-screen mode, which takes over the monitor's display and has no controls visible. + // Set the "PageMode" property to "PdfPageMode.UseThumbs" to get the PDF reader to display a separate panel + // with a thumbnail for each page in the document. + // Set the "PageMode" property to "PdfPageMode.UseOC" to get the PDF reader to display a separate panel + // that allows us to work with any layers present in the document. + // Set the "PageMode" property to "PdfPageMode.UseOutlines" to get the PDF reader + // also to display the outline, if possible. + // Set the "PageMode" property to "PdfPageMode.UseNone" to get the PDF reader to display just the document itself. + // Set the "PageMode" property to "PdfPageMode.UseAttachments" to make visible attachments panel. + options.setPageMode(pageMode); + + doc.save(getArtifactsDir() + "PdfSaveOptions.PageMode.pdf", options); + //ExEnd + + String docLocaleName = new msCultureInfo(doc.getStyles().getDefaultFont().getLocaleId()).getName(); + + switch (pageMode) + { + case PdfPageMode.FULL_SCREEN: + TestUtil.fileContainsString( + $"<>\r\n", + getArtifactsDir() + "PdfSaveOptions.PageMode.pdf"); + break; + case PdfPageMode.USE_THUMBS: + TestUtil.fileContainsString( + $"<>", + getArtifactsDir() + "PdfSaveOptions.PageMode.pdf"); + break; + case PdfPageMode.USE_OC: + TestUtil.fileContainsString( + $"<>\r\n", + getArtifactsDir() + "PdfSaveOptions.PageMode.pdf"); + break; + case PdfPageMode.USE_OUTLINES: + case PdfPageMode.USE_NONE: + TestUtil.fileContainsString($"<>\r\n", + getArtifactsDir() + "PdfSaveOptions.PageMode.pdf"); + break; + case PdfPageMode.USE_ATTACHMENTS: + TestUtil.fileContainsString( + $"<>\r\n", + getArtifactsDir() + "PdfSaveOptions.PageMode.pdf"); + break; + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "pageModeDataProvider") + public static Object[][] pageModeDataProvider() throws Exception + { + return new Object[][] + { + {PdfPageMode.FULL_SCREEN}, + {PdfPageMode.USE_THUMBS}, + {PdfPageMode.USE_OC}, + {PdfPageMode.USE_OUTLINES}, + {PdfPageMode.USE_NONE}, + {PdfPageMode.USE_ATTACHMENTS}, + }; + } + + @Test (dataProvider = "usePdfDocumentForPageModeDataProvider") + public void usePdfDocumentForPageMode(/*PdfPageMode*/int pageMode) throws Exception + { + pageMode(pageMode); + + Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.PageMode.pdf"); + + switch (pageMode) + { + case PdfPageMode.USE_NONE: + case PdfPageMode.USE_OUTLINES: + Assert.That(pdfDocument.PageMode, Is.EqualTo(Aspose.Pdf.PageMode.UseNone)); + break; + case PdfPageMode.USE_THUMBS: + Assert.That(pdfDocument.PageMode, Is.EqualTo(Aspose.Pdf.PageMode.UseThumbs)); + break; + case PdfPageMode.FULL_SCREEN: + Assert.That(pdfDocument.PageMode, Is.EqualTo(Aspose.Pdf.PageMode.FullScreen)); + break; + case PdfPageMode.USE_OC: + Assert.That(pdfDocument.PageMode, Is.EqualTo(Aspose.Pdf.PageMode.UseOC)); + break; + case PdfPageMode.USE_ATTACHMENTS: + Assert.That(pdfDocument.PageMode, Is.EqualTo(Aspose.Pdf.PageMode.UseAttachments)); + break; + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForPageModeDataProvider") + public static Object[][] usePdfDocumentForPageModeDataProvider() throws Exception + { + return new Object[][] + { + {PdfPageMode.FULL_SCREEN}, + {PdfPageMode.USE_THUMBS}, + {PdfPageMode.USE_OC}, + {PdfPageMode.USE_OUTLINES}, + {PdfPageMode.USE_NONE}, + {PdfPageMode.USE_ATTACHMENTS}, + }; + } + + @Test (dataProvider = "noteHyperlinksDataProvider") + public void noteHyperlinks(boolean createNoteHyperlinks) throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.CreateNoteHyperlinks + //ExSummary:Shows how to make footnotes and endnotes function as hyperlinks. + Document doc = new Document(getMyDir() + "Footnotes and endnotes.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "CreateNoteHyperlinks" property to "true" to turn all footnote/endnote symbols + // in the text act as links that, upon clicking, take us to their respective footnotes/endnotes. + // Set the "CreateNoteHyperlinks" property to "false" not to have footnote/endnote symbols link to anything. + options.setCreateNoteHyperlinks(createNoteHyperlinks); + + doc.save(getArtifactsDir() + "PdfSaveOptions.NoteHyperlinks.pdf", options); + //ExEnd + + if (createNoteHyperlinks) + { + TestUtil.fileContainsString( + "<>/Dest[5 0 R /XYZ 85 677 0]>>", + getArtifactsDir() + "PdfSaveOptions.NoteHyperlinks.pdf"); + TestUtil.fileContainsString( + "<>/Dest[5 0 R /XYZ 85 79 0]>>", + getArtifactsDir() + "PdfSaveOptions.NoteHyperlinks.pdf"); + TestUtil.fileContainsString( + "<>/Dest[5 0 R /XYZ 85 654 0]>>", + getArtifactsDir() + "PdfSaveOptions.NoteHyperlinks.pdf"); + TestUtil.fileContainsString( + "<>/Dest[5 0 R /XYZ 85 68 0]>>", + getArtifactsDir() + "PdfSaveOptions.NoteHyperlinks.pdf"); + TestUtil.fileContainsString( + "<>/Dest[5 0 R /XYZ 202 733 0]>>", + getArtifactsDir() + "PdfSaveOptions.NoteHyperlinks.pdf"); + TestUtil.fileContainsString( + "<>/Dest[5 0 R /XYZ 258 711 0]>>", + getArtifactsDir() + "PdfSaveOptions.NoteHyperlinks.pdf"); + TestUtil.fileContainsString( + "<>/Dest[5 0 R /XYZ 157 733 0]>>", + getArtifactsDir() + "PdfSaveOptions.NoteHyperlinks.pdf"); + TestUtil.fileContainsString( + "<>/Dest[5 0 R /XYZ 212 711 0]>>", + getArtifactsDir() + "PdfSaveOptions.NoteHyperlinks.pdf"); + } + else + { + if (!isRunningOnMono()) + Assert.Throws(() => + TestUtil.fileContainsString("< linkAnnotations = annotationSelector.Selected.Cast().ToList(); + + if (createNoteHyperlinks) + { + Assert.That(linkAnnotations.Count(a => a.AnnotationType == AnnotationType.Link), assertEquals(8, ); + + Assert.That(linkAnnotations.get(0).Destination.ToString(), assertEquals("1 XYZ 85 677 0", ); + Assert.That(linkAnnotations.get(1).Destination.ToString(), assertEquals("1 XYZ 85 79 0", ); + Assert.That(linkAnnotations.get(2).Destination.ToString(), assertEquals("1 XYZ 85 654 0", ); + Assert.That(linkAnnotations.get(3).Destination.ToString(), assertEquals("1 XYZ 85 68 0", ); + Assert.That(linkAnnotations.get(4).Destination.ToString(), assertEquals("1 XYZ 202 733 0", ); + Assert.That(linkAnnotations.get(5).Destination.ToString(), assertEquals("1 XYZ 258 711 0", ); + Assert.That(linkAnnotations.get(6).Destination.ToString(), assertEquals("1 XYZ 157 733 0", ); + Assert.That(linkAnnotations.get(7).Destination.ToString(), assertEquals("1 XYZ 212 711 0", ); + } + else + { + Assert.That(annotationSelector.Selected.Count, assertEquals(0, ); + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForNoteHyperlinksDataProvider") + public static Object[][] usePdfDocumentForNoteHyperlinksDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "customPropertiesExportDataProvider") + public void customPropertiesExport(/*PdfCustomPropertiesExport*/int pdfCustomPropertiesExportMode) throws Exception + { + //ExStart + //ExFor:PdfCustomPropertiesExport + //ExFor:PdfSaveOptions.CustomPropertiesExport + //ExSummary:Shows how to export custom properties while converting a document to PDF. + Document doc = new Document(); + + doc.getCustomDocumentProperties().add("Company", "My value"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "CustomPropertiesExport" property to "PdfCustomPropertiesExport.None" to discard + // custom document properties as we save the document to .PDF. + // Set the "CustomPropertiesExport" property to "PdfCustomPropertiesExport.Standard" + // to preserve custom properties within the output PDF document. + // Set the "CustomPropertiesExport" property to "PdfCustomPropertiesExport.Metadata" + // to preserve custom properties in an XMP packet. + options.setCustomPropertiesExport(pdfCustomPropertiesExportMode); + + doc.save(getArtifactsDir() + "PdfSaveOptions.CustomPropertiesExport.pdf", options); + //ExEnd + + switch (pdfCustomPropertiesExportMode) + { + case PdfCustomPropertiesExport.NONE: + if (!isRunningOnMono()) + { + Assert.Throws(() => TestUtil.fileContainsString( + doc.getCustomDocumentProperties().get(0).getName(), + getArtifactsDir() + "PdfSaveOptions.CustomPropertiesExport.pdf")); + Assert.Throws(() => TestUtil.fileContainsString( + "<>", + getArtifactsDir() + "PdfSaveOptions.CustomPropertiesExport.pdf")); + } + + break; + case PdfCustomPropertiesExport.STANDARD: + TestUtil.fileContainsString( + "<>", + getArtifactsDir() + "PdfSaveOptions.CustomPropertiesExport.pdf"); + break; + case PdfCustomPropertiesExport.METADATA: + TestUtil.fileContainsString("<>", + getArtifactsDir() + "PdfSaveOptions.CustomPropertiesExport.pdf"); + break; + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "customPropertiesExportDataProvider") + public static Object[][] customPropertiesExportDataProvider() throws Exception + { + return new Object[][] + { + {PdfCustomPropertiesExport.NONE}, + {PdfCustomPropertiesExport.STANDARD}, + {PdfCustomPropertiesExport.METADATA}, + }; + } + + @Test (dataProvider = "usePdfDocumentForCustomPropertiesExportDataProvider") + public void usePdfDocumentForCustomPropertiesExport(/*PdfCustomPropertiesExport*/int pdfCustomPropertiesExportMode) throws Exception + { + customPropertiesExport(pdfCustomPropertiesExportMode); + + Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.CustomPropertiesExport.pdf"); + + Assert.That(pdfDocument.Info.Creator, assertEquals("Aspose.Words", ); + Assert.That(pdfDocument.Info.Producer.StartsWith("Aspose.Words"), assertTrue(); + + switch (pdfCustomPropertiesExportMode) + { + case PdfCustomPropertiesExport.NONE: + Assert.That(pdfDocument.Info.Count, assertEquals(2, ); + Assert.That(pdfDocument.Metadata.Count, assertEquals(3, ); + break; + case PdfCustomPropertiesExport.METADATA: + Assert.That(pdfDocument.Info.Count, assertEquals(2, ); + Assert.That(pdfDocument.Metadata.Count, assertEquals(4, ); + + Assert.That(pdfDocument.Metadata["xmp:CreatorTool"].ToString(), assertEquals("Aspose.Words", ); + Assert.That(pdfDocument.Metadata["custprops:Property1"].ToString(), assertEquals("Company", ); + break; + case PdfCustomPropertiesExport.STANDARD: + Assert.That(pdfDocument.Info.Count, assertEquals(3, ); + Assert.That(pdfDocument.Metadata.Count, assertEquals(3, ); + + Assert.That(pdfDocument.Info["Company"], assertEquals("My value", ); + break; + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForCustomPropertiesExportDataProvider") + public static Object[][] usePdfDocumentForCustomPropertiesExportDataProvider() throws Exception + { + return new Object[][] + { + {PdfCustomPropertiesExport.NONE}, + {PdfCustomPropertiesExport.STANDARD}, + {PdfCustomPropertiesExport.METADATA}, + }; + } + + @Test (dataProvider = "drawingMLEffectsDataProvider") + public void drawingMLEffects(/*DmlEffectsRenderingMode*/int effectsRenderingMode) throws Exception + { + //ExStart + //ExFor:DmlRenderingMode + //ExFor:DmlEffectsRenderingMode + //ExFor:PdfSaveOptions.DmlEffectsRenderingMode + //ExFor:SaveOptions.DmlEffectsRenderingMode + //ExFor:SaveOptions.DmlRenderingMode + //ExSummary:Shows how to configure the rendering quality of DrawingML effects in a document as we save it to PDF. + Document doc = new Document(getMyDir() + "DrawingML shape effects.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "DmlEffectsRenderingMode" property to "DmlEffectsRenderingMode.None" to discard all DrawingML effects. + // Set the "DmlEffectsRenderingMode" property to "DmlEffectsRenderingMode.Simplified" + // to render a simplified version of DrawingML effects. + // Set the "DmlEffectsRenderingMode" property to "DmlEffectsRenderingMode.Fine" to + // render DrawingML effects with more accuracy and also with more processing cost. + options.setDmlEffectsRenderingMode(effectsRenderingMode); + + Assert.assertEquals(DmlRenderingMode.DRAWING_ML, options.getDmlRenderingMode()); + + doc.save(getArtifactsDir() + "PdfSaveOptions.DrawingMLEffects.pdf", options); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "drawingMLEffectsDataProvider") + public static Object[][] drawingMLEffectsDataProvider() throws Exception + { + return new Object[][] + { + {DmlEffectsRenderingMode.NONE}, + {DmlEffectsRenderingMode.SIMPLIFIED}, + {DmlEffectsRenderingMode.FINE}, + }; + } + + @Test (dataProvider = "usePdfDocumentForDrawingMLEffectsDataProvider") + public void usePdfDocumentForDrawingMLEffects(/*DmlEffectsRenderingMode*/int effectsRenderingMode) throws Exception + { + drawingMLEffects(effectsRenderingMode); + + Aspose.Pdf.Document pdfDocument = + new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.DrawingMLEffects.pdf"); + + ImagePlacementAbsorber imagePlacementAbsorber = new ImagePlacementAbsorber(); + imagePlacementAbsorber.Visit(pdfDocument.Pages[1]); + + TableAbsorber tableAbsorber = new TableAbsorber(); + tableAbsorber.Visit(pdfDocument.Pages[1]); + + switch (effectsRenderingMode) + { + case DmlEffectsRenderingMode.NONE: + case DmlEffectsRenderingMode.SIMPLIFIED: + TestUtil.fileContainsString("<>>>/Group<>>>", + getArtifactsDir() + "PdfSaveOptions.DrawingMLEffects.pdf"); + Assert.That(imagePlacementAbsorber.ImagePlacements.Count, assertEquals(0, ); + Assert.That(tableAbsorber.TableList.Count, assertEquals(28, ); + break; + case DmlEffectsRenderingMode.FINE: + TestUtil.fileContainsString( + "<>/XObject<>>>/Group<>>>", + getArtifactsDir() + "PdfSaveOptions.DrawingMLEffects.pdf"); + Assert.That(imagePlacementAbsorber.ImagePlacements.Count, assertEquals(21, ); + Assert.That(tableAbsorber.TableList.Count, assertEquals(4, ); + break; + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForDrawingMLEffectsDataProvider") + public static Object[][] usePdfDocumentForDrawingMLEffectsDataProvider() throws Exception + { + return new Object[][] + { + {DmlEffectsRenderingMode.NONE}, + {DmlEffectsRenderingMode.SIMPLIFIED}, + {DmlEffectsRenderingMode.FINE}, + }; + } + + @Test (dataProvider = "drawingMLFallbackDataProvider") + public void drawingMLFallback(/*DmlRenderingMode*/int dmlRenderingMode) throws Exception + { + //ExStart + //ExFor:DmlRenderingMode + //ExFor:SaveOptions.DmlRenderingMode + //ExSummary:Shows how to render fallback shapes when saving to PDF. + Document doc = new Document(getMyDir() + "DrawingML shape fallbacks.docx"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "DmlRenderingMode" property to "DmlRenderingMode.Fallback" + // to substitute DML shapes with their fallback shapes. + // Set the "DmlRenderingMode" property to "DmlRenderingMode.DrawingML" + // to render the DML shapes themselves. + options.setDmlRenderingMode(dmlRenderingMode); + + doc.save(getArtifactsDir() + "PdfSaveOptions.DrawingMLFallback.pdf", options); + //ExEnd + + switch (dmlRenderingMode) + { + case DmlRenderingMode.DRAWING_ML: + TestUtil.fileContainsString( + "<>>>/Group<>>>", + getArtifactsDir() + "PdfSaveOptions.DrawingMLFallback.pdf"); + break; + case DmlRenderingMode.FALLBACK: + TestUtil.fileContainsString( + "<>/ExtGState<>>>/Group<>>>", + getArtifactsDir() + "PdfSaveOptions.DrawingMLFallback.pdf"); + break; + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "drawingMLFallbackDataProvider") + public static Object[][] drawingMLFallbackDataProvider() throws Exception + { + return new Object[][] + { + {DmlRenderingMode.FALLBACK}, + {DmlRenderingMode.DRAWING_ML}, + }; + } + + @Test (dataProvider = "usePdfDocumentForDrawingMLFallbackDataProvider") + public void usePdfDocumentForDrawingMLFallback(/*DmlRenderingMode*/int dmlRenderingMode) throws Exception + { + drawingMLFallback(dmlRenderingMode); + + Aspose.Pdf.Document pdfDocument = + new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.DrawingMLFallback.pdf"); + + ImagePlacementAbsorber imagePlacementAbsorber = new ImagePlacementAbsorber(); + imagePlacementAbsorber.Visit(pdfDocument.Pages[1]); + + TableAbsorber tableAbsorber = new TableAbsorber(); + tableAbsorber.Visit(pdfDocument.Pages[1]); + + switch (dmlRenderingMode) + { + case DmlRenderingMode.DRAWING_ML: + Assert.That(tableAbsorber.TableList.Count, assertEquals(6, ); + break; + case DmlRenderingMode.FALLBACK: + Assert.That(tableAbsorber.TableList.Count, assertEquals(12, ); + break; + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForDrawingMLFallbackDataProvider") + public static Object[][] usePdfDocumentForDrawingMLFallbackDataProvider() throws Exception + { + return new Object[][] + { + {DmlRenderingMode.FALLBACK}, + {DmlRenderingMode.DRAWING_ML}, + }; + } + + @Test (dataProvider = "exportDocumentStructureDataProvider") + public void exportDocumentStructure(boolean exportDocumentStructure) throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.ExportDocumentStructure + //ExSummary:Shows how to preserve document structure elements, which can assist in programmatically interpreting our document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 1")); + builder.writeln("Hello world!"); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Normal")); + builder.write( + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + // Set the "ExportDocumentStructure" property to "true" to make the document structure, such tags, available via the + // "Content" navigation pane of Adobe Acrobat at the cost of increased file size. + // Set the "ExportDocumentStructure" property to "false" to not export the document structure. + options.setExportDocumentStructure(exportDocumentStructure); + + // Suppose we export document structure while saving this document. In that case, + // we can open it using Adobe Acrobat and find tags for elements such as the heading + // and the next paragraph via "View" -> "Show/Hide" -> "Navigation panes" -> "Tags". + doc.save(getArtifactsDir() + "PdfSaveOptions.ExportDocumentStructure.pdf", options); + //ExEnd + + if (exportDocumentStructure) + { + TestUtil.fileContainsString("<>/ExtGState<>>>/Group<>/StructParents 0/Tabs/S>>", + getArtifactsDir() + "PdfSaveOptions.ExportDocumentStructure.pdf"); + } + else + { + TestUtil.fileContainsString("<>>>/Group<>>>", + getArtifactsDir() + "PdfSaveOptions.ExportDocumentStructure.pdf"); + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "exportDocumentStructureDataProvider") + public static Object[][] exportDocumentStructureDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "preblendImagesDataProvider") + public void preblendImages(boolean preblendImages) throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.PreblendImages + //ExSummary:Shows how to preblend images with transparent backgrounds while saving a document to PDF. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertImage(getImageDir() + "Transparent background logo.png"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + // Set the "PreblendImages" property to "true" to preblend transparent images + // with a background, which may reduce artifacts. + // Set the "PreblendImages" property to "false" to render transparent images normally. + options.setPreblendImages(preblendImages); + + doc.save(getArtifactsDir() + "PdfSaveOptions.PreblendImages.pdf", options); + //ExEnd + + Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.PreblendImages.pdf"); + XImage image = pdfDocument.Pages[1].Resources.Images[1]; + + MemoryStream stream = new MemoryStream(); + try /*JAVA: was using*/ + { + image.Save(stream); + + if (preblendImages) + { + Assert.assertEquals(17890, stream.getLength()); + } + else + { + Assert.assertTrue(stream.getLength() < 19500); + } + } + finally { if (stream != null) stream.close(); } + } + + //JAVA-added data provider for test method + @DataProvider(name = "preblendImagesDataProvider") + public static Object[][] preblendImagesDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "interpolateImagesDataProvider") + public void interpolateImages(boolean interpolateImages) throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.InterpolateImages + //ExSummary:Shows how to perform interpolation on images while saving a document to PDF. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertImage(getImageDir() + "Transparent background logo.png"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + // Set the "InterpolateImages" property to "true" to get the reader that opens this document to interpolate images. + // Their resolution should be lower than that of the device that is displaying the document. + // Set the "InterpolateImages" property to "false" to make it so that the reader does not apply any interpolation. + saveOptions.setInterpolateImages(interpolateImages); + + // When we open this document with a reader such as Adobe Acrobat, we will need to zoom in on the image + // to see the interpolation effect if we saved the document with it enabled. + doc.save(getArtifactsDir() + "PdfSaveOptions.InterpolateImages.pdf", saveOptions); + //ExEnd + + if (interpolateImages) + { + TestUtil.fileContainsString("<>", + getArtifactsDir() + "PdfSaveOptions.InterpolateImages.pdf"); + } + else + { + TestUtil.fileContainsString("<>", + getArtifactsDir() + "PdfSaveOptions.InterpolateImages.pdf"); + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "interpolateImagesDataProvider") + public static Object[][] interpolateImagesDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (groups = "SkipMono") + public void dml3DEffectsRenderingModeTest() throws Exception + { + //ExStart + //ExFor:Dml3DEffectsRenderingMode + //ExFor:SaveOptions.Dml3DEffectsRenderingMode + //ExSummary:Shows how 3D effects are rendered. + Document doc = new Document(getMyDir() + "DrawingML shape 3D effects.docx"); + + RenderCallback warningCallback = new RenderCallback(); + doc.setWarningCallback(warningCallback); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setDml3DEffectsRenderingMode(Dml3DEffectsRenderingMode.ADVANCED); + + doc.save(getArtifactsDir() + "PdfSaveOptions.Dml3DEffectsRenderingModeTest.pdf", saveOptions); + //ExEnd + + Assert.That(48, Is.EqualTo(warningCallback.Count)); + } + + public static class RenderCallback implements IWarningCallback + { + public void warning(WarningInfo info) + { + System.out.println("{info.WarningType}: {info.Description}."); + mWarnings.Add(info); + } + + !!Autoporter error: Indexer ApiExamples.ExPdfSaveOptions.RenderCallback.Item(int) hasn't both getter and setter! + mWarnings.Clear(); + } + + public int Count => private mWarnings.CountmWarnings; + + /// + /// Returns true if a warning with the specified properties has been generated. + /// + public boolean contains(/*WarningSource*/int source, /*WarningType*/int type, String description) + { + return mWarnings.Any(warning => + warning.Source == source && warning.WarningType == type && warning.Description == description); + } + + private /*final*/ ArrayList mWarnings = new ArrayList(); + } + + @Test + public void pdfDigitalSignature() throws Exception + { + //ExStart + //ExFor:PdfDigitalSignatureDetails + //ExFor:PdfDigitalSignatureDetails.#ctor + //ExFor:PdfDigitalSignatureDetails.#ctor(CertificateHolder, String, String, DateTime) + //ExFor:PdfDigitalSignatureDetails.HashAlgorithm + //ExFor:PdfDigitalSignatureDetails.Location + //ExFor:PdfDigitalSignatureDetails.Reason + //ExFor:PdfDigitalSignatureDetails.SignatureDate + //ExFor:PdfDigitalSignatureHashAlgorithm + //ExFor:PdfSaveOptions.DigitalSignatureDetails + //ExFor:PdfDigitalSignatureDetails.CertificateHolder + //ExSummary:Shows how to sign a generated PDF document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Contents of signed PDF."); + + CertificateHolder certificateHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Configure the "DigitalSignatureDetails" object of the "SaveOptions" object to + // digitally sign the document as we render it with the "Save" method. + DateTime signingTime = new DateTime(2015, 7, 20); + options.setDigitalSignatureDetails(new PdfDigitalSignatureDetails(certificateHolder, "Test Signing", "My Office", signingTime)); + options.getDigitalSignatureDetails().setHashAlgorithm(PdfDigitalSignatureHashAlgorithm.RIPE_MD_160); + + Assert.assertEquals("Test Signing", options.getDigitalSignatureDetails().getReason()); + Assert.assertEquals("My Office", options.getDigitalSignatureDetails().getLocation()); + Assert.assertEquals(signingTime, options.getDigitalSignatureDetails().getSignatureDateInternal().toLocalTime()); + Assert.assertEquals(certificateHolder, options.getDigitalSignatureDetails().getCertificateHolder()); + + doc.save(getArtifactsDir() + "PdfSaveOptions.PdfDigitalSignature.pdf", options); + //ExEnd + + TestUtil.fileContainsString("<>>>/Group<>>>", + getArtifactsDir() + "PdfSaveOptions.RenderMetafile.pdf"); + break; + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForRenderMetafileDataProvider") + public static Object[][] usePdfDocumentForRenderMetafileDataProvider() throws Exception + { + return new Object[][] + { + {EmfPlusDualRenderingMode.EMF}, + {EmfPlusDualRenderingMode.EMF_PLUS}, + {EmfPlusDualRenderingMode.EMF_PLUS_WITH_FALLBACK}, + }; + } + + @Test + public void encryptionPermissions() throws Exception + { + //ExStart + //ExFor:PdfEncryptionDetails.#ctor(String,String,PdfPermissions) + //ExFor:PdfSaveOptions.EncryptionDetails + //ExFor:PdfEncryptionDetails.Permissions + //ExFor:PdfEncryptionDetails.OwnerPassword + //ExFor:PdfEncryptionDetails.UserPassword + //ExFor:PdfPermissions + //ExFor:PdfEncryptionDetails + //ExSummary:Shows how to set permissions on a saved PDF document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + + // Extend permissions to allow the editing of annotations. + PdfEncryptionDetails encryptionDetails = + new PdfEncryptionDetails("password", "", PdfPermissions.MODIFY_ANNOTATIONS | PdfPermissions.DOCUMENT_ASSEMBLY); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + // Enable encryption via the "EncryptionDetails" property. + saveOptions.setEncryptionDetails(encryptionDetails); + + // When we open this document, we will need to provide the password before accessing its contents. + doc.save(getArtifactsDir() + "PdfSaveOptions.EncryptionPermissions.pdf", saveOptions); + //ExEnd + } + + @Test + public void usePdfDocumentForEncryptionPermissions() throws Exception + { + encryptionPermissions(); + + Aspose.Pdf.Document pdfDocument; + + Assert.Throws(() => + pdfDocument = new Aspose.Pdf.Document(ArtifactsDir + "PdfSaveOptions.EncryptionPermissions.pdf")); + + pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.EncryptionPermissions.pdf", "password"); + TextFragmentAbsorber textAbsorber = new TextFragmentAbsorber(); + + pdfDocument.Pages[1].Accept(textAbsorber); + + Assert.That(textAbsorber.Text, assertEquals("Hello world!", ); + } + + @Test (dataProvider = "setNumeralFormatDataProvider") + public void setNumeralFormat(/*NumeralFormat*/int numeralFormat) throws Exception + { + //ExStart + //ExFor:FixedPageSaveOptions.NumeralFormat + //ExFor:NumeralFormat + //ExSummary:Shows how to set the numeral format used when saving to PDF. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setLocaleId(new msCultureInfo("ar-AR").getLCID()); + builder.writeln("1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 50, 100"); + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Set the "NumeralFormat" property to "NumeralFormat.ArabicIndic" to + // use glyphs from the U+0660 to U+0669 range as numbers. + // Set the "NumeralFormat" property to "NumeralFormat.Context" to + // look up the locale to determine what number of glyphs to use. + // Set the "NumeralFormat" property to "NumeralFormat.EasternArabicIndic" to + // use glyphs from the U+06F0 to U+06F9 range as numbers. + // Set the "NumeralFormat" property to "NumeralFormat.European" to use european numerals. + // Set the "NumeralFormat" property to "NumeralFormat.System" to determine the symbol set from regional settings. + options.setNumeralFormat(numeralFormat); + + doc.save(getArtifactsDir() + "PdfSaveOptions.SetNumeralFormat.pdf", options); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "setNumeralFormatDataProvider") + public static Object[][] setNumeralFormatDataProvider() throws Exception + { + return new Object[][] + { + {NumeralFormat.ARABIC_INDIC}, + {NumeralFormat.CONTEXT}, + {NumeralFormat.EASTERN_ARABIC_INDIC}, + {NumeralFormat.EUROPEAN}, + {NumeralFormat.SYSTEM}, + }; + } + + @Test (dataProvider = "usePdfDocumentForSetNumeralFormatDataProvider") + public void usePdfDocumentForSetNumeralFormat(/*NumeralFormat*/int numeralFormat) throws Exception + { + setNumeralFormat(numeralFormat); + + Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.SetNumeralFormat.pdf"); + TextFragmentAbsorber textAbsorber = new TextFragmentAbsorber(); + + pdfDocument.Pages[1].Accept(textAbsorber); + + switch (numeralFormat) + { + case NumeralFormat.EUROPEAN: + Assert.That(textAbsorber.Text, assertEquals("1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 50, 100", ); + break; + case NumeralFormat.ARABIC_INDIC: + Assert.That(textAbsorber.Text, assertEquals(", ٢, ٣, ٤, ٥, ٦, ٧, ٨, ٩, ١٠, ٥٠, ١١٠٠", ); + break; + case NumeralFormat.EASTERN_ARABIC_INDIC: + Assert.That(textAbsorber.Text, assertEquals("۱۰۰ ,۵۰ ,۱۰ ,۹ ,۸ ,۷ ,۶ ,۵ ,۴ ,۳ ,۲ ,۱", ); + break; + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "usePdfDocumentForSetNumeralFormatDataProvider") + public static Object[][] usePdfDocumentForSetNumeralFormatDataProvider() throws Exception + { + return new Object[][] + { + {NumeralFormat.ARABIC_INDIC}, + {NumeralFormat.CONTEXT}, + {NumeralFormat.EASTERN_ARABIC_INDIC}, + {NumeralFormat.EUROPEAN}, + {NumeralFormat.SYSTEM}, + }; + } + + @Test + public void exportPageSet() throws Exception + { + //ExStart + //ExFor:FixedPageSaveOptions.PageSet + //ExFor:PageSet.All + //ExFor:PageSet.Even + //ExFor:PageSet.Odd + //ExSummary:Shows how to export Odd pages from the document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + for (int i = 0; i < 5; i++) + { + builder.writeln($"Page {i + 1} ({(i % 2 == 0 ? "odd" : "even")})"); + if (i < 4) + builder.insertBreak(BreakType.PAGE_BREAK); + } + + // Create a "PdfSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to .PDF. + PdfSaveOptions options = new PdfSaveOptions(); + + // Below are three PageSet properties that we can use to filter out a set of pages from + // our document to save in an output PDF document based on the parity of their page numbers. + // 1 - Save only the even-numbered pages: + options.setPageSet(PageSet.getEven()); + + doc.save(getArtifactsDir() + "PdfSaveOptions.ExportPageSet.Even.pdf", options); + + // 2 - Save only the odd-numbered pages: + options.setPageSet(PageSet.getOdd()); + + doc.save(getArtifactsDir() + "PdfSaveOptions.ExportPageSet.Odd.pdf", options); + + // 3 - Save every page: + options.setPageSet(PageSet.getAll()); + + doc.save(getArtifactsDir() + "PdfSaveOptions.ExportPageSet.All.pdf", options); + //ExEnd + } + + @Test + public void usePdfDocumentForExportPageSet() throws Exception + { + exportPageSet(); + + Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.ExportPageSet.Even.pdf"); + TextAbsorber textAbsorber = new TextAbsorber(); + pdfDocument.Pages.Accept(textAbsorber); + + Assert.That(textAbsorber.Text, assertEquals("Page 2 (even)\r\n" + + "Page 4 (even)", ); + + pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.ExportPageSet.Odd.pdf"); + textAbsorber = new TextAbsorber(); + pdfDocument.Pages.Accept(textAbsorber); + + Assert.That(textAbsorber.Text, assertEquals("Page 1 (odd)\r\n" + + "Page 3 (odd)\r\n" + + "Page 5 (odd)", ); + + pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.ExportPageSet.All.pdf"); + textAbsorber = new TextAbsorber(); + pdfDocument.Pages.Accept(textAbsorber); + + Assert.That(textAbsorber.Text, assertEquals("Page 1 (odd)\r\n" + + "Page 2 (even)\r\n" + + "Page 3 (odd)\r\n" + + "Page 4 (even)\r\n" + + "Page 5 (odd)", ); + } + + @Test + public void exportLanguageToSpanTag() throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.ExportLanguageToSpanTag + //ExSummary:Shows how to create a "Span" tag in the document structure to export the text language. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + builder.writeln("Hola mundo!"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + { + // Note, when "ExportDocumentStructure" is false, "ExportLanguageToSpanTag" is ignored. + saveOptions.setExportDocumentStructure(true); saveOptions.setExportLanguageToSpanTag(true); + } + + doc.save(getArtifactsDir() + "PdfSaveOptions.ExportLanguageToSpanTag.pdf", saveOptions); + //ExEnd + } + + @Test + public void attachmentsEmbeddingMode() throws Exception + { + //ExStart:AttachmentsEmbeddingMode + //GistId:1a265b92fa0019b26277ecfef3c20330 + //ExFor:PdfSaveOptions.AttachmentsEmbeddingMode + //ExSummary:Shows how to add embed attachments to the PDF document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertOleObjectInternal(getMyDir() + "Spreadsheet.xlsx", "Excel.Sheet", false, true, null); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setAttachmentsEmbeddingMode(PdfAttachmentsEmbeddingMode.ANNOTATIONS); + + doc.save(getArtifactsDir() + "PdfSaveOptions.AttachmentsEmbeddingMode.pdf", saveOptions); + //ExEnd:AttachmentsEmbeddingMode + } + + @Test + public void cacheBackgroundGraphics() throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.CacheBackgroundGraphics + //ExSummary:Shows how to cache graphics placed in document's background. + Document doc = new Document(getMyDir() + "Background images.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setCacheBackgroundGraphics(true); + + doc.save(getArtifactsDir() + "PdfSaveOptions.CacheBackgroundGraphics.pdf", saveOptions); + + long asposeToPdfSize = new FileInfo(getArtifactsDir() + "PdfSaveOptions.CacheBackgroundGraphics.pdf").getLength(); + long wordToPdfSize = new FileInfo(getMyDir() + "Background images (word to pdf).pdf").getLength(); + + Assert.greater(wordToPdfSize, asposeToPdfSize); + //ExEnd + } + + @Test + public void exportParagraphGraphicsToArtifact() throws Exception + { + //ExStart + //ExFor:PdfSaveOptions.ExportParagraphGraphicsToArtifact + //ExSummary:Shows how to export paragraph graphics as artifact (underlines, text emphasis, etc.). + Document doc = new Document(getMyDir() + "PDF artifacts.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setExportDocumentStructure(true); + saveOptions.setExportParagraphGraphicsToArtifact(true); + saveOptions.setTextCompression(PdfTextCompression.NONE); + + doc.save(getArtifactsDir() + "PdfSaveOptions.ExportParagraphGraphicsToArtifact.pdf", saveOptions); + //ExEnd + } + + @Test + public void usePdfDocumentForExportParagraphGraphicsToArtifact() throws Exception + { + exportParagraphGraphicsToArtifact(); + + Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(getArtifactsDir() + "PdfSaveOptions.ExportParagraphGraphicsToArtifact.pdf"); + Assert.That(pdfDocument.Pages[1].Artifacts.Count(), assertEquals(3, ); + } + + @Test + public void pageLayout() throws Exception + { + //ExStart:PageLayout + //GistId:e386727403c2341ce4018bca370a5b41 + //ExFor:PdfSaveOptions.PageLayout + //ExFor:PdfPageLayout + //ExSummary:Shows how to display pages when opened in a PDF reader. + Document doc = new Document(getMyDir() + "Big document.docx"); + + // Display the pages two at a time, with odd-numbered pages on the left. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setPageLayout(PdfPageLayout.TWO_PAGE_LEFT); + + doc.save(getArtifactsDir() + "PdfSaveOptions.PageLayout.pdf", saveOptions); + //ExEnd:PageLayout + } + + @Test + public void sdtTagAsFormFieldName() throws Exception + { + //ExStart:SdtTagAsFormFieldName + //GistId:708ce40a68fac5003d46f6b4acfd5ff1 + //ExFor:PdfSaveOptions.UseSdtTagAsFormFieldName + //ExSummary:Shows how to use SDT control Tag or Id property as a name of form field in PDF. + Document doc = new Document(getMyDir() + "Form fields.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setPreserveFormFields(true); + // When set to 'false', SDT control Id property is used as a name of form field in PDF. + // When set to 'true', SDT control Tag property is used as a name of form field in PDF. + saveOptions.setUseSdtTagAsFormFieldName(true); + + doc.save(getArtifactsDir() + "PdfSaveOptions.SdtTagAsFormFieldName.pdf", saveOptions); + //ExEnd:SdtTagAsFormFieldName + } + + @Test + public void renderChoiceFormFieldBorder() throws Exception + { + //ExStart:RenderChoiceFormFieldBorder + //GistId:366eb64fd56dec3c2eaa40410e594182 + //ExFor:PdfSaveOptions.RenderChoiceFormFieldBorder + //ExSummary:Shows how to render PDF choice form field border. + Document doc = new Document(getMyDir() + "Legacy drop-down.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setPreserveFormFields(true); + saveOptions.setRenderChoiceFormFieldBorder(true); + + doc.save(getArtifactsDir() + "PdfSaveOptions.RenderChoiceFormFieldBorder.pdf", saveOptions); + //ExEnd:RenderChoiceFormFieldBorder + } +} + diff --git a/Examples/ApiExamples/JavaPorting/ExPlainTextDocument.java b/Examples/ApiExamples/JavaPorting/ExPlainTextDocument.java new file mode 100644 index 00000000..df20086c --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExPlainTextDocument.java @@ -0,0 +1,166 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.PlainTextDocument; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.ms.System.IO.FileStream; +import com.aspose.ms.System.IO.FileMode; +import com.aspose.words.OoxmlSaveOptions; +import com.aspose.words.LoadOptions; + + +@Test +class ExPlainTextDocument !Test class should be public in Java to run, please fix .Net source! extends ApiExampleBase +{ + @Test + public void load() throws Exception + { + //ExStart + //ExFor:PlainTextDocument + //ExFor:PlainTextDocument.#ctor(String) + //ExFor:PlainTextDocument.Text + //ExSummary:Shows how to load the contents of a Microsoft Word document in plaintext. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + doc.save(getArtifactsDir() + "PlainTextDocument.Load.docx"); + + PlainTextDocument plaintext = new PlainTextDocument(getArtifactsDir() + "PlainTextDocument.Load.docx"); + + Assert.assertEquals("Hello world!", plaintext.getText().trim()); + //ExEnd + } + + @Test + public void loadFromStream() throws Exception + { + //ExStart + //ExFor:PlainTextDocument.#ctor(Stream) + //ExSummary:Shows how to load the contents of a Microsoft Word document in plaintext using stream. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + doc.save(getArtifactsDir() + "PlainTextDocument.LoadFromStream.docx"); + + FileStream stream = new FileStream(getArtifactsDir() + "PlainTextDocument.LoadFromStream.docx", FileMode.OPEN); + try /*JAVA: was using*/ + { + PlainTextDocument plaintext = new PlainTextDocument(stream); + + Assert.assertEquals("Hello world!", plaintext.getText().trim()); + } + finally { if (stream != null) stream.close(); } + //ExEnd + } + + @Test + public void loadEncrypted() throws Exception + { + //ExStart + //ExFor:PlainTextDocument.#ctor(String, LoadOptions) + //ExSummary:Shows how to load the contents of an encrypted Microsoft Word document in plaintext. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + saveOptions.setPassword("MyPassword"); + + doc.save(getArtifactsDir() + "PlainTextDocument.LoadEncrypted.docx", saveOptions); + + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setPassword("MyPassword"); + + PlainTextDocument plaintext = new PlainTextDocument(getArtifactsDir() + "PlainTextDocument.LoadEncrypted.docx", loadOptions); + + Assert.assertEquals("Hello world!", plaintext.getText().trim()); + //ExEnd + } + + @Test + public void loadEncryptedUsingStream() throws Exception + { + //ExStart + //ExFor:PlainTextDocument.#ctor(Stream, LoadOptions) + //ExSummary:Shows how to load the contents of an encrypted Microsoft Word document in plaintext using stream. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + saveOptions.setPassword("MyPassword"); + + doc.save(getArtifactsDir() + "PlainTextDocument.LoadFromStreamWithOptions.docx", saveOptions); + + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setPassword("MyPassword"); + + FileStream stream = new FileStream(getArtifactsDir() + "PlainTextDocument.LoadFromStreamWithOptions.docx", FileMode.OPEN); + try /*JAVA: was using*/ + { + PlainTextDocument plaintext = new PlainTextDocument(stream, loadOptions); + + Assert.assertEquals("Hello world!", plaintext.getText().trim()); + } + finally { if (stream != null) stream.close(); } + //ExEnd + } + + @Test + public void builtInProperties() throws Exception + { + //ExStart + //ExFor:PlainTextDocument.BuiltInDocumentProperties + //ExSummary:Shows how to load the contents of a Microsoft Word document in plaintext and then access the original document's built-in properties. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + doc.getBuiltInDocumentProperties().setAuthor("John Doe"); + + doc.save(getArtifactsDir() + "PlainTextDocument.BuiltInProperties.docx"); + + PlainTextDocument plaintext = new PlainTextDocument(getArtifactsDir() + "PlainTextDocument.BuiltInProperties.docx"); + + Assert.assertEquals("Hello world!", plaintext.getText().trim()); + Assert.assertEquals("John Doe", plaintext.getBuiltInDocumentProperties().getAuthor()); + //ExEnd + } + + @Test + public void customDocumentProperties() throws Exception + { + //ExStart + //ExFor:PlainTextDocument.CustomDocumentProperties + //ExSummary:Shows how to load the contents of a Microsoft Word document in plaintext and then access the original document's custom properties. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + doc.getCustomDocumentProperties().add("Location of writing", "123 Main St, London, UK"); + + doc.save(getArtifactsDir() + "PlainTextDocument.CustomDocumentProperties.docx"); + + PlainTextDocument plaintext = new PlainTextDocument(getArtifactsDir() + "PlainTextDocument.CustomDocumentProperties.docx"); + + Assert.assertEquals("Hello world!", plaintext.getText().trim()); + Assert.assertEquals("123 Main St, London, UK", plaintext.getCustomDocumentProperties().get("Location of writing").getValue()); + //ExEnd + } +} + diff --git a/Examples/ApiExamples/JavaPorting/ExPsSaveOptions.java b/Examples/ApiExamples/JavaPorting/ExPsSaveOptions.java new file mode 100644 index 00000000..18973251 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExPsSaveOptions.java @@ -0,0 +1,68 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.PsSaveOptions; +import com.aspose.words.SaveFormat; +import com.aspose.words.Section; +import com.aspose.words.MultiplePagesType; +import org.testng.annotations.DataProvider; + + +@Test +public class ExPsSaveOptions extends ApiExampleBase +{ + @Test (dataProvider = "useBookFoldPrintingSettingsDataProvider") + public void useBookFoldPrintingSettings(boolean renderTextAsBookFold) throws Exception + { + //ExStart + //ExFor:PsSaveOptions + //ExFor:PsSaveOptions.SaveFormat + //ExFor:PsSaveOptions.UseBookFoldPrintingSettings + //ExSummary:Shows how to save a document to the Postscript format in the form of a book fold. + Document doc = new Document(getMyDir() + "Paragraphs.docx"); + + // Create a "PsSaveOptions" object that we can pass to the document's "Save" method + // to modify how that method converts the document to PostScript. + // Set the "UseBookFoldPrintingSettings" property to "true" to arrange the contents + // in the output Postscript document in a way that helps us make a booklet out of it. + // Set the "UseBookFoldPrintingSettings" property to "false" to save the document normally. + PsSaveOptions saveOptions = new PsSaveOptions(); + { + saveOptions.setSaveFormat(SaveFormat.PS); + saveOptions.setUseBookFoldPrintingSettings(renderTextAsBookFold); + } + + // If we are rendering the document as a booklet, we must set the "MultiplePages" + // properties of the page setup objects of all sections to "MultiplePagesType.BookFoldPrinting". + for (Section s : (Iterable
          ) doc.getSections()) + { + s.getPageSetup().setMultiplePages(MultiplePagesType.BOOK_FOLD_PRINTING); + } + + // Once we print this document on both sides of the pages, we can fold all the pages down the middle at once, + // and the contents will line up in a way that creates a booklet. + doc.save(getArtifactsDir() + "PsSaveOptions.UseBookFoldPrintingSettings.ps", saveOptions); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "useBookFoldPrintingSettingsDataProvider") + public static Object[][] useBookFoldPrintingSettingsDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } +} diff --git a/Examples/ApiExamples/JavaPorting/ExRange.java b/Examples/ApiExamples/JavaPorting/ExRange.java new file mode 100644 index 00000000..12cf0a25 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExRange.java @@ -0,0 +1,1009 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.FindReplaceOptions; +import java.util.Date; +import com.aspose.ms.System.DateTime; +import com.aspose.ms.System.Text.RegularExpressions.Regex; +import com.aspose.ms.System.msConsole; +import com.aspose.words.FootnoteType; +import com.aspose.words.ParagraphCollection; +import com.aspose.words.Paragraph; +import java.util.ArrayList; +import com.aspose.words.Footnote; +import com.aspose.words.NodeType; +import com.aspose.words.SaveFormat; +import com.aspose.words.ShapeType; +import com.aspose.words.BreakType; +import com.aspose.words.IReplacingCallback; +import com.aspose.words.ReplaceAction; +import com.aspose.words.ReplacingArgs; +import com.aspose.ms.System.Text.msStringBuilder; +import com.aspose.ms.System.Drawing.msColor; +import java.awt.Color; +import com.aspose.words.Run; +import com.aspose.ms.System.Convert; +import com.aspose.ms.System.msString; +import com.aspose.words.ParagraphAlignment; +import com.aspose.words.Shape; +import com.aspose.words.Node; +import com.aspose.words.CompositeNode; +import com.aspose.words.NodeImporter; +import com.aspose.words.ImportFormatMode; +import com.aspose.words.Section; +import com.aspose.words.FindReplaceDirection; +import org.testng.annotations.DataProvider; + + +@Test +public class ExRange extends ApiExampleBase +{ + @Test + public void replace() throws Exception + { + //ExStart + //ExFor:Range.Replace(String, String) + //ExSummary:Shows how to perform a find-and-replace text operation on the contents of a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Greetings, _FullName_!"); + + // Perform a find-and-replace operation on our document's contents and verify the number of replacements that took place. + int replacementCount = doc.getRange().replace("_FullName_", "John Doe"); + + Assert.assertEquals(1, replacementCount); + Assert.assertEquals("Greetings, John Doe!", doc.getText().trim()); + //ExEnd + } + + @Test (dataProvider = "replaceMatchCaseDataProvider") + public void replaceMatchCase(boolean matchCase) throws Exception + { + //ExStart + //ExFor:Range.Replace(String, String, FindReplaceOptions) + //ExFor:FindReplaceOptions + //ExFor:FindReplaceOptions.MatchCase + //ExSummary:Shows how to toggle case sensitivity when performing a find-and-replace operation. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Ruby bought a ruby necklace."); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Set the "MatchCase" flag to "true" to apply case sensitivity while finding strings to replace. + // Set the "MatchCase" flag to "false" to ignore character case while searching for text to replace. + options.setMatchCase(matchCase); + + doc.getRange().replace("Ruby", "Jade", options); + + Assert.assertEquals(matchCase ? "Jade bought a ruby necklace." : "Jade bought a Jade necklace.", doc.getText().trim()); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "replaceMatchCaseDataProvider") + public static Object[][] replaceMatchCaseDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "replaceFindWholeWordsOnlyDataProvider") + public void replaceFindWholeWordsOnly(boolean findWholeWordsOnly) throws Exception + { + //ExStart + //ExFor:Range.Replace(String, String, FindReplaceOptions) + //ExFor:FindReplaceOptions + //ExFor:FindReplaceOptions.FindWholeWordsOnly + //ExSummary:Shows how to toggle standalone word-only find-and-replace operations. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Jackson will meet you in Jacksonville."); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Set the "FindWholeWordsOnly" flag to "true" to replace the found text if it is not a part of another word. + // Set the "FindWholeWordsOnly" flag to "false" to replace all text regardless of its surroundings. + options.setFindWholeWordsOnly(findWholeWordsOnly); + + doc.getRange().replace("Jackson", "Louis", options); + + Assert.assertEquals(findWholeWordsOnly ? "Louis will meet you in Jacksonville." : "Louis will meet you in Louisville.", doc.getText().trim()); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "replaceFindWholeWordsOnlyDataProvider") + public static Object[][] replaceFindWholeWordsOnlyDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "ignoreDeletedDataProvider") + public void ignoreDeleted(boolean ignoreTextInsideDeleteRevisions) throws Exception + { + //ExStart + //ExFor:FindReplaceOptions.IgnoreDeleted + //ExSummary:Shows how to include or ignore text inside delete revisions during a find-and-replace operation. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + builder.writeln("Hello again!"); + + // Start tracking revisions and remove the second paragraph, which will create a delete revision. + // That paragraph will persist in the document until we accept the delete revision. + doc.startTrackRevisionsInternal("John Doe", new Date); + doc.getFirstSection().getBody().getParagraphs().get(1).remove(); + doc.stopTrackRevisions(); + + Assert.assertTrue(doc.getFirstSection().getBody().getParagraphs().get(1).isDeleteRevision()); + + // We can use a "FindReplaceOptions" object to modify the find and replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Set the "IgnoreDeleted" flag to "true" to get the find-and-replace + // operation to ignore paragraphs that are delete revisions. + // Set the "IgnoreDeleted" flag to "false" to get the find-and-replace + // operation to also search for text inside delete revisions. + options.setIgnoreDeleted(ignoreTextInsideDeleteRevisions); + + doc.getRange().replace("Hello", "Greetings", options); + + Assert.assertEquals(ignoreTextInsideDeleteRevisions + ? "Greetings world!\rHello again!" + : "Greetings world!\rGreetings again!", doc.getText().trim()); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "ignoreDeletedDataProvider") + public static Object[][] ignoreDeletedDataProvider() throws Exception + { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test (dataProvider = "ignoreInsertedDataProvider") + public void ignoreInserted(boolean ignoreTextInsideInsertRevisions) throws Exception + { + //ExStart + //ExFor:FindReplaceOptions.IgnoreInserted + //ExSummary:Shows how to include or ignore text inside insert revisions during a find-and-replace operation. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + + // Start tracking revisions and insert a paragraph. That paragraph will be an insert revision. + doc.startTrackRevisionsInternal("John Doe", new Date); + builder.writeln("Hello again!"); + doc.stopTrackRevisions(); + + Assert.assertTrue(doc.getFirstSection().getBody().getParagraphs().get(1).isInsertRevision()); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Set the "IgnoreInserted" flag to "true" to get the find-and-replace + // operation to ignore paragraphs that are insert revisions. + // Set the "IgnoreInserted" flag to "false" to get the find-and-replace + // operation to also search for text inside insert revisions. + options.setIgnoreInserted(ignoreTextInsideInsertRevisions); + + doc.getRange().replace("Hello", "Greetings", options); + + Assert.assertEquals(ignoreTextInsideInsertRevisions + ? "Greetings world!\rHello again!" + : "Greetings world!\rGreetings again!", doc.getText().trim()); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "ignoreInsertedDataProvider") + public static Object[][] ignoreInsertedDataProvider() throws Exception + { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test (dataProvider = "ignoreFieldsDataProvider") + public void ignoreFields(boolean ignoreTextInsideFields) throws Exception + { + //ExStart + //ExFor:FindReplaceOptions.IgnoreFields + //ExSummary:Shows how to ignore text inside fields. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + builder.insertField("QUOTE", "Hello again!"); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Set the "IgnoreFields" flag to "true" to get the find-and-replace + // operation to ignore text inside fields. + // Set the "IgnoreFields" flag to "false" to get the find-and-replace + // operation to also search for text inside fields. + options.setIgnoreFields(ignoreTextInsideFields); + + doc.getRange().replace("Hello", "Greetings", options); + + Assert.assertEquals(ignoreTextInsideFields + ? "Greetings world!\r\u0013QUOTE\u0014Hello again!\u0015" + : "Greetings world!\r\u0013QUOTE\u0014Greetings again!\u0015", doc.getText().trim()); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "ignoreFieldsDataProvider") + public static Object[][] ignoreFieldsDataProvider() throws Exception + { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test (dataProvider = "ignoreFieldCodesDataProvider") + public void ignoreFieldCodes(boolean ignoreFieldCodes) throws Exception + { + //ExStart + //ExFor:FindReplaceOptions.IgnoreFieldCodes + //ExSummary:Shows how to ignore text inside field codes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField("INCLUDETEXT", "Test IT!"); + + FindReplaceOptions options = new FindReplaceOptions(); {options.setIgnoreFieldCodes(ignoreFieldCodes);} + + // Replace 'T' in document ignoring text inside field code or not. + doc.getRange().replaceInternal(new Regex("T"), "*", options); + System.out.println(doc.getText()); + + Assert.assertEquals(ignoreFieldCodes + ? "\u0013INCLUDETEXT\u0014*est I*!\u0015" + : "\u0013INCLUDE*EX*\u0014*est I*!\u0015", doc.getText().trim()); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "ignoreFieldCodesDataProvider") + public static Object[][] ignoreFieldCodesDataProvider() throws Exception + { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test (dataProvider = "ignoreFootnoteDataProvider") + public void ignoreFootnote(boolean isIgnoreFootnotes) throws Exception + { + //ExStart + //ExFor:FindReplaceOptions.IgnoreFootnotes + //ExSummary:Shows how to ignore footnotes during a find-and-replace operation. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + builder.insertFootnote(FootnoteType.FOOTNOTE, "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + + builder.insertParagraph(); + + builder.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + builder.insertFootnote(FootnoteType.ENDNOTE, "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + + // Set the "IgnoreFootnotes" flag to "true" to get the find-and-replace + // operation to ignore text inside footnotes. + // Set the "IgnoreFootnotes" flag to "false" to get the find-and-replace + // operation to also search for text inside footnotes. + FindReplaceOptions options = new FindReplaceOptions(); { options.setIgnoreFootnotes(isIgnoreFootnotes); } + doc.getRange().replace("Lorem ipsum", "Replaced Lorem ipsum", options); + //ExEnd + + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + for (Paragraph para : (Iterable) paragraphs) + { + Assert.assertEquals("Replaced Lorem ipsum", para.getRuns().get(0).getText()); + } + + ArrayList footnotes = doc.getChildNodes(NodeType.FOOTNOTE, true).Cast().ToList(); + Assert.assertEquals(isIgnoreFootnotes + ? "Lorem ipsum dolor sit amet, consectetur adipiscing elit." + : "Replaced Lorem ipsum dolor sit amet, consectetur adipiscing elit.", footnotes.get(0).toString(SaveFormat.TEXT).trim()); + Assert.assertEquals(isIgnoreFootnotes + ? "Lorem ipsum dolor sit amet, consectetur adipiscing elit." + : "Replaced Lorem ipsum dolor sit amet, consectetur adipiscing elit.", footnotes.get(1).toString(SaveFormat.TEXT).trim()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "ignoreFootnoteDataProvider") + public static Object[][] ignoreFootnoteDataProvider() throws Exception + { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test + public void ignoreShapes() throws Exception + { + //ExStart + //ExFor:FindReplaceOptions.IgnoreShapes + //ExSummary:Shows how to ignore shapes while replacing text. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + builder.insertShape(ShapeType.BALLOON, 200.0, 200.0); + builder.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + + FindReplaceOptions findReplaceOptions = new FindReplaceOptions(); { findReplaceOptions.setIgnoreShapes(true); } + builder.getDocument().getRange().replace("Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", findReplaceOptions); + Assert.assertEquals("Lorem ipsum dolor sit amet, consectetur adipiscing elit.", builder.getDocument().getText().trim()); + //ExEnd + } + + @Test + public void updateFieldsInRange() throws Exception + { + //ExStart + //ExFor:Range.UpdateFields + //ExSummary:Shows how to update all the fields in a range. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField(" DOCPROPERTY Category"); + builder.insertBreak(BreakType.SECTION_BREAK_EVEN_PAGE); + builder.insertField(" DOCPROPERTY Category"); + + // The above DOCPROPERTY fields will display the value of this built-in document property. + doc.getBuiltInDocumentProperties().setCategory("MyCategory"); + + // If we update the value of a document property, we will need to update all the DOCPROPERTY fields to display it. + Assert.assertEquals("", doc.getRange().getFields().get(0).getResult()); + Assert.assertEquals("", doc.getRange().getFields().get(1).getResult()); + + // Update all the fields that are in the range of the first section. + doc.getFirstSection().getRange().updateFields(); + + Assert.assertEquals("MyCategory", doc.getRange().getFields().get(0).getResult()); + Assert.assertEquals("", doc.getRange().getFields().get(1).getResult()); + //ExEnd + } + + @Test + public void replaceWithString() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("This one is sad."); + builder.writeln("That one is mad."); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setMatchCase(false); + options.setFindWholeWordsOnly(true); + + doc.getRange().replace("sad", "bad", options); + + doc.save(getArtifactsDir() + "Range.ReplaceWithString.docx"); + } + + @Test + public void replaceWithRegex() throws Exception + { + //ExStart + //ExFor:Range.Replace(Regex, String) + //ExSummary:Shows how to replace all occurrences of a regular expression pattern with other text. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("I decided to get the curtains in gray, ideal for the grey-accented room."); + + doc.getRange().replaceInternal(new Regex("gr(a|e)y"), "lavender"); + + Assert.assertEquals("I decided to get the curtains in lavender, ideal for the lavender-accented room.", doc.getText().trim()); + //ExEnd + } + + //ExStart + //ExFor:FindReplaceOptions.ReplacingCallback + //ExFor:Range.Replace(Regex, String, FindReplaceOptions) + //ExFor:ReplacingArgs.Replacement + //ExFor:IReplacingCallback + //ExFor:IReplacingCallback.Replacing + //ExFor:ReplacingArgs + //ExSummary:Shows how to replace all occurrences of a regular expression pattern with another string, while tracking all such replacements. + @Test //ExSkip + public void replaceWithCallback() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Our new location in New York City is opening tomorrow. " + + "Hope to see all our NYC-based customers at the opening!"); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Set a callback that tracks any replacements that the "Replace" method will make. + TextFindAndReplacementLogger logger = new TextFindAndReplacementLogger(); + options.setReplacingCallback(logger); + + doc.getRange().replaceInternal(new Regex("New York City|NYC"), "Washington", options); + + Assert.assertEquals("Our new location in (Old value:\"New York City\") Washington is opening tomorrow. " + + "Hope to see all our (Old value:\"NYC\") Washington-based customers at the opening!", doc.getText().trim()); + + Assert.assertEquals("\"New York City\" converted to \"Washington\" 20 characters into a Run node.\r\n" + + "\"NYC\" converted to \"Washington\" 42 characters into a Run node.", logger.getLog().trim()); + } + + /// + /// Maintains a log of every text replacement done by a find-and-replace operation + /// and notes the original matched text's value. + /// + private static class TextFindAndReplacementLogger implements IReplacingCallback + { + public /*ReplaceAction*/int /*IReplacingCallback.*/replacing(ReplacingArgs args) + { + msStringBuilder.appendLine(mLog, $"\"{args.Match.Value}\" converted to \"{args.Replacement}\" " + + $"{args.MatchOffset} characters into a {args.MatchNode.NodeType} node."); + + args.setReplacement("(Old value:\"{args.Match.Value}\") {args.Replacement}"); + return ReplaceAction.REPLACE; + } + + public String getLog() + { + return mLog.toString(); + } + + private /*final*/ StringBuilder mLog = new StringBuilder(); + } + //ExEnd + + //ExStart + //ExFor:FindReplaceOptions.ApplyFont + //ExFor:FindReplaceOptions.ReplacingCallback + //ExFor:ReplacingArgs.GroupIndex + //ExFor:ReplacingArgs.GroupName + //ExFor:ReplacingArgs.Match + //ExFor:ReplacingArgs.MatchOffset + //ExSummary:Shows how to apply a different font to new content via FindReplaceOptions. + @Test //ExSkip + public void convertNumbersToHexadecimal() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Arial"); + builder.writeln("Numbers that the find-and-replace operation will convert to hexadecimal and highlight:\n" + + "123, 456, 789 and 17379."); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Set the "HighlightColor" property to a background color that we want to apply to the operation's resulting text. + options.getApplyFont().setHighlightColor(msColor.getLightGray()); + + NumberHexer numberHexer = new NumberHexer(); + options.setReplacingCallback(numberHexer); + + int replacementCount = doc.getRange().replaceInternal(new Regex("[0-9]+"), "", options); + + System.out.println(numberHexer.getLog()); + + Assert.assertEquals(4, replacementCount); + Assert.assertEquals("Numbers that the find-and-replace operation will convert to hexadecimal and highlight:\r" + + "0x7B, 0x1C8, 0x315 and 0x43E3.", doc.getText().trim()); + Assert.That(doc.getChildNodes(NodeType.RUN, true).OfType() + .Count(r => r.Font.HighlightColor.ToArgb() == Color.LightGray.ToArgb()), assertEquals(4, ); + } + + /// + /// Replaces numeric find-and-replacement matches with their hexadecimal equivalents. + /// Maintains a log of every replacement. + /// + private static class NumberHexer implements IReplacingCallback + { + public /*ReplaceAction*/int replacing(ReplacingArgs args) + { + mCurrentReplacementNumber++; + + int number = Convert.toInt32(args.getMatchInternal().getValue()); + + args.setReplacement("0x{number:X}"); + + msStringBuilder.appendLine(mLog, $"Match #{mCurrentReplacementNumber}"); + msStringBuilder.appendLine(mLog, $"\tOriginal value:\t{args.Match.Value}"); + msStringBuilder.appendLine(mLog, $"\tReplacement:\t{args.Replacement}"); + msStringBuilder.appendLine(mLog, $"\tOffset in parent {args.MatchNode.NodeType} node:\t{args.MatchOffset}"); + + msStringBuilder.appendLine(mLog, msString.isNullOrEmpty(args.GroupName) + ? $"\tGroup index:\t{args.GroupIndex}" + : $"\tGroup name:\t{args.GroupName}"); + + return ReplaceAction.REPLACE; + } + + public String getLog() + { + return mLog.toString(); + } + + private int mCurrentReplacementNumber; + private /*final*/ StringBuilder mLog = new StringBuilder(); + } + //ExEnd + + @Test + public void applyParagraphFormat() throws Exception + { + //ExStart + //ExFor:FindReplaceOptions.ApplyParagraphFormat + //ExFor:Range.Replace(String, String) + //ExSummary:Shows how to add formatting to paragraphs in which a find-and-replace operation has found matches. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Every paragraph that ends with a full stop like this one will be right aligned."); + builder.writeln("This one will not!"); + builder.write("This one also will."); + + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + + Assert.assertEquals(ParagraphAlignment.LEFT, paragraphs.get(0).getParagraphFormat().getAlignment()); + Assert.assertEquals(ParagraphAlignment.LEFT, paragraphs.get(1).getParagraphFormat().getAlignment()); + Assert.assertEquals(ParagraphAlignment.LEFT, paragraphs.get(2).getParagraphFormat().getAlignment()); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Set the "Alignment" property to "ParagraphAlignment.Right" to right-align every paragraph + // that contains a match that the find-and-replace operation finds. + options.getApplyParagraphFormat().setAlignment(ParagraphAlignment.RIGHT); + + // Replace every full stop that is right before a paragraph break with an exclamation point. + int count = doc.getRange().replace(".&p", "!&p", options); + + Assert.assertEquals(2, count); + Assert.assertEquals(ParagraphAlignment.RIGHT, paragraphs.get(0).getParagraphFormat().getAlignment()); + Assert.assertEquals(ParagraphAlignment.LEFT, paragraphs.get(1).getParagraphFormat().getAlignment()); + Assert.assertEquals(ParagraphAlignment.RIGHT, paragraphs.get(2).getParagraphFormat().getAlignment()); + Assert.assertEquals("Every paragraph that ends with a full stop like this one will be right aligned!\r" + + "This one will not!\r" + + "This one also will!", doc.getText().trim()); + //ExEnd + } + + @Test + public void deleteSelection() throws Exception + { + //ExStart + //ExFor:Node.Range + //ExFor:Range.Delete + //ExSummary:Shows how to delete all the nodes from a range. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Add text to the first section in the document, and then add another section. + builder.write("Section 1. "); + builder.insertBreak(BreakType.SECTION_BREAK_CONTINUOUS); + builder.write("Section 2."); + + Assert.assertEquals("Section 1. \fSection 2.", doc.getText().trim()); + + // Remove the first section entirely by removing all the nodes + // within its range, including the section itself. + doc.getSections().get(0).getRange().delete(); + + Assert.assertEquals(1, doc.getSections().getCount()); + Assert.assertEquals("Section 2.", doc.getText().trim()); + //ExEnd + } + + @Test + public void rangesGetText() throws Exception + { + //ExStart + //ExFor:Range + //ExFor:Range.Text + //ExSummary:Shows how to get the text contents of all the nodes that a range covers. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Hello world!"); + + Assert.assertEquals("Hello world!", doc.getRange().getText().trim()); + //ExEnd + } + + //ExStart + //ExFor:FindReplaceOptions.UseLegacyOrder + //ExSummary:Shows how to change the searching order of nodes when performing a find-and-replace text operation. + @Test (dataProvider = "useLegacyOrderDataProvider") //ExSkip + public void useLegacyOrder(boolean useLegacyOrder) throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert three runs which we can search for using a regex pattern. + // Place one of those runs inside a text box. + builder.writeln("[tag 1]"); + Shape textBox = builder.insertShape(ShapeType.TEXT_BOX, 100.0, 50.0); + builder.writeln("[tag 2]"); + builder.moveTo(textBox.getFirstParagraph()); + builder.write("[tag 3]"); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Assign a custom callback to the "ReplacingCallback" property. + TextReplacementTracker callback = new TextReplacementTracker(); + options.setReplacingCallback(callback); + + // If we set the "UseLegacyOrder" property to "true", the + // find-and-replace operation will go through all the runs outside of a text box + // before going through the ones inside a text box. + // If we set the "UseLegacyOrder" property to "false", the + // find-and-replace operation will go over all the runs in a range in sequential order. + options.setUseLegacyOrder(useLegacyOrder); + + doc.getRange().replaceInternal(new Regex("\\[tag \\d*\\]"), "", options); + + ArrayList expected; + if (useLegacyOrder) + expected = new ArrayList(); { expected.add("[tag 1]"); expected.add("[tag 3]"); expected.add("[tag 2]"); } + else + expected = new ArrayList(); { expected.add("[tag 1]"); expected.add("[tag 2]"); expected.add("[tag 3]"); } + Assert.assertEquals(expected, callback.getMatches()); + + } + + //JAVA-added data provider for test method + @DataProvider(name = "useLegacyOrderDataProvider") + public static Object[][] useLegacyOrderDataProvider() throws Exception + { + return new Object[][] + { + {true}, + {false}, + }; + } + + /// + /// Records the order of all matches that occur during a find-and-replace operation. + /// + private static class TextReplacementTracker implements IReplacingCallback + { + public /*ReplaceAction*/int /*IReplacingCallback.*/replacing(ReplacingArgs e) + { + getMatches().add(e.getMatchInternal().getValue()); + return ReplaceAction.REPLACE; + } + + public ArrayList getMatches() { return mMatches; }; + + private ArrayList mMatches !!!Autoporter warning: AutoProperty initialization can't be autoported! = /*new*/ArrayListlist(); + } + //ExEnd + + @Test (dataProvider = "useSubstitutionsDataProvider") + public void useSubstitutions(boolean useSubstitutions) throws Exception + { + //ExStart + //ExFor:FindReplaceOptions.UseSubstitutions + //ExSummary:Shows how to replace the text with substitutions. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("John sold a car to Paul."); + builder.writeln("Jane sold a house to Joe."); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Set the "UseSubstitutions" property to "true" to get + // the find-and-replace operation to recognize substitution elements. + // Set the "UseSubstitutions" property to "false" to ignore substitution elements. + options.setUseSubstitutions(useSubstitutions); + + Regex regex = new Regex("([A-z]+) sold a ([A-z]+) to ([A-z]+)"); + doc.getRange().replaceInternal(regex, "$3 bought a $2 from $1", options); + + Assert.assertEquals(useSubstitutions + ? "Paul bought a car from John.\rJoe bought a house from Jane." + : "$3 bought a $2 from $1.\r$3 bought a $2 from $1.", doc.getText().trim()); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "useSubstitutionsDataProvider") + public static Object[][] useSubstitutionsDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + //ExStart + //ExFor:Range.Replace(Regex, String, FindReplaceOptions) + //ExFor:IReplacingCallback + //ExFor:ReplaceAction + //ExFor:IReplacingCallback.Replacing + //ExFor:ReplacingArgs + //ExFor:ReplacingArgs.MatchNode + //ExSummary:Shows how to insert an entire document's contents as a replacement of a match in a find-and-replace operation. + @Test //ExSkip + public void insertDocumentAtReplace() throws Exception + { + Document mainDoc = new Document(getMyDir() + "Document insertion destination.docx"); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + options.setReplacingCallback(new InsertDocumentAtReplaceHandler()); + + mainDoc.getRange().replaceInternal(new Regex("\\[MY_DOCUMENT\\]"), "", options); + mainDoc.save(getArtifactsDir() + "InsertDocument.InsertDocumentAtReplace.docx"); + + testInsertDocumentAtReplace(new Document(getArtifactsDir() + "InsertDocument.InsertDocumentAtReplace.docx")); //ExSkip + } + + private static class InsertDocumentAtReplaceHandler implements IReplacingCallback + { + public /*ReplaceAction*/int /*IReplacingCallback.*/replacing(ReplacingArgs args) throws Exception + { + Document subDoc = new Document(getMyDir() + "Document.docx"); + + // Insert a document after the paragraph containing the matched text. + Paragraph para = (Paragraph)args.getMatchNode().getParentNode(); + insertDocument(para, subDoc); + + // Remove the paragraph with the matched text. + para.remove(); + + return ReplaceAction.SKIP; + } + } + + /// + /// Inserts all the nodes of another document after a paragraph or table. + /// + private static void insertDocument(Node insertionDestination, Document docToInsert) + { + if (insertionDestination.getNodeType() == NodeType.PARAGRAPH || insertionDestination.getNodeType() == NodeType.TABLE) + { + CompositeNode dstStory = insertionDestination.getParentNode(); + + NodeImporter importer = + new NodeImporter(docToInsert, insertionDestination.getDocument(), ImportFormatMode.KEEP_SOURCE_FORMATTING); + + for (Section srcSection : docToInsert.getSections().
          OfType() !!Autoporter error: Undefined expression type ) + for (Node srcNode : (Iterable) srcSection.getBody()) + { + // Skip the node if it is the last empty paragraph in a section. + if (srcNode.getNodeType() == NodeType.PARAGRAPH) + { + Paragraph para = (Paragraph)srcNode; + if (para.isEndOfSection() && !para.hasChildNodes()) + continue; + } + + Node newNode = importer.importNode(srcNode, true); + + dstStory.insertAfter(newNode, insertionDestination); + insertionDestination = newNode; + } + } + else + { + throw new IllegalArgumentException("The destination node must be either a paragraph or table."); + } + } + //ExEnd + + private static void testInsertDocumentAtReplace(Document doc) + { + Assert.assertEquals("1) At text that can be identified by regex:\rHello World!\r" + + "2) At a MERGEFIELD:\r\u0013 MERGEFIELD Document_1 \\* MERGEFORMAT \u0014«Document_1»\u0015\r" + + "3) At a bookmark:", doc.getFirstSection().getBody().getText().trim()); + } + + //ExStart + //ExFor:FindReplaceOptions.Direction + //ExFor:FindReplaceDirection + //ExSummary:Shows how to determine which direction a find-and-replace operation traverses the document in. + @Test (dataProvider = "directionDataProvider") //ExSkip + public void direction(/*FindReplaceDirection*/int findReplaceDirection) throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert three runs which we can search for using a regex pattern. + // Place one of those runs inside a text box. + builder.writeln("Match 1."); + builder.writeln("Match 2."); + builder.writeln("Match 3."); + builder.writeln("Match 4."); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Assign a custom callback to the "ReplacingCallback" property. + TextReplacementRecorder callback = new TextReplacementRecorder(); + options.setReplacingCallback(callback); + + // Set the "Direction" property to "FindReplaceDirection.Backward" to get the find-and-replace + // operation to start from the end of the range, and traverse back to the beginning. + // Set the "Direction" property to "FindReplaceDirection.Forward" to get the find-and-replace + // operation to start from the beginning of the range, and traverse to the end. + options.setDirection(findReplaceDirection); + + doc.getRange().replaceInternal(new Regex("Match \\d*"), "Replacement", options); + + Assert.assertEquals("Replacement.\r" + + "Replacement.\r" + + "Replacement.\r" + + "Replacement.", doc.getText().trim()); + + switch (findReplaceDirection) + { + case FindReplaceDirection.FORWARD: + Assert.assertEquals(new String[] { "Match 1", "Match 2", "Match 3", "Match 4" }, callback.getMatches()); + break; + case FindReplaceDirection.BACKWARD: + Assert.assertEquals(new String[] { "Match 4", "Match 3", "Match 2", "Match 1" }, callback.getMatches()); + break; + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "directionDataProvider") + public static Object[][] directionDataProvider() throws Exception + { + return new Object[][] + { + {FindReplaceDirection.BACKWARD}, + {FindReplaceDirection.FORWARD}, + }; + } + + /// + /// Records all matches that occur during a find-and-replace operation in the order that they take place. + /// + private static class TextReplacementRecorder implements IReplacingCallback + { + public /*ReplaceAction*/int /*IReplacingCallback.*/replacing(ReplacingArgs e) + { + getMatches().add(e.getMatchInternal().getValue()); + return ReplaceAction.REPLACE; + } + + public ArrayList getMatches() { return mMatches; }; + + private ArrayList mMatches !!!Autoporter warning: AutoProperty initialization can't be autoported! = /*new*/ArrayListlist(); + } + //ExEnd + + //ExStart:MatchEndNode + //GistId:67c1d01ce69d189983b497fd497a7768 + //ExFor:ReplacingArgs.MatchEndNode + //ExSummary:Shows how to get match end node. + @Test + public void matchEndNode() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("1"); + builder.writeln("2"); + builder.writeln("3"); + + ReplacingCallback replacingCallback = new ReplacingCallback(); + FindReplaceOptions options = new FindReplaceOptions(); + options.setReplacingCallback(replacingCallback); + + doc.getRange().replaceInternal(new Regex("1[\\s\\S]*3"), "X", options); + Assert.assertEquals("1", replacingCallback.getStartNodeText()); + Assert.assertEquals("3", replacingCallback.getEndNodeText()); + } + + /// + /// The replacing callback. + /// + private static class ReplacingCallback implements IReplacingCallback + { + public /*ReplaceAction*/int /*IReplacingCallback.*/replacing(ReplacingArgs e) + { + setStartNodeText(e.getMatchNode().getText().trim()); + setEndNodeText(e.getMatchEndNode().getText().trim()); + + return ReplaceAction.REPLACE; + } + + String getStartNodeText() { return mStartNodeText; }; private void setStartNodeText(String value) { mStartNodeText = value; }; + + private String mStartNodeText; + String getEndNodeText() { return mEndNodeText; }; private void setEndNodeText(String value) { mEndNodeText = value; }; + + private String mEndNodeText; + } + //ExEnd:MatchEndNode + + @Test (dataProvider = "ignoreOfficeMathDataProvider") + public void ignoreOfficeMath(boolean isIgnoreOfficeMath) throws Exception + { + //ExStart:IgnoreOfficeMath + //GistId:571cc6e23284a2ec075d15d4c32e3bbf + //ExFor:FindReplaceOptions.IgnoreOfficeMath + //ExSummary:Shows how to find and replace text within OfficeMath. + Document doc = new Document(getMyDir() + "Office math.docx"); + + Assert.assertEquals("i+b-c≥iM+bM-cM", doc.getFirstSection().getBody().getFirstParagraph().getText().trim()); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setIgnoreOfficeMath(isIgnoreOfficeMath); + doc.getRange().replace("b", "x", options); + + if (isIgnoreOfficeMath) + Assert.assertEquals("i+b-c≥iM+bM-cM", doc.getFirstSection().getBody().getFirstParagraph().getText().trim()); + else + Assert.assertEquals("i+x-c≥iM+xM-cM", doc.getFirstSection().getBody().getFirstParagraph().getText().trim()); + //ExEnd:IgnoreOfficeMath + } + + //JAVA-added data provider for test method + @DataProvider(name = "ignoreOfficeMathDataProvider") + public static Object[][] ignoreOfficeMathDataProvider() throws Exception + { + return new Object[][] + { + {true}, + {false}, + }; + } +} diff --git a/Examples/ApiExamples/JavaPorting/ExRenameMergeFields.java b/Examples/ApiExamples/JavaPorting/ExRenameMergeFields.java new file mode 100644 index 00000000..21fcce97 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExRenameMergeFields.java @@ -0,0 +1,173 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.NodeCollection; +import com.aspose.words.NodeType; +import com.aspose.words.FieldStart; +import com.aspose.words.FieldType; +import com.aspose.ms.System.msString; +import com.aspose.words.Run; +import com.aspose.ms.System.Text.RegularExpressions.Match; +import com.aspose.words.Node; +import com.aspose.ms.System.Text.msStringBuilder; +import com.aspose.ms.System.Text.RegularExpressions.Regex; + + +/// +/// Shows how to rename merge fields in a Word document. +/// +@Test +public class ExRenameMergeFields extends ApiExampleBase +{ + /// + /// Finds all merge fields in a Word document and changes their names. + /// + @Test + public void rename() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Dear "); + builder.insertField("MERGEFIELD FirstName "); + builder.write(" "); + builder.insertField("MERGEFIELD LastName "); + builder.writeln(","); + builder.insertField("MERGEFIELD CustomGreeting "); + + // Select all field start nodes so we can find the MERGEFIELDs. + NodeCollection fieldStarts = doc.getChildNodes(NodeType.FIELD_START, true); + for (FieldStart fieldStart : fieldStarts.OfType() !!Autoporter error: Undefined expression type ) + { + if (fieldStart.getFieldType() == FieldType.FIELD_MERGE_FIELD) + { + MergeField mergeField = new MergeField(fieldStart); + mergeField.setName(mergeField.getName() + "_Renamed"); + } + } + + doc.save(getArtifactsDir() + "RenameMergeFields.Rename.docx"); + } +} + +/// +/// Represents a facade object for a merge field in a Microsoft Word document. +/// +class MergeField +{ + MergeField(FieldStart fieldStart) + { + if (fieldStart.getFieldType() != FieldType.FIELD_MERGE_FIELD) + throw new IllegalArgumentException("Field start type must be FieldMergeField."); + + mFieldStart = fieldStart; + + // Find the field separator node. + mFieldSeparator = findNextSibling(mFieldStart, NodeType.FIELD_SEPARATOR); + if (mFieldSeparator == null) + throw new IllegalStateException("Cannot find field separator."); + + // Find the field end node. Normally field end will always be found, but in the example document + // there happens to be a paragraph break included in the hyperlink and this puts the field end + // in the next paragraph. It will be much more complicated to handle fields which span several + // paragraphs correctly, but in this case allowing field end to be null is enough for our purposes. + mFieldEnd = findNextSibling(mFieldSeparator, NodeType.FIELD_END); + } + + /// + /// Gets or sets the name of the merge field. + /// + String getName() + { + return msString.trim(getTextSameParent(mFieldSeparator.getNextSibling(), mFieldEnd), '«', '»'); + } + void setName(String value) + { + // Merge field name is stored in the field result which is a Run + // node between field separator and field end. + Run fieldResult = (Run) mFieldSeparator.getNextSibling(); + fieldResult.setText("«{value}»"); + + // But sometimes the field result can consist of more than one run, delete these runs. + removeSameParent(fieldResult.getNextSibling(), mFieldEnd); + + updateFieldCode(value); + } + + private void updateFieldCode(String fieldName) + { + // Field code is stored in a Run node between field start and field separator. + Run fieldCode = (Run) mFieldStart.getNextSibling(); + Match match = G_REGEX.match(fieldCode.getText()); + + String newFieldCode = $" {match.Groups["start"].Value}{fieldName} "; + fieldCode.setText(newFieldCode); + + // But sometimes the field code can consist of more than one run, delete these runs. + removeSameParent(fieldCode.getNextSibling(), mFieldSeparator); + } + + /// + /// Goes through siblings starting from the start node until it finds a node of the specified type or null. + /// + private static Node findNextSibling(Node startNode, /*NodeType*/int nodeType) + { + for (Node node = startNode; node != null; node = node.getNextSibling()) + { + if (node.getNodeType() == nodeType) + return node; + } + + return null; + } + + /// + /// Retrieves text from start up to but not including the end node. + /// + private static String getTextSameParent(Node startNode, Node endNode) + { + if (endNode != null && startNode.getParentNode() != endNode.getParentNode()) + throw new IllegalArgumentException("Start and end nodes are expected to have the same parent."); + + StringBuilder builder = new StringBuilder(); + for (Node child = startNode; !child.equals(endNode); child = child.getNextSibling()) + msStringBuilder.append(builder, child.getText()); + + return builder.toString(); + } + + /// + /// Removes nodes from start up to but not including the end node. + /// Start and end are assumed to have the same parent. + /// + private static void removeSameParent(Node startNode, Node endNode) + { + if (endNode != null && startNode.getParentNode() != endNode.getParentNode()) + throw new IllegalArgumentException("Start and end nodes are expected to have the same parent."); + + Node curChild = startNode; + while ((curChild != null) && (curChild != endNode)) + { + Node nextChild = curChild.getNextSibling(); + curChild.remove(); + curChild = nextChild; + } + } + + private /*final*/ Node mFieldStart; + private /*final*/ Node mFieldSeparator; + private /*final*/ Node mFieldEnd; + + private static /*final*/ Regex G_REGEX = new Regex("\\s*(?MERGEFIELD\\s|)(\\s|)(?\\S+)\\s+"); +} diff --git a/Examples/ApiExamples/JavaPorting/ExRendering.java b/Examples/ApiExamples/JavaPorting/ExRendering.java new file mode 100644 index 00000000..b70862cf --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExRendering.java @@ -0,0 +1,275 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.ms.System.Drawing.msSize; +import com.aspose.words.Chart; +import com.aspose.words.ChartType; +import com.aspose.words.Shape; +import com.aspose.words.NodeType; +import com.aspose.words.GroupShape; +import com.aspose.ms.System.Drawing.RectangleF; +import com.aspose.words.ShapeType; +import java.awt.Color; +import java.util.ArrayList; +import java.util.Map; +import com.aspose.words.ShapeBase; +import com.aspose.ms.System.Collections.DictionaryEntry; +import com.aspose.words.ShapeRenderer; +import java.awt.Graphics2D; +import com.aspose.ms.System.EventArgs; +import java.awt.image.BufferedImage; +import com.aspose.ms.System.Drawing.Text.TextRenderingHint; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.ms.System.Drawing.msSizeF; + + +@Test +public class ExRendering extends ApiExampleBase +{ + //ExStart + //ExFor:NodeRendererBase.RenderToScale(Graphics, Single, Single, Single) + //ExFor:NodeRendererBase.RenderToSize(Graphics, Single, Single, Single, Single) + //ExFor:ShapeRenderer + //ExFor:ShapeRenderer.#ctor(ShapeBase) + //ExSummary:Shows how to render a shape with a Graphics object and display it using a Windows Form. + @Test (groups = "IgnoreOnJenkins") //ExSkip + public void renderShapesOnForm() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + ShapeForm shapeForm = new ShapeForm(msSize.ctor(1017, 840)); + + // Below are two ways to use the "ShapeRenderer" class to render a shape to a Graphics object. + // 1 - Create a shape with a chart, and render it to a specific scale. + Chart chart = builder.insertChart(ChartType.PIE, 500.0, 400.0).getChart(); + chart.getSeries().clear(); + chart.getSeries().add("Desktop Browser Market Share (Oct. 2020)", + new String[] { "Google Chrome", "Apple Safari", "Mozilla Firefox", "Microsoft Edge", "Other" }, + new double[] { 70.33, 8.87, 7.69, 5.83, 7.28 }); + + Shape chartShape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + shapeForm.addShapeToRenderToScale(chartShape, 0f, 0f, 1.5f); + + // 2 - Create a shape group, and render it to a specific size. + GroupShape group = new GroupShape(doc); + group.setBoundsInternal(new RectangleF(0f, 0f, 100f, 100f)); + group.setCoordSizeInternal(msSize.ctor(500, 500)); + + Shape subShape = new Shape(doc, ShapeType.RECTANGLE); + subShape.setWidth(500.0); + subShape.setHeight(500.0); + subShape.setLeft(0.0); + subShape.setTop(0.0); + subShape.setFillColor(Color.RoyalBlue); + group.appendChild(subShape); + + subShape = new Shape(doc, ShapeType.IMAGE); + subShape.setWidth(450.0); + subShape.setHeight(450.0); + subShape.setLeft(25.0); + subShape.setTop(25.0); + subShape.getImageData().setImage(getImageDir() + "Logo.jpg"); + group.appendChild(subShape); + + builder.insertNode(group); + + GroupShape groupShape = (GroupShape)doc.getChild(NodeType.GROUP_SHAPE, 0, true); + shapeForm.addShapeToRenderToSize(groupShape, 880f, 680f, 100f, 100f); + + shapeForm.ShowDialog(); + } + + /// + /// Renders and displays a list of shapes. + /// + private static class ShapeForm extends Form + { + public ShapeForm(/*Size*/long size) + { + Timer timer = new Timer(); //ExSkip + timer.Interval = 10000; //ExSkip + timer.Tick += timerTick; //ExSkip + timer.Start(); //ExSkip + Size = size; + mShapesToRender = new ArrayList>(); + } + + public void addShapeToRenderToScale(ShapeBase shape, float x, float y, float scale) + { + mShapesToRender.add(new DictionaryEntry<>(shape, new float[] {x, y, scale})); + } + + public void addShapeToRenderToSize(ShapeBase shape, float x, float y, float width, float height) + { + mShapesToRender.add(new DictionaryEntry<>(shape, new float[] {x, y, width, height})); + } + + protected /*override*/ void onPaint(PaintEventArgs e) throws Exception + { + for (Map.Entry renderingArgs : mShapesToRender) + if (renderingArgs.getValue().length == 3) + renderShapeToScale(renderingArgs.getKey(), renderingArgs.getValue()[0], renderingArgs.getValue()[1], + renderingArgs.getValue()[2]); + else if (renderingArgs.getValue().length == 4) + renderShapeToSize(renderingArgs.getKey(), renderingArgs.getValue()[0], renderingArgs.getValue()[1], + renderingArgs.getValue()[2], renderingArgs.getValue()[3]); + } + + private void renderShapeToScale(ShapeBase shape, float x, float y, float scale) throws Exception + { + ShapeRenderer renderer = new ShapeRenderer(shape); + Graphics2D formGraphics = CreateGraphics(); + try /*JAVA: was using*/ + { + renderer.renderToScaleInternal(formGraphics, x, y, scale); + } + finally { if (formGraphics != null) formGraphics.close(); } + } + + private void renderShapeToSize(ShapeBase shape, float x, float y, float width, float height) throws Exception + { + ShapeRenderer renderer = new ShapeRenderer(shape); + Graphics2D formGraphics = CreateGraphics(); + try /*JAVA: was using*/ + { + renderer.renderToSize(formGraphics, x, y, width, height); + } + finally { if (formGraphics != null) formGraphics.close(); } + } + + private void timerTick(Object sender, EventArgs e) => private Closeclose(); //ExSkip + private /*final*/ ArrayList> mShapesToRender; + } + //ExEnd + + @Test + public void renderToSize() throws Exception + { + //ExStart + //ExFor:Document.RenderToSize + //ExSummary:Shows how to render a document to a bitmap at a specified location and size. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + BufferedImage bmp = new BufferedImage(700, 700); + try /*JAVA: was using*/ + { + Graphics2D gr = Graphics2D.FromImage(bmp); + try /*JAVA: was using*/ + { + gr.TextRenderingHint = TextRenderingHint.ANTI_ALIAS_GRID_FIT; + + // Set the "PageUnit" property to "GraphicsUnit.Inch" to use inches as the + // measurement unit for any transformations and dimensions that we will define. + gr.PageUnit = GraphicsUnit.Inch; + + // Offset the output 0.5" from the edge. + gr.TranslateTransform(0.5f, 0.5f); + + // Rotate the output by 10 degrees. + gr.RotateTransform(10f); + + // Draw a 3"x3" rectangle. + gr.DrawRectangle(new Pen(Color.BLACK, 3f / 72f), 0f, 0f, 3f, 3f); + + // Draw the first page of our document with the same dimensions and transformation as the rectangle. + // The rectangle will frame the first page. + float returnedScale = doc.renderToSize(0, gr, 0f, 0f, 3f, 3f); + + // This is the scaling factor that the RenderToSize method applied to the first page to fit the specified size. + Assert.assertEquals(0.2566f, 0.0001f, returnedScale); + + // Set the "PageUnit" property to "GraphicsUnit.Millimeter" to use millimeters as the + // measurement unit for any transformations and dimensions that we will define. + gr.PageUnit = GraphicsUnit.Millimeter; + + // Reset the transformations that we used from the previous rendering. + gr.ResetTransform(); + + // Apply another set of transformations. + gr.TranslateTransform(10f, 10f); + gr.ScaleTransform(0.5f, 0.5f); + gr.PageScale = 2f; + + // Create another rectangle and use it to frame another page from the document. + gr.DrawRectangle(new Pen(Color.BLACK, 1f), 90, 10, 50, 100); + doc.renderToSize(1, gr, 90f, 10f, 50f, 100f); + + bmp.Save(getArtifactsDir() + "Rendering.RenderToSize.png"); + } + finally { if (gr != null) gr.close(); } + } + finally { if (bmp != null) bmp.close(); } + //ExEnd + } + + @Test + public void thumbnails() throws Exception + { + //ExStart + //ExFor:Document.RenderToScale + //ExSummary:Shows how to the individual pages of a document to graphics to create one image with thumbnails of all pages. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // Calculate the number of rows and columns that we will fill with thumbnails. + final int THUMB_COLUMNS = 2; + int thumbRows = doc.getPageCount() / THUMB_COLUMNS; + int remainder = doc.getPageCount() % THUMB_COLUMNS; + + if (remainder > 0) + thumbRows++; + + // Scale the thumbnails relative to the size of the first page. + final float SCALE = 0.25f; + /*Size*/long thumbSize = doc.getPageInfo(0).getSizeInPixelsInternal(SCALE, 96f); + + // Calculate the size of the image that will contain all the thumbnails. + int imgWidth = msSize.getWidth(thumbSize) * THUMB_COLUMNS; + int imgHeight = msSize.getHeight(thumbSize) * thumbRows; + + BufferedImage img = new BufferedImage(imgWidth, imgHeight); + try /*JAVA: was using*/ + { + Graphics2D gr = Graphics2D.FromImage(img); + try /*JAVA: was using*/ + { + gr.TextRenderingHint = TextRenderingHint.ANTI_ALIAS_GRID_FIT; + + // Fill the background, which is transparent by default, in white. + gr.FillRectangle(new SolidBrush(Color.WHITE), 0, 0, imgWidth, imgHeight); + + for (int pageIndex = 0; pageIndex < doc.getPageCount(); pageIndex++) + { + int rowIdx = pageIndex / THUMB_COLUMNS; + int columnIdx = pageIndex % THUMB_COLUMNS; + + // Specify where we want the thumbnail to appear. + float thumbLeft = columnIdx * msSize.getWidth(thumbSize); + float thumbTop = rowIdx * msSize.getHeight(thumbSize); + + // Render a page as a thumbnail, and then frame it in a rectangle of the same size. + /*SizeF*/long size = doc.renderToScaleInternal(pageIndex, gr, thumbLeft, thumbTop, SCALE); + gr.DrawRectangle(Pens.Black, thumbLeft, thumbTop, msSizeF.getWidth(size), msSizeF.getHeight(size)); + } + + img.Save(getArtifactsDir() + "Rendering.Thumbnails.png"); + } + finally { if (gr != null) gr.close(); } + } + finally { if (img != null) img.close(); } + //ExEnd + } +} diff --git a/Examples/ApiExamples/JavaPorting/ExReplaceHyperlinks.java b/Examples/ApiExamples/JavaPorting/ExReplaceHyperlinks.java new file mode 100644 index 00000000..12c100ac --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExReplaceHyperlinks.java @@ -0,0 +1,229 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +//ExStart +//ExFor:NodeList +//ExFor:FieldStart +//ExSummary:Shows how to find all hyperlinks in a Word document, and then change their URLs and display names. +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.NodeList; +import com.aspose.words.FieldStart; +import com.aspose.words.FieldType; +import com.aspose.words.NodeType; +import com.aspose.ms.System.Text.RegularExpressions.Match; +import com.aspose.words.Run; +import java.text.MessageFormat; +import com.aspose.words.Node; +import com.aspose.ms.System.Text.msStringBuilder; +import com.aspose.ms.System.Text.RegularExpressions.Regex; + + +@Test //ExSkip +public class ExReplaceHyperlinks extends ApiExampleBase +{ + @Test //ExSkip + public void fields() throws Exception + { + Document doc = new Document(getMyDir() + "Hyperlinks.docx"); + + // Hyperlinks in a Word documents are fields. To begin looking for hyperlinks, we must first find all the fields. + // Use the "SelectNodes" method to find all the fields in the document via an XPath. + NodeList fieldStarts = doc.selectNodes("//FieldStart"); + + for (FieldStart fieldStart : fieldStarts.OfType() !!Autoporter error: Undefined expression type ) + { + if (fieldStart.getFieldType() == FieldType.FIELD_HYPERLINK) + { + Hyperlink hyperlink = new Hyperlink(fieldStart); + + // Hyperlinks that link to bookmarks do not have URLs. + if (hyperlink.isLocal()) + continue; + + // Give each URL hyperlink a new URL and name. + hyperlink.setTarget(NEW_URL); + hyperlink.setName(NEW_NAME); + } + } + + doc.save(getArtifactsDir() + "ReplaceHyperlinks.Fields.docx"); + } + + private static final String NEW_URL = "http://www.aspose.com"; + private static final String NEW_NAME = "Aspose - The .NET & Java Component Publisher"; +} + +/// +/// HYPERLINK fields contain and display hyperlinks in the document body. A field in Aspose.Words +/// consists of several nodes, and it might be difficult to work with all those nodes directly. +/// This implementation will work only if the hyperlink code and name each consist of only one Run node. +/// +/// The node structure for fields is as follows: +/// +/// [FieldStart][Run - field code][FieldSeparator][Run - field result][FieldEnd] +/// +/// Below are two example field codes of HYPERLINK fields: +/// HYPERLINK "url" +/// HYPERLINK \l "bookmark name" +/// +/// A field's "Result" property contains text that the field displays in the document body to the user. +/// +class Hyperlink +{ + Hyperlink(FieldStart fieldStart) + { + if (fieldStart == null) + throw new NullPointerException("Value cannot be null.\r\nParameter name: " + "fieldStart"); + if (fieldStart.getFieldType() != FieldType.FIELD_HYPERLINK) + throw new IllegalArgumentException("Field start type must be FieldHyperlink."); + + mFieldStart = fieldStart; + + // Find the field separator node. + mFieldSeparator = findNextSibling(mFieldStart, NodeType.FIELD_SEPARATOR); + if (mFieldSeparator == null) + throw new IllegalStateException("Cannot find field separator."); + + // Normally, we can always find the field's end node, but the example document + // contains a paragraph break inside a hyperlink, which puts the field end + // in the next paragraph. It will be much more complicated to handle fields which span several + // paragraphs correctly. In this case allowing field end to be null is enough. + mFieldEnd = findNextSibling(mFieldSeparator, NodeType.FIELD_END); + + // Field code looks something like "HYPERLINK "http:\\www.myurl.com"", but it can consist of several runs. + String fieldCode = getTextSameParent(mFieldStart.getNextSibling(), mFieldSeparator); + Match match = G_REGEX.match(fieldCode.trim()); + + // The hyperlink is local if \l is present in the field code. + mIsLocal = match.getGroups().get(1).getLength() > 0; + mTarget = match.getGroups().get(2).getValue(); + } + + /// + /// Gets or sets the display name of the hyperlink. + /// + String getName() + { + return getTextSameParent(mFieldSeparator, mFieldEnd); + } + void setName(String value) + { + // Hyperlink display name is stored in the field result, which is a Run + // node between field separator and field end. + Run fieldResult = (Run) mFieldSeparator.getNextSibling(); + fieldResult.setText(value); + + // If the field result consists of more than one run, delete these runs. + removeSameParent(fieldResult.getNextSibling(), mFieldEnd); + } + + /// + /// Gets or sets the target URL or bookmark name of the hyperlink. + /// + String getTarget() + { + return mTarget; + } + void setTarget(String value) + { + mTarget = value; + updateFieldCode(); + } + + /// + /// True if the hyperlinks target is a bookmark inside the document. False if the hyperlink is a URL. + /// + boolean isLocal() + { + return mIsLocal; + } + void isLocal(boolean value) + { + mIsLocal = value; + updateFieldCode(); + } + + private void updateFieldCode() + { + // A field's field code is in a Run node between the field's start node and field separator. + Run fieldCode = (Run) mFieldStart.getNextSibling(); + fieldCode.setText(MessageFormat.format("HYPERLINK {0}\"{1}\"", ((mIsLocal) ? "\\l " : ""), mTarget)); + + // If the field code consists of more than one run, delete these runs. + removeSameParent(fieldCode.getNextSibling(), mFieldSeparator); + } + + /// + /// Goes through siblings starting from the start node until it finds a node of the specified type or null. + /// + private static Node findNextSibling(Node startNode, /*NodeType*/int nodeType) + { + for (Node node = startNode; node != null; node = node.getNextSibling()) + { + if (node.getNodeType() == nodeType) + return node; + } + + return null; + } + + /// + /// Retrieves text from start up to but not including the end node. + /// + private static String getTextSameParent(Node startNode, Node endNode) + { + if ((endNode != null) && (startNode.getParentNode() != endNode.getParentNode())) + throw new IllegalArgumentException("Start and end nodes are expected to have the same parent."); + + StringBuilder builder = new StringBuilder(); + for (Node child = startNode; !child.equals(endNode); child = child.getNextSibling()) + msStringBuilder.append(builder, child.getText()); + + return builder.toString(); + } + + /// + /// Removes nodes from start up to but not including the end node. + /// Assumes that the start and end nodes have the same parent. + /// + private static void removeSameParent(Node startNode, Node endNode) + { + if (endNode != null && startNode.getParentNode() != endNode.getParentNode()) + throw new IllegalArgumentException("Start and end nodes are expected to have the same parent."); + + Node curChild = startNode; + while ((curChild != null) && (curChild != endNode)) + { + Node nextChild = curChild.getNextSibling(); + curChild.remove(); + curChild = nextChild; + } + } + + private /*final*/ Node mFieldStart; + private /*final*/ Node mFieldSeparator; + private /*final*/ Node mFieldEnd; + private boolean mIsLocal; + private String mTarget; + + private static /*final*/ Regex G_REGEX = new Regex( + "\\S+" + // One or more non spaces HYPERLINK or other word in other languages. + "\\s+" + // One or more spaces. + "(?:\"\"\\s+)?" + // Non-capturing optional "" and one or more spaces. + "(\\\\l\\s+)?" + // Optional \l flag followed by one or more spaces. + "\"" + // One apostrophe. + "([^\"]+)" + // One or more characters, excluding the apostrophe (hyperlink target). + "\"" // One closing apostrophe. + ); +} + +//ExEnd \ No newline at end of file diff --git a/Examples/ApiExamples/JavaPorting/ExReportingEngine.java b/Examples/ApiExamples/JavaPorting/ExReportingEngine.java new file mode 100644 index 00000000..eadf23ba --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExReportingEngine.java @@ -0,0 +1,1505 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import ApiExamples.TestData.TestClasses.MessageTestClass; +import com.aspose.words.ReportBuildOptions; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import ApiExamples.TestData.TestClasses.NumericTestClass; +import ApiExamples.TestData.TestBuilders.NumericTestBuilder; +import com.aspose.ms.System.DateTime; +import ApiExamples.TestData.Common; +import ApiExamples.TestData.TestClasses.DocumentTestClass; +import ApiExamples.TestData.TestBuilders.DocumentTestBuilder; +import java.util.ArrayList; +import ApiExamples.TestData.TestClasses.ColorItemTestClass; +import ApiExamples.TestData.TestBuilders.ColorItemTestBuilder; +import java.awt.Color; +import com.aspose.ms.System.Drawing.msColor; +import com.aspose.words.ReportingEngine; +import com.aspose.words.net.System.Data.DataSet; +import com.aspose.ms.System.Environment; +import com.aspose.ms.System.IO.FileStream; +import com.aspose.ms.System.IO.FileMode; +import com.aspose.ms.System.IO.FileAccess; +import com.aspose.ms.System.IO.File; +import com.aspose.words.ShapeType; +import ApiExamples.TestData.TestClasses.ImageTestClass; +import ApiExamples.TestData.TestBuilders.ImageTestBuilder; +import com.aspose.words.DocumentBuilder; +import ApiExamples.TestData.TestClasses.ClientTestClass; +import com.aspose.words.NodeCollection; +import com.aspose.words.NodeType; +import com.aspose.words.Shape; +import com.aspose.ms.System.msString; +import com.aspose.words.FileFormatUtil; +import com.aspose.words.SaveFormat; +import com.aspose.words.XmlDataSource; +import java.io.FileInputStream; +import com.aspose.words.JsonDataLoadOptions; +import com.aspose.words.JsonSimpleValueParseMode; +import com.aspose.words.JsonDataSource; +import com.aspose.ms.System.IO.MemoryStream; +import com.aspose.ms.System.Text.Encoding; +import com.aspose.words.ControlChar; +import com.aspose.words.CsvDataLoadOptions; +import com.aspose.words.CsvDataSource; +import com.aspose.words.SdtType; +import com.aspose.words.SdtListItem; +import com.aspose.words.StructuredDocumentTag; +import com.aspose.words.MarkupLevel; +import java.lang.Class; +import org.testng.annotations.DataProvider; + + +@Test +public class ExReportingEngine extends ApiExampleBase +{ + private /*final*/ String mImage = getImageDir() + "Logo.jpg"; + private /*final*/ String mDocument = getMyDir() + "Reporting engine template - Data table.docx"; + + @Test + public void simpleCase() throws Exception + { + Document doc = DocumentHelper.createSimpleDocument("<<[s.Name]>> says: <<[s.Message]>>"); + + MessageTestClass sender = new MessageTestClass("LINQ Reporting Engine", "Hello World"); + buildReport(doc, sender, "s", ReportBuildOptions.INLINE_ERROR_MESSAGES); + + doc = DocumentHelper.saveOpen(doc); + + Assert.assertEquals("LINQ Reporting Engine says: Hello World\f", doc.getText()); + } + + @Test + public void stringFormat() throws Exception + { + Document doc = DocumentHelper.createSimpleDocument( + "<<[s.Name]:lower>> says: <<[s.Message]:upper>>, <<[s.Message]:caps>>, <<[s.Message]:firstCap>>"); + + MessageTestClass sender = new MessageTestClass("LINQ Reporting Engine", "hello world"); + buildReport(doc, sender, "s"); + + doc = DocumentHelper.saveOpen(doc); + + Assert.assertEquals("linq reporting engine says: HELLO WORLD, Hello World, Hello world\f", doc.getText()); + } + + @Test + public void numberFormat() throws Exception + { + Document doc = DocumentHelper.createSimpleDocument( + "<<[s.Value1]:alphabetic>> : <<[s.Value2]:roman:lower>>, <<[s.Value3]:ordinal>>, <<[s.Value1]:ordinalText:upper>>" + + ", <<[s.Value2]:cardinal>>, <<[s.Value3]:hex>>, <<[s.Value3]:arabicDash>>"); + + NumericTestClass sender = new NumericTestBuilder() + .withValuesAndDate(1, 2.2, 200, null, DateTime.parse("10.09.2016 10:00:00")).build(); + buildReport(doc, sender, "s"); + + doc = DocumentHelper.saveOpen(doc); + + Assert.assertEquals("A : ii, 200th, FIRST, Two, C8, - 200 -\f", doc.getText()); + } + + @Test + public void testDataTable() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Data table.docx"); + + buildReport(doc, Common.getContracts(), "Contracts"); + + doc.save(getArtifactsDir() + "ReportingEngine.TestDataTable.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.TestDataTable.docx", getGoldsDir() + "ReportingEngine.TestDataTable Gold.docx")); + } + + @Test + public void total() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Total.docx"); + + buildReport(doc, Common.getContracts(), "Contracts"); + + doc.save(getArtifactsDir() + "ReportingEngine.Total.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.Total.docx", getGoldsDir() + "ReportingEngine.Total Gold.docx")); + } + + @Test + public void testNestedDataTable() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Nested data table.docx"); + + buildReport(doc, Common.getManagers(), "Managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.TestNestedDataTable.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.TestNestedDataTable.docx", getGoldsDir() + "ReportingEngine.TestNestedDataTable Gold.docx")); + } + + @Test + public void restartingListNumberingDynamically() throws Exception + { + Document template = new Document(getMyDir() + "Reporting engine template - List numbering.docx"); + + buildReport(template, Common.getManagers(), "Managers", ReportBuildOptions.REMOVE_EMPTY_PARAGRAPHS); + + template.save(getArtifactsDir() + "ReportingEngine.RestartingListNumberingDynamically.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.RestartingListNumberingDynamically.docx", getGoldsDir() + "ReportingEngine.RestartingListNumberingDynamically Gold.docx")); + } + + @Test + public void restartingListNumberingDynamicallyWhileInsertingDocumentDynamically() throws Exception + { + Document template = DocumentHelper.createSimpleDocument("<>"); + + DocumentTestClass doc = new DocumentTestBuilder() + .withDocument(new Document(getMyDir() + "Reporting engine template - List numbering.docx")).build(); + + buildReport(template, new Object[] {doc, Common.getManagers()} , new String[] {"src", "Managers"}, ReportBuildOptions.REMOVE_EMPTY_PARAGRAPHS); + + template.save(getArtifactsDir() + "ReportingEngine.RestartingListNumberingDynamicallyWhileInsertingDocumentDynamically.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.RestartingListNumberingDynamicallyWhileInsertingDocumentDynamically.docx", getGoldsDir() + "ReportingEngine.RestartingListNumberingDynamicallyWhileInsertingDocumentDynamically Gold.docx")); + } + + @Test + public void restartingListNumberingDynamicallyWhileMultipleInsertionsDocumentDynamically() throws Exception + { + Document mainTemplate = DocumentHelper.createSimpleDocument("<>"); + Document template1 = DocumentHelper.createSimpleDocument("<>"); + Document template2 = DocumentHelper.createSimpleDocument("<>"); + + DocumentTestClass doc = new DocumentTestBuilder() + .withDocument(new Document(getMyDir() + "Reporting engine template - List numbering.docx")).build(); + + buildReport(mainTemplate, new Object[] {template1, template2, doc, Common.getManagers()} , new String[] {"src", "src1", "src2", "Managers"}, ReportBuildOptions.REMOVE_EMPTY_PARAGRAPHS); + + mainTemplate.save(getArtifactsDir() + "ReportingEngine.RestartingListNumberingDynamicallyWhileMultipleInsertionsDocumentDynamically.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.RestartingListNumberingDynamicallyWhileMultipleInsertionsDocumentDynamically.docx", getGoldsDir() + "ReportingEngine.RestartingListNumberingDynamicallyWhileInsertingDocumentDynamically Gold.docx")); + } + + @Test + public void chartTest() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Chart.docx"); + + buildReport(doc, Common.getManagers(), "managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.TestChart.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.TestChart.docx", getGoldsDir() + "ReportingEngine.TestChart Gold.docx")); + } + + @Test + public void bubbleChartTest() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Bubble chart.docx"); + + buildReport(doc, Common.getManagers(), "managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.TestBubbleChart.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.TestBubbleChart.docx", getGoldsDir() + "ReportingEngine.TestBubbleChart Gold.docx")); + } + + @Test + public void setChartSeriesColorsDynamically() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Chart series color.docx"); + + buildReport(doc, Common.getManagers(), "managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.SetChartSeriesColorDynamically.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.SetChartSeriesColorDynamically.docx", getGoldsDir() + "ReportingEngine.SetChartSeriesColorDynamically Gold.docx")); + } + + @Test + public void setPointColorsDynamically() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Point color.docx"); + + ArrayList colors = new ArrayList(); + { + colors.add(new ColorItemTestBuilder().withColorCodeAndValues("Black", Color.BLACK.getRGB(), 1.0, 2.5, 3.5).build()); + colors.add(new ColorItemTestBuilder().withColorCodeAndValues("Red", Color.RED.getRGB(), 2.0, 4.0, 2.5).build()); + colors.add(new ColorItemTestBuilder().withColorCodeAndValues("Green", msColor.getGreen().getRGB(), 0.5, 1.5, 2.5).build()); + colors.add(new ColorItemTestBuilder().withColorCodeAndValues("Blue", Color.BLUE.getRGB(), 4.5, 3.5, 1.5).build()); + colors.add(new ColorItemTestBuilder().withColorCodeAndValues("Yellow", Color.YELLOW.getRGB(), 5.0, 2.5, 1.5) + .build()); + } + + buildReport(doc, colors, "colorItems", new Class[] { ColorItemTestClass.class }); + + doc.save(getArtifactsDir() + "ReportingEngine.SetPointColorDynamically.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.SetPointColorDynamically.docx", getGoldsDir() + "ReportingEngine.SetPointColorDynamically Gold.docx")); + } + + @Test + public void conditionalExpressionForLeaveChartSeries() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Chart series.docx"); + + int condition = 3; + buildReport(doc, new Object[] { Common.getManagers(), condition }, new String[] { "managers", "condition" }); + + doc.save(getArtifactsDir() + "ReportingEngine.TestLeaveChartSeries.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.TestLeaveChartSeries.docx", getGoldsDir() + "ReportingEngine.TestLeaveChartSeries Gold.docx")); + } + + @Test (enabled = false, description = "WORDSNET-20810") + public void conditionalExpressionForRemoveChartSeries() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Chart series.docx"); + + int condition = 2; + buildReport(doc, new Object[] { Common.getManagers(), condition }, new String[] { "managers", "condition" }); + + doc.save(getArtifactsDir() + "ReportingEngine.TestRemoveChartSeries.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.TestRemoveChartSeries.docx", getGoldsDir() + "ReportingEngine.TestRemoveChartSeries Gold.docx")); + } + + @Test + public void indexOf() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Index of.docx"); + + buildReport(doc, Common.getManagers(), "Managers"); + + doc = DocumentHelper.saveOpen(doc); + + Assert.assertEquals("The names are: John Smith, Tony Anderson, July James\f", doc.getText()); + } + + @Test + public void ifElse() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - If-else.docx"); + + buildReport(doc, Common.getManagers(), "m"); + + doc = DocumentHelper.saveOpen(doc); + + Assert.assertEquals("You have chosen 3 item(s).\f", doc.getText()); + } + + @Test + public void ifElseWithoutData() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - If-else.docx"); + + buildReport(doc, Common.getEmptyManagers(), "m"); + + doc = DocumentHelper.saveOpen(doc); + + Assert.assertEquals("You have chosen no items.\f", doc.getText()); + } + + @Test + public void extensionMethods() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Extension methods.docx"); + + buildReport(doc, Common.getManagers(), "Managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.ExtensionMethods.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.ExtensionMethods.docx", getGoldsDir() + "ReportingEngine.ExtensionMethods Gold.docx")); + } + + @Test + public void operators() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Operators.docx"); + + NumericTestClass testData = new NumericTestBuilder().withValuesAndLogical(1, 2.0, 3, null, true).build(); + + ReportingEngine report = new ReportingEngine(); + report.getKnownTypes().add(NumericTestBuilder.class); + report.buildReport(doc, testData, "ds"); + + doc.save(getArtifactsDir() + "ReportingEngine.Operators.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.Operators.docx", getGoldsDir() + "ReportingEngine.Operators Gold.docx")); + } + + @Test + public void headerVariable() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Header variable.docx"); + + buildReport(doc, new DataSet(), "", ReportBuildOptions.USE_LEGACY_HEADER_FOOTER_VISITING); + + doc.save(getArtifactsDir() + "ReportingEngine.HeaderVariable.docx"); + + Assert.assertEquals("Value of myHeaderVariable is: I am header variable", doc.getFirstSection().getBody().getFirstParagraph().getText().trim()); + } + + @Test + public void contextualObjectMemberAccess() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Contextual object member access.docx"); + + buildReport(doc, Common.getManagers(), "Managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.ContextualObjectMemberAccess.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.ContextualObjectMemberAccess.docx", getGoldsDir() + "ReportingEngine.ContextualObjectMemberAccess Gold.docx")); + } + + @Test + public void insertDocumentDynamicallyWithAdditionalTemplateChecking() throws Exception + { + Document template = DocumentHelper.createSimpleDocument("<>"); + + DocumentTestClass doc = new DocumentTestBuilder() + .withDocument(new Document(getMyDir() + "Reporting engine template - Data table.docx")).build(); + + buildReport(template, new Object[] { doc, Common.getContracts() }, new String[] { "src", "Contracts" }, + ReportBuildOptions.NONE); + template.save( + getArtifactsDir() + "ReportingEngine.InsertDocumentDynamicallyWithAdditionalTemplateChecking.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs( + getArtifactsDir() + "ReportingEngine.InsertDocumentDynamicallyWithAdditionalTemplateChecking.docx", + getGoldsDir() + "ReportingEngine.InsertDocumentDynamicallyWithAdditionalTemplateChecking Gold.docx"), "Fail inserting document by document"); + } + + @Test + public void insertDocumentDynamicallyWithStyles() throws Exception + { + Document template = DocumentHelper.createSimpleDocument("<>"); + + DocumentTestClass doc = new DocumentTestBuilder() + .withDocument(new Document(getMyDir() + "Reporting engine template - Data table.docx")).build(); + + buildReport(template, doc, "src", ReportBuildOptions.NONE); + template.save(getArtifactsDir() + "ReportingEngine.InsertDocumentDynamically.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.InsertDocumentDynamically.docx", getGoldsDir() + "ReportingEngine.InsertDocumentDynamically(stream,doc,bytes) Gold.docx"), "Fail inserting document by document"); + } + + @Test + public void insertDocumentDynamicallyTrimLastParagraph() throws Exception + { + Document template = DocumentHelper.createSimpleDocument("<>"); + + DocumentTestClass doc = new DocumentTestBuilder() + .withDocument(new Document(getMyDir() + "Reporting engine template - Data table.docx")).build(); + + buildReport(template, doc, "src", ReportBuildOptions.NONE); + template.save(getArtifactsDir() + "ReportingEngine.InsertDocumentDynamically.docx"); + + template = new Document(getArtifactsDir() + "ReportingEngine.InsertDocumentDynamically.docx"); + Assert.assertEquals(1, template.getFirstSection().getBody().getParagraphs().getCount()); + } + + @Test + public void sourseListNumbering() throws Exception + { + //ExStart:SourseListNumbering + //GistId:6e4482e7434754c31c6f2f6e4bf48bb1 + //ExFor:ReportingEngine.BuildReport(Document, Object[], String[]) + //ExSummary:Shows how to keep inserted numbering as is. + // By default, numbered lists from a template document are continued when their identifiers match those from a document being inserted. + // With "-sourceNumbering" numbering should be separated and kept as is. + Document template = DocumentHelper.createSimpleDocument("<>" + Environment.getNewLine() + "<>"); + + DocumentTestClass doc = new DocumentTestBuilder() + .withDocument(new Document(getMyDir() + "List item.docx")).build(); + + ReportingEngine engine = new ReportingEngine(); { engine.setOptions(ReportBuildOptions.REMOVE_EMPTY_PARAGRAPHS); } + engine.buildReport(template, new Object[] { doc }, new String[] { "src" }); + + template.save(getArtifactsDir() + "ReportingEngine.SourseListNumbering.docx"); + //ExEnd:SourseListNumbering + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.SourseListNumbering.docx", getGoldsDir() + "ReportingEngine.SourseListNumbering Gold.docx")); + } + + @Test + public void insertDocumentDynamicallyByStream() throws Exception + { + Document template = DocumentHelper.createSimpleDocument("<>"); + + DocumentTestClass docStream = new DocumentTestBuilder() + .withDocumentStream(new FileStream(mDocument, FileMode.OPEN, FileAccess.READ)).build(); + + buildReport(template, docStream, "src", ReportBuildOptions.NONE); + template.save(getArtifactsDir() + "ReportingEngine.InsertDocumentDynamically.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.InsertDocumentDynamically.docx", getGoldsDir() + "ReportingEngine.InsertDocumentDynamically(stream,doc,bytes) Gold.docx"), "Fail inserting document by stream"); + } + + @Test + public void insertDocumentDynamicallyByBytes() throws Exception + { + Document template = DocumentHelper.createSimpleDocument("<>"); + + DocumentTestClass docBytes = new DocumentTestBuilder() + .withDocumentBytes(File.readAllBytes(getMyDir() + "Reporting engine template - Data table.docx")).build(); + + buildReport(template, docBytes, "src", ReportBuildOptions.NONE); + template.save(getArtifactsDir() + "ReportingEngine.InsertDocumentDynamically.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.InsertDocumentDynamically.docx", getGoldsDir() + "ReportingEngine.InsertDocumentDynamically(stream,doc,bytes) Gold.docx"), "Fail inserting document by bytes"); + } + + @Test + public void insertDocumentDynamicallyByUri() throws Exception + { + Document template = DocumentHelper.createSimpleDocument("<>"); + + DocumentTestClass docUri = new DocumentTestBuilder() + .withDocumentString("http://www.snee.com/xml/xslt/sample.doc").build(); + + buildReport(template, docUri, "src", ReportBuildOptions.NONE); + template.save(getArtifactsDir() + "ReportingEngine.InsertDocumentDynamically.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.InsertDocumentDynamically.docx", getGoldsDir() + "ReportingEngine.InsertDocumentDynamically(uri) Gold.docx"), "Fail inserting document by uri"); + } + + @Test + public void insertDocumentDynamicallyByBase64() throws Exception + { + Document template = DocumentHelper.createSimpleDocument("<>"); + String base64Template = File.readAllText(getMyDir() + "Reporting engine template - Data table (base64).txt"); + + DocumentTestClass docBase64 = new DocumentTestBuilder().withDocumentString(base64Template).build(); + + buildReport(template, docBase64, "src", ReportBuildOptions.NONE); + template.save(getArtifactsDir() + "ReportingEngine.InsertDocumentDynamically.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.InsertDocumentDynamically.docx", getGoldsDir() + "ReportingEngine.InsertDocumentDynamically(stream,doc,bytes) Gold.docx"), "Fail inserting document by uri"); + } + + @Test + public void insertImageDynamically() throws Exception + { + Document template = + DocumentHelper.createTemplateDocumentWithDrawObjects("<>", ShapeType.TEXT_BOX); + + ImageTestClass image = new ImageTestBuilder().withImage(mImage).build(); + + buildReport(template, image, "src", ReportBuildOptions.NONE); + template.save(getArtifactsDir() + "ReportingEngine.InsertImageDynamically.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.InsertImageDynamically.docx", getGoldsDir() + "ReportingEngine.InsertImageDynamically(stream,doc,bytes) Gold.docx"), "Fail inserting document by bytes"); + } + + @Test + public void insertImageDynamicallyByStream() throws Exception + { + Document template = + DocumentHelper.createTemplateDocumentWithDrawObjects("<>", ShapeType.TEXT_BOX); + ImageTestClass imageStream = new ImageTestBuilder() + .withImageStream(new FileStream(mImage, FileMode.OPEN, FileAccess.READ)).build(); + + buildReport(template, imageStream, "src", ReportBuildOptions.NONE); + template.save(getArtifactsDir() + "ReportingEngine.InsertImageDynamically.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.InsertImageDynamically.docx", getGoldsDir() + "ReportingEngine.InsertImageDynamically(stream,doc,bytes) Gold.docx"), "Fail inserting document by bytes"); + } + + @Test + public void insertImageDynamicallyByBytes() throws Exception + { + Document template = + DocumentHelper.createTemplateDocumentWithDrawObjects("<>", ShapeType.TEXT_BOX); + ImageTestClass imageBytes = new ImageTestBuilder().withImageBytes(File.readAllBytes(mImage)).build(); + + buildReport(template, imageBytes, "src", ReportBuildOptions.NONE); + template.save(getArtifactsDir() + "ReportingEngine.InsertImageDynamically.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.InsertImageDynamically.docx", getGoldsDir() + "ReportingEngine.InsertImageDynamically(stream,doc,bytes) Gold.docx"), "Fail inserting document by bytes"); + } + + @Test + public void insertImageDynamicallyByUri() throws Exception + { + Document template = + DocumentHelper.createTemplateDocumentWithDrawObjects("<>", ShapeType.TEXT_BOX); + ImageTestClass imageUri = new ImageTestBuilder() + .withImageString("https://metrics.aspose.com/img/headergraphics.svg") + .build(); + + buildReport(template, imageUri, "src", ReportBuildOptions.NONE); + template.save(getArtifactsDir() + "ReportingEngine.InsertImageDynamically.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.InsertImageDynamically.docx", + getGoldsDir() + "ReportingEngine.InsertImageDynamically(uri) Gold.docx"), "Fail inserting document by bytes"); + } + + @Test + public void insertImageDynamicallyByBase64() throws Exception + { + Document template = + DocumentHelper.createTemplateDocumentWithDrawObjects("<>", ShapeType.TEXT_BOX); + String base64Template = File.readAllText(getMyDir() + "Reporting engine template - base64 image.txt"); + + ImageTestClass imageBase64 = new ImageTestBuilder().withImageString(base64Template).build(); + + buildReport(template, imageBase64, "src", ReportBuildOptions.NONE); + template.save(getArtifactsDir() + "ReportingEngine.InsertImageDynamically.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.InsertImageDynamically.docx", + getGoldsDir() + "ReportingEngine.InsertImageDynamically(stream,doc,bytes) Gold.docx"), "Fail inserting document by bytes"); + + } + + @Test (dataProvider = "insertHtmlDinamicallyDataProvider") + public void insertHtmlDinamically(String templateText) throws Exception + { + String html = File.readAllText(getMyDir() + "Reporting engine template - Html.html"); + + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln(templateText); + + buildReport(doc, html, "html_text"); + doc.save(getArtifactsDir() + "ReportingEngine.InsertHtmlDinamically.docx"); + } + + //JAVA-added data provider for test method + @DataProvider(name = "insertHtmlDinamicallyDataProvider") + public static Object[][] insertHtmlDinamicallyDataProvider() throws Exception + { + return new Object[][] + { + {"<<[html_text] -html>>"}, + {"<>"}, + {"<>"}, + }; + } + + @Test + public void imageExifOrientation() throws Exception + { + Document template = new Document(getMyDir() + "Reporting engine template - Image exif orientation.docx"); + + byte[] image1Bytes = File.readAllBytes(getImageDir() + "RightF.jpg"); + byte[] image2Bytes = File.readAllBytes(getImageDir() + "WrongF.jpg"); + + buildReport(template, new Object[] { image1Bytes, image2Bytes }, new String[] { "image1", "image2" }, + ReportBuildOptions.RESPECT_JPEG_EXIF_ORIENTATION); + template.save(getArtifactsDir() + "ReportingEngine.ImageExifOrientation.docx"); + } + + @Test + public void dynamicStretchingImageWithinTextBox() throws Exception + { + Document template = new Document(getMyDir() + "Reporting engine template - Dynamic stretching.docx"); + + ImageTestClass image = new ImageTestBuilder().withImage(mImage).build(); + + buildReport(template, image, "src", ReportBuildOptions.NONE); + template.save(getArtifactsDir() + "ReportingEngine.DynamicStretchingImageWithinTextBox.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.DynamicStretchingImageWithinTextBox.docx", + getGoldsDir() + "ReportingEngine.DynamicStretchingImageWithinTextBox Gold.docx")); + } + + @Test (dataProvider = "insertHyperlinksDynamicallyDataProvider") + public void insertHyperlinksDynamically(String link) throws Exception + { + Document template = new Document(getMyDir() + "Reporting engine template - Inserting hyperlinks.docx"); + buildReport(template, + new Object[] + { + link, // Use URI or the name of a bookmark within the same document for a hyperlink + "Aspose" + }, + new String[] + { + "uri_or_bookmark_expression", + "display_text_expression" + }); + + template.save(getArtifactsDir() + "ReportingEngine.InsertHyperlinksDynamically.docx"); + } + + //JAVA-added data provider for test method + @DataProvider(name = "insertHyperlinksDynamicallyDataProvider") + public static Object[][] insertHyperlinksDynamicallyDataProvider() throws Exception + { + return new Object[][] + { + {"https://auckland.dynabic.com/wiki/display/org/Supported+dynamic+insertion+of+hyperlinks+for+LINQ+Reporting+Engine"}, + {"Bookmark"}, + }; + } + + @Test + public void insertBookmarksDynamically() throws Exception + { + Document doc = + DocumentHelper.createSimpleDocument( + "<><><<[m.Client.Name]>><><>"); + + buildReport(doc, new Object[] { "BookmarkOne", Common.getContracts() }, + new String[] { "bookmark_expression", "Contracts" }); + + doc.save(getArtifactsDir() + "ReportingEngine.InsertBookmarksDynamically.docx"); + } + + @Test + public void withoutKnownType() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("<<[new DateTime()]:”dd.MM.yyyy”>>"); + + ReportingEngine engine = new ReportingEngine(); + Assert.Throws(() => engine.buildReport(doc, "")); + } + + @Test + public void workWithKnownTypes() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("<<[new DateTime(2016, 1, 20)]:”dd.MM.yyyy”>>"); + builder.writeln("<<[new DateTime(2016, 1, 20)]:”dd”>>"); + builder.writeln("<<[new DateTime(2016, 1, 20)]:”MM”>>"); + builder.writeln("<<[new DateTime(2016, 1, 20)]:”yyyy”>>"); + builder.writeln("<<[new DateTime(2016, 1, 20).Month]>>"); + + buildReport(doc, "", new Class[]{ DateTime.class }); + + doc.save(getArtifactsDir() + "ReportingEngine.KnownTypes.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.KnownTypes.docx", getGoldsDir() + "ReportingEngine.KnownTypes Gold.docx")); + } + + @Test + public void workWithContentControls() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - CheckBox Content Control.docx"); + buildReport(doc, Common.getManagers(), "Managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.WorkWithContentControls.docx"); + } + + @Test + public void workWithSingleColumnTableRow() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Table row.docx"); + buildReport(doc, Common.getManagers(), "Managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.SingleColumnTableRow.docx"); + } + + @Test + public void workWithSingleColumnTableRowGreedy() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Table row greedy.docx"); + buildReport(doc, Common.getManagers(), "Managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.SingleColumnTableRowGreedy.docx"); + } + + @Test + public void tableRowConditionalBlocks() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Table row conditional blocks.docx"); + + ArrayList clients = new ArrayList(); + { + clients.add(new ClientTestClass()); + { + ((ClientTestClass)clients.get(0)).setName("John Monrou"); + ((ClientTestClass)clients.get(0)).setCountry("France"); + ((ClientTestClass)clients.get(0)).setLocalAddress("27 RUE PASTEUR"); + } + clients.add(new ClientTestClass()); + { + ((ClientTestClass)clients.get(1)).setName("James White"); + ((ClientTestClass)clients.get(1)).setCountry("England"); + ((ClientTestClass)clients.get(1)).setLocalAddress("14 Tottenham Court Road"); + } + clients.add(new ClientTestClass()); + { + ((ClientTestClass)clients.get(2)).setName("Kate Otts"); + ((ClientTestClass)clients.get(2)).setCountry("New Zealand"); + ((ClientTestClass)clients.get(2)).setLocalAddress("Wellington 6004"); + } + } + + buildReport(doc, clients, "clients"); + + doc.save(getArtifactsDir() + "ReportingEngine.TableRowConditionalBlocks.docx"); + } + + @Test + public void ifGreedy() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - If greedy.docx"); + + AsposeData obj = new AsposeData(); + { + obj.setList(new ArrayList()); + { + obj.getList().add("abc"); + } + } + + buildReport(doc, obj); + + doc.save(getArtifactsDir() + "ReportingEngine.IfGreedy.docx"); + } + + public static class AsposeData + { + public ArrayList getList() { return mList; }; public void setList(ArrayList value) { mList = value; }; + + private ArrayList mList; + } + + @Test + public void stretchImagefitHeight() throws Exception + { + Document doc = + DocumentHelper.createTemplateDocumentWithDrawObjects("<>", + ShapeType.TEXT_BOX); + + ImageTestClass imageStream = new ImageTestBuilder() + .withImageStream(new FileStream(mImage, FileMode.OPEN, FileAccess.READ)).build(); + buildReport(doc, imageStream, "src", ReportBuildOptions.NONE); + + doc = DocumentHelper.saveOpen(doc); + + NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); + + for (Shape shape : shapes.OfType() !!Autoporter error: Undefined expression type ) + { + // Assert that the image is really insert in textbox. + Assert.Is.Not.Nullshape.getFill().getImageBytes()); + + // Assert that the width is preserved, and the height is changed. + Assert.Is.Not.EqualTo(346.35)shape.getHeight()); + Assert.assertEquals(431.5, shape.getWidth()); + } + } + + @Test + public void stretchImagefitWidth() throws Exception + { + Document doc = + DocumentHelper.createTemplateDocumentWithDrawObjects("<>", + ShapeType.TEXT_BOX); + + ImageTestClass imageStream = new ImageTestBuilder() + .withImageStream(new FileStream(mImage, FileMode.OPEN, FileAccess.READ)).build(); + buildReport(doc, imageStream, "src", ReportBuildOptions.NONE); + + doc = DocumentHelper.saveOpen(doc); + + NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); + + for (Shape shape : shapes.OfType() !!Autoporter error: Undefined expression type ) + { + Assert.Is.Not.Nullshape.getFill().getImageBytes()); + + // Assert that the height is preserved, and the width is changed. + Assert.Is.Not.EqualTo(431.5)shape.getWidth()); + Assert.assertEquals(346.35, shape.getHeight()); + } + } + + @Test + public void stretchImagefitSize() throws Exception + { + Document doc = + DocumentHelper.createTemplateDocumentWithDrawObjects("<>", + ShapeType.TEXT_BOX); + + ImageTestClass imageStream = new ImageTestBuilder() + .withImageStream(new FileStream(mImage, FileMode.OPEN, FileAccess.READ)).build(); + buildReport(doc, imageStream, "src", ReportBuildOptions.NONE); + + doc = DocumentHelper.saveOpen(doc); + + NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); + + for (Shape shape : shapes.OfType() !!Autoporter error: Undefined expression type ) + { + Assert.Is.Not.Nullshape.getFill().getImageBytes()); + + // Assert that the height and the width are changed. + Assert.Is.Not.EqualTo(346.35)shape.getHeight()); + Assert.Is.Not.EqualTo(431.5)shape.getWidth()); + } + } + + @Test + public void stretchImagefitSizeLim() throws Exception + { + Document doc = + DocumentHelper.createTemplateDocumentWithDrawObjects("<>", + ShapeType.TEXT_BOX); + + ImageTestClass imageStream = new ImageTestBuilder() + .withImageStream(new FileStream(mImage, FileMode.OPEN, FileAccess.READ)).build(); + buildReport(doc, imageStream, "src", ReportBuildOptions.NONE); + + doc = DocumentHelper.saveOpen(doc); + + NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); + + for (Shape shape : shapes.OfType() !!Autoporter error: Undefined expression type ) + { + Assert.Is.Not.Nullshape.getFill().getImageBytes()); + + // Assert that textbox size are equal image size. + Assert.assertEquals(300.0d, shape.getHeight()); + Assert.assertEquals(300.0d, shape.getWidth()); + } + } + + @Test + public void withoutMissingMembers() throws Exception + { + DocumentBuilder builder = new DocumentBuilder(); + + // Add templete to the document for reporting engine. + DocumentHelper.insertBuilderText(builder, + new String[] { "<<[missingObject.First().id]>>", "<><<[id]>><>" }); + + // Assert that build report failed without "ReportBuildOptions.AllowMissingMembers". + Assert.Throws( + () => buildReport(builder.getDocument(), new DataSet(), "", ReportBuildOptions.NONE)); + } + + @Test + public void missingMembers() throws Exception + { + //ExStart:MissingMembers + //GistId:65919861586e42e24f61a3ccb65f8f4e + //ExFor:ReportingEngine.BuildReport(Document, Object, String) + //ExFor:ReportingEngine.MissingMemberMessage + //ExFor:ReportingEngine.Options + //ExSummary:Shows how to allow missinng members. + DocumentBuilder builder = new DocumentBuilder(); + builder.writeln("<<[missingObject.First().id]>>"); + builder.writeln("<><<[id]>><>"); + + ReportingEngine engine = new ReportingEngine(); { engine.setOptions(ReportBuildOptions.ALLOW_MISSING_MEMBERS); } + engine.setMissingMemberMessage("Missed"); + engine.buildReport(builder.getDocument(), new DataSet(), ""); + //ExEnd:MissingMembers + + // Assert that build report success with "ReportBuildOptions.AllowMissingMembers". + Assert.assertEquals("Missed", builder.getDocument().getText().trim()); + } + + @Test (dataProvider = "inlineErrorMessagesDataProvider") + public void inlineErrorMessages(String templateText, String result) throws Exception + { + DocumentBuilder builder = new DocumentBuilder(); + DocumentHelper.insertBuilderText(builder, new String[] { templateText }); + + buildReport(builder.getDocument(), new DataSet(), "", ReportBuildOptions.INLINE_ERROR_MESSAGES); + + Assert.assertEquals(result, msString.trimEnd(builder.getDocument().getFirstSection().getBody().getParagraphs().get(0).getText())); + } + + //JAVA-added data provider for test method + @DataProvider(name = "inlineErrorMessagesDataProvider") + public static Object[][] inlineErrorMessagesDataProvider() throws Exception + { + return new Object[][] + { + {"<<[missingObject.First().id]>>", "<<[missingObject.First( Error! Can not get the value of member 'missingObject' on type 'System.Data.DataSet'. ).id]>>"}, + {"<<[new DateTime()]:\"dd.MM.yyyy\">>", "<<[new DateTime( Error! A type identifier is expected. )]:\"dd.MM.yyyy\">>"}, + {"<<]>>", "<<] Error! Character ']' is unexpected. >>"}, + {"<<[>>", "<<[>> Error! An expression is expected."}, + {"<<>>", "<<>> Error! Tag end is unexpected."}, + }; + } + + @Test + public void setBackgroundColorDynamically() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Background color.docx"); + + ArrayList colors = new ArrayList(); + { + colors.add(new ColorItemTestBuilder().withColor("Black", Color.BLACK).build()); + colors.add(new ColorItemTestBuilder().withColor("Red", new Color((255), (0), (0))).build()); + colors.add(new ColorItemTestBuilder().withColor("Empty", msColor.Empty).build()); + } + + buildReport(doc, colors, "Colors"); + + doc.save(getArtifactsDir() + "ReportingEngine.SetBackgroundColorDynamically.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.SetBackgroundColorDynamically.docx", + getGoldsDir() + "ReportingEngine.SetBackgroundColorDynamically Gold.docx")); + } + + @Test + public void setTextColorDynamically() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Text color.docx"); + + ArrayList colors = new ArrayList(); + { + colors.add(new ColorItemTestBuilder().withColor("Black", Color.BLUE).build()); + colors.add(new ColorItemTestBuilder().withColor("Red", new Color((255), (0), (0))).build()); + colors.add(new ColorItemTestBuilder().withColor("Empty", msColor.Empty).build()); + } + + buildReport(doc, colors, "Colors"); + + doc.save(getArtifactsDir() + "ReportingEngine.SetTextColorDynamically.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.SetTextColorDynamically.docx", + getGoldsDir() + "ReportingEngine.SetTextColorDynamically Gold.docx")); + } + + @Test + public void doNotRemoveEmptyParagraphs() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Remove empty paragraphs.docx"); + + buildReport(doc, Common.getManagers(), "Managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.DoNotRemoveEmptyParagraphs.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.DoNotRemoveEmptyParagraphs.docx", + getGoldsDir() + "ReportingEngine.DoNotRemoveEmptyParagraphs Gold.docx")); + } + + @Test + public void removeEmptyParagraphs() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Remove empty paragraphs.docx"); + + buildReport(doc, Common.getManagers(), "Managers", ReportBuildOptions.REMOVE_EMPTY_PARAGRAPHS); + + doc.save(getArtifactsDir() + "ReportingEngine.RemoveEmptyParagraphs.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.RemoveEmptyParagraphs.docx", + getGoldsDir() + "ReportingEngine.RemoveEmptyParagraphs Gold.docx")); + } + + @Test (dataProvider = "mergingTableCellsDynamicallyDataProvider") + public void mergingTableCellsDynamically(String value1, String value2, String resultDocumentName) throws Exception + { + String artifactPath = getArtifactsDir() + resultDocumentName + + FileFormatUtil.saveFormatToExtension(SaveFormat.DOCX); + String goldPath = getGoldsDir() + resultDocumentName + " Gold" + + FileFormatUtil.saveFormatToExtension(SaveFormat.DOCX); + + Document doc = new Document(getMyDir() + "Reporting engine template - Merging table cells dynamically.docx"); + + ArrayList clients = new ArrayList(); + { + clients.add(new ClientTestClass()); + { + ((ClientTestClass)clients.get(0)).setName("John Monrou"); + ((ClientTestClass)clients.get(0)).setCountry("France"); + ((ClientTestClass)clients.get(0)).setLocalAddress("27 RUE PASTEUR"); + } + clients.add(new ClientTestClass()); + { + ((ClientTestClass)clients.get(1)).setName("James White"); + ((ClientTestClass)clients.get(1)).setCountry("New Zealand"); + ((ClientTestClass)clients.get(1)).setLocalAddress("14 Tottenham Court Road"); + } + clients.add(new ClientTestClass()); + { + ((ClientTestClass)clients.get(2)).setName("Kate Otts"); + ((ClientTestClass)clients.get(2)).setCountry("New Zealand"); + ((ClientTestClass)clients.get(2)).setLocalAddress("Wellington 6004"); + } + } + + buildReport(doc, new Object[] { value1, value2, clients }, new String[] { "value1", "value2", "clients" }); + doc.save(artifactPath); + + Assert.assertTrue(DocumentHelper.compareDocs(artifactPath, goldPath)); + } + + //JAVA-added data provider for test method + @DataProvider(name = "mergingTableCellsDynamicallyDataProvider") + public static Object[][] mergingTableCellsDynamicallyDataProvider() throws Exception + { + return new Object[][] + { + {"Hello", "Hello", "ReportingEngine.MergingTableCellsDynamically.Merged"}, + {"Hello", "Name", "ReportingEngine.MergingTableCellsDynamically.NotMerged"}, + }; + } + + @Test + public void xmlDataStringWithoutSchema() throws Exception + { + //ExStart + //ExFor:XmlDataSource + //ExFor:XmlDataSource.#ctor(String) + //ExSummary:Show how to use XML as a data source (string). + Document doc = new Document(getMyDir() + "Reporting engine template - XML data destination.docx"); + + XmlDataSource dataSource = new XmlDataSource(getMyDir() + "List of people.xml"); + buildReport(doc, dataSource, "persons"); + + doc.save(getArtifactsDir() + "ReportingEngine.XmlDataString.docx"); + //ExEnd + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.XmlDataString.docx", + getGoldsDir() + "ReportingEngine.DataSource Gold.docx")); + } + + @Test + public void xmlDataStreamWithoutSchema() throws Exception + { + //ExStart + //ExFor:XmlDataSource + //ExFor:XmlDataSource.#ctor(Stream) + //ExSummary:Show how to use XML as a data source (stream). + Document doc = new Document(getMyDir() + "Reporting engine template - XML data destination.docx"); + + FileStream stream = new FileInputStream(getMyDir() + "List of people.xml"); + try /*JAVA: was using*/ + { + XmlDataSource dataSource = new XmlDataSource(stream); + buildReport(doc, dataSource, "persons"); + } + finally { if (stream != null) stream.close(); } + + doc.save(getArtifactsDir() + "ReportingEngine.XmlDataStream.docx"); + //ExEnd + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.XmlDataStream.docx", + getGoldsDir() + "ReportingEngine.DataSource Gold.docx")); + } + + @Test + public void xmlDataWithNestedElements() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Data destination with nested elements.docx"); + + XmlDataSource dataSource = new XmlDataSource(getMyDir() + "Nested elements.xml"); + buildReport(doc, dataSource, "managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.XmlDataWithNestedElements.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.XmlDataWithNestedElements.docx", + getGoldsDir() + "ReportingEngine.DataSourceWithNestedElements Gold.docx")); + } + + @Test + public void jsonDataString() throws Exception + { + //ExStart + //ExFor:JsonDataLoadOptions + //ExFor:JsonDataLoadOptions.#ctor + //ExFor:JsonDataLoadOptions.ExactDateTimeParseFormats + //ExFor:JsonDataLoadOptions.AlwaysGenerateRootObject + //ExFor:JsonDataLoadOptions.PreserveSpaces + //ExFor:JsonDataLoadOptions.SimpleValueParseMode + //ExFor:JsonDataSource + //ExFor:JsonDataSource.#ctor(String,JsonDataLoadOptions) + //ExFor:JsonSimpleValueParseMode + //ExSummary:Shows how to use JSON as a data source (string). + Document doc = new Document(getMyDir() + "Reporting engine template - JSON data destination.docx"); + + JsonDataLoadOptions options = new JsonDataLoadOptions(); + { + options.setExactDateTimeParseFormats(new ArrayList()); {options.getExactDateTimeParseFormats().add("MM/dd/yyyy"); options.getExactDateTimeParseFormats().add("MM.d.yy"); options.getExactDateTimeParseFormats().add("MM d yy");} + options.setAlwaysGenerateRootObject(true); + options.setPreserveSpaces(true); + options.setSimpleValueParseMode(JsonSimpleValueParseMode.LOOSE); + } + + JsonDataSource dataSource = new JsonDataSource(getMyDir() + "List of people.json", options); + buildReport(doc, dataSource, "persons"); + + doc.save(getArtifactsDir() + "ReportingEngine.JsonDataString.docx"); + //ExEnd + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.JsonDataString.docx", + getGoldsDir() + "ReportingEngine.JsonDataString Gold.docx")); + } + + @Test + public void jsonDataStringException() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - JSON data destination.docx"); + + JsonDataLoadOptions options = new JsonDataLoadOptions(); + options.setSimpleValueParseMode(JsonSimpleValueParseMode.STRICT); + + JsonDataSource dataSource = new JsonDataSource(getMyDir() + "List of people.json", options); + Assert.Throws(() => buildReport(doc, dataSource, "persons")); + } + + @Test + public void jsonDataStream() throws Exception + { + //ExStart + //ExFor:JsonDataSource.#ctor(Stream,JsonDataLoadOptions) + //ExSummary:Shows how to use JSON as a data source (stream). + Document doc = new Document(getMyDir() + "Reporting engine template - JSON data destination.docx"); + + JsonDataLoadOptions options = new JsonDataLoadOptions(); + { + options.setExactDateTimeParseFormats(new ArrayList()); {options.getExactDateTimeParseFormats().add("MM/dd/yyyy"); options.getExactDateTimeParseFormats().add("MM.d.yy"); options.getExactDateTimeParseFormats().add("MM d yy");} + } + + FileStream stream = new FileInputStream(getMyDir() + "List of people.json"); + try /*JAVA: was using*/ + { + JsonDataSource dataSource = new JsonDataSource(stream, options); + buildReport(doc, dataSource, "persons"); + } + finally { if (stream != null) stream.close(); } + + doc.save(getArtifactsDir() + "ReportingEngine.JsonDataStream.docx"); + //ExEnd + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.JsonDataStream.docx", + getGoldsDir() + "ReportingEngine.JsonDataString Gold.docx")); + } + + @Test + public void jsonDataWithNestedElements() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Data destination with nested elements.docx"); + + JsonDataSource dataSource = new JsonDataSource(getMyDir() + "Nested elements.json"); + buildReport(doc, dataSource, "managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.JsonDataWithNestedElements.docx"); + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.JsonDataWithNestedElements.docx", + getGoldsDir() + "ReportingEngine.DataSourceWithNestedElements Gold.docx")); + } + + @Test + public void jsonDataPreserveSpaces() throws Exception + { + final String TEMPLATE = "LINE BEFORE\r<<[LineWhitespace]>>\r<<[BlockWhitespace]>>LINE AFTER"; + final String EXPECTED_RESULT = "LINE BEFORE\r \r\r\r\r\rLINE AFTER"; + final String JSON = + "{" + + " \"LineWhitespace\" : \" \"," + + " \"BlockWhitespace\" : \"\r\n\r\n\r\n\r\n\"" + + "}"; + + MemoryStream stream = new MemoryStream(Encoding.getUTF8().getBytes(JSON)); + try /*JAVA: was using*/ + { + JsonDataLoadOptions options = new JsonDataLoadOptions(); + options.setPreserveSpaces(true); + options.setSimpleValueParseMode(JsonSimpleValueParseMode.STRICT); + + JsonDataSource dataSource = new JsonDataSource(stream, options); + + DocumentBuilder builder = new DocumentBuilder(); + builder.write(TEMPLATE); + + buildReport(builder.getDocument(), dataSource, "ds"); + + Assert.assertEquals(EXPECTED_RESULT + ControlChar.SECTION_BREAK, builder.getDocument().getText()); + } + finally { if (stream != null) stream.close(); } + } + + @Test + public void csvDataString() throws Exception + { + //ExStart + //ExFor:CsvDataLoadOptions + //ExFor:CsvDataLoadOptions.#ctor + //ExFor:CsvDataLoadOptions.#ctor(Boolean) + //ExFor:CsvDataLoadOptions.Delimiter + //ExFor:CsvDataLoadOptions.CommentChar + //ExFor:CsvDataLoadOptions.HasHeaders + //ExFor:CsvDataLoadOptions.QuoteChar + //ExFor:CsvDataSource + //ExFor:CsvDataSource.#ctor(String,CsvDataLoadOptions) + //ExSummary:Shows how to use CSV as a data source (string). + Document doc = new Document(getMyDir() + "Reporting engine template - CSV data destination.docx"); + + CsvDataLoadOptions loadOptions = new CsvDataLoadOptions(true); + loadOptions.setDelimiter(';'); + loadOptions.setCommentChar('$'); + loadOptions.hasHeaders(true); + loadOptions.setQuoteChar('"'); + + CsvDataSource dataSource = new CsvDataSource(getMyDir() + "List of people.csv", loadOptions); + buildReport(doc, dataSource, "persons"); + + doc.save(getArtifactsDir() + "ReportingEngine.CsvDataString.docx"); + //ExEnd + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.CsvDataString.docx", + getGoldsDir() + "ReportingEngine.CsvData Gold.docx")); + } + + @Test + public void csvDataStream() throws Exception + { + //ExStart + //ExFor:CsvDataSource.#ctor(Stream,CsvDataLoadOptions) + //ExSummary:Shows how to use CSV as a data source (stream). + Document doc = new Document(getMyDir() + "Reporting engine template - CSV data destination.docx"); + + CsvDataLoadOptions loadOptions = new CsvDataLoadOptions(true); + loadOptions.setDelimiter(';'); + loadOptions.setCommentChar('$'); + + FileStream stream = new FileInputStream(getMyDir() + "List of people.csv"); + try /*JAVA: was using*/ + { + CsvDataSource dataSource = new CsvDataSource(stream, loadOptions); + buildReport(doc, dataSource, "persons"); + } + finally { if (stream != null) stream.close(); } + + doc.save(getArtifactsDir() + "ReportingEngine.CsvDataStream.docx"); + //ExEnd + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.CsvDataStream.docx", + getGoldsDir() + "ReportingEngine.CsvData Gold.docx")); + } + + @Test (dataProvider = "insertComboboxDropdownListItemsDynamicallyDataProvider") + public void insertComboboxDropdownListItemsDynamically(/*SdtType*/int sdtType) throws Exception + { + final String TEMPLATE = + "<><><><><>"; + + SdtListItem[] staticItems = + { + new SdtListItem("1", "one"), + new SdtListItem("2", "two") + }; + + Document doc = new Document(); + + StructuredDocumentTag sdt = new StructuredDocumentTag(doc, sdtType, MarkupLevel.BLOCK); { sdt.setTitle(TEMPLATE); } + + for (SdtListItem item : staticItems) + { + sdt.getListItems().add(item); + } + + doc.getFirstSection().getBody().appendChild(sdt); + + buildReport(doc, new Object(), ""); + + doc.save(getArtifactsDir() + $"ReportingEngine.InsertComboboxDropdownListItemsDynamically_{sdtType}.docx"); + + doc = new Document(getArtifactsDir() + + $"ReportingEngine.InsertComboboxDropdownListItemsDynamically_{sdtType}.docx"); + + sdt = (StructuredDocumentTag) doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + + SdtListItem[] expectedItems = + { + new SdtListItem("1", "one"), + new SdtListItem("2", "two"), + new SdtListItem("3", "three"), + new SdtListItem("5", "five") + }; + + Assert.assertEquals(expectedItems.length, sdt.getListItems().getCount()); + + for (int i = 0; i < expectedItems.length; i++) + { + Assert.assertEquals(expectedItems[i].getValue(), sdt.getListItems().get(i).getValue()); + Assert.assertEquals(expectedItems[i].getDisplayText(), sdt.getListItems().get(i).getDisplayText()); + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "insertComboboxDropdownListItemsDynamicallyDataProvider") + public static Object[][] insertComboboxDropdownListItemsDynamicallyDataProvider() throws Exception + { + return new Object[][] + { + {SdtType.COMBO_BOX}, + {SdtType.DROP_DOWN_LIST}, + }; + } + + @Test + public void updateFieldsSyntaxAware() throws Exception + { + Document doc = new Document(getMyDir() + "Reporting engine template - Fields.docx"); + + // Note that enabling of the option makes the engine to update fields while building a report, + // so there is no need to update fields separately after that. + buildReport(doc, new String[] { "First topic", "Second topic", "Third topic" }, "topics", + ReportBuildOptions.UPDATE_FIELDS_SYNTAX_AWARE); + + doc.save(getArtifactsDir() + "ReportingEngine.UpdateFieldsSyntaxAware.docx"); + } + + @Test + public void dollarTextFormat() throws Exception + { + //ExStart:DollarTextFormat + //GistId:e386727403c2341ce4018bca370a5b41 + //ExFor:ReportingEngine.BuildReport(Document, Object, String) + //ExSummary:Shows how to display values as dollar text. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("<<[ds.Value1]:dollarText>>\r<<[ds.Value2]:dollarText>>"); + + NumericTestClass testData = new NumericTestBuilder().withValues(1234, 5621718.589).build(); + + ReportingEngine report = new ReportingEngine(); + report.getKnownTypes().add(NumericTestClass.class); + report.buildReport(doc, testData, "ds"); + + doc.save(getArtifactsDir() + "ReportingEngine.DollarTextFormat.docx"); + //ExEnd:DollarTextFormat + + Assert.assertEquals("one thousand two hundred thirty-four and 00/100\rfive million six hundred twenty-one thousand seven hundred eighteen and 59/100\r\f", doc.getText()); + } + + @Test (enabled = false, description = "To avoid exception with 'SetRestrictedTypes' after execution other tests.") + public void restrictedTypes() throws Exception + { + //ExStart:RestrictedTypes + //GistId:eeeec1fbf118e95e7df3f346c91ed726 + //ExFor:ReportingEngine.SetRestrictedTypes(Type[]) + //ExSummary:Shows how to deny access to members of types considered insecure. + Document doc = + DocumentHelper.createSimpleDocument( + "<><<[typeVar]>>"); + + // Note, that you can't set restricted types during or after building a report. + ReportingEngine.setRestrictedTypes(Class.class); + // We set "AllowMissingMembers" option to avoid exceptions during building a report. + ReportingEngine engine = new ReportingEngine(); { engine.setOptions(ReportBuildOptions.ALLOW_MISSING_MEMBERS); } + engine.buildReport(doc, new Object()); + + // We get an empty string because we can't access the GetType() method. + Assert.assertEquals("", doc.getText().trim()); + //ExEnd:RestrictedTypes + } + + @Test + public void word2016Charts() throws Exception + { + //ExStart:Word2016Charts + //GistId:a775441ecb396eea917a2717cb9e8f8f + //ExFor:ReportingEngine.BuildReport(Document, Object[], String[]) + //ExSummary:Shows how to work with charts from word 2016. + Document doc = new Document(getMyDir() + "Reporting engine template - Word 2016 Charts.docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, new Object[] { Common.getShares(), Common.getShareQuotes() }, + new String[] { "shares", "quotes" }); + + doc.save(getArtifactsDir() + "ReportingEngine.Word2016Charts.docx"); + //ExEnd:Word2016Charts + } + + @Test + public void removeParagraphsSelectively() throws Exception + { + //ExStart:RemoveParagraphsSelectively + //GistId:65919861586e42e24f61a3ccb65f8f4e + //ExFor:ReportingEngine.BuildReport(Document, Object, String) + //ExSummary:Shows how to remove paragraphs selectively. + // Template contains tags with an exclamation mark. For such tags, empty paragraphs will be removed. + Document doc = new Document(getMyDir() + "Reporting engine template - Selective remove paragraphs.docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, false, "value"); + + doc.save(getArtifactsDir() + "ReportingEngine.SelectiveDeletionOfParagraphs.docx"); + //ExEnd:RemoveParagraphsSelectively + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "ReportingEngine.SelectiveDeletionOfParagraphs.docx", getGoldsDir() + "ReportingEngine.SelectiveDeletionOfParagraphs Gold.docx")); + } + + private static void buildReport(Document document, Object dataSource, /*ReportBuildOptions*/int reportBuildOptions) throws Exception + { + ReportingEngine engine = new ReportingEngine(); { engine.setOptions(reportBuildOptions); } + engine.buildReport(document, dataSource); + } + + private static void buildReport(Document document, Object dataSource, String dataSourceName, + /*ReportBuildOptions*/int reportBuildOptions) throws Exception + { + ReportingEngine engine = new ReportingEngine(); { engine.setOptions(reportBuildOptions); } + engine.buildReport(document, dataSource, dataSourceName); + } + + private static void buildReport(Document document, Object[] dataSource, String[] dataSourceName) throws Exception + { + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(document, dataSource, dataSourceName); + } + + private static void buildReport(Document document, Object[] dataSource, String[] dataSourceName, + /*ReportBuildOptions*/int reportBuildOptions) throws Exception + { + ReportingEngine engine = new ReportingEngine(); { engine.setOptions(reportBuildOptions); } + engine.buildReport(document, dataSource, dataSourceName); + } + + private static void buildReport(Document document, Object dataSource, String dataSourceName, Class[] knownTypes) throws Exception + { + ReportingEngine engine = new ReportingEngine(); + + for (Class knownType : knownTypes) + { + engine.getKnownTypes().add(knownType); + } + + engine.buildReport(document, dataSource, dataSourceName); + } + + private static void buildReport(Document document, Object dataSource) throws Exception + { + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(document, dataSource); + } + + private static void buildReport(Document document, Object dataSource, String dataSourceName) throws Exception + { + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(document, dataSource, dataSourceName); + } + + private static void buildReport(Document document, Object dataSource, Class[] knownTypes) throws Exception + { + ReportingEngine engine = new ReportingEngine(); + + for (Class knownType : knownTypes) + { + engine.getKnownTypes().add(knownType); + } + + engine.buildReport(document, dataSource); + } +} + + diff --git a/Examples/ApiExamples/JavaPorting/ExRevision.java b/Examples/ApiExamples/JavaPorting/ExRevision.java new file mode 100644 index 00000000..7c6657d3 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExRevision.java @@ -0,0 +1,829 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import java.util.Date; +import com.aspose.ms.System.DateTime; +import com.aspose.words.Revision; +import com.aspose.words.RevisionType; +import com.aspose.words.Node; +import com.aspose.words.RevisionCollection; +import com.aspose.ms.System.msConsole; +import java.util.Iterator; +import com.aspose.words.RevisionGroup; +import com.aspose.words.ShowInBalloons; +import com.aspose.words.RevisionOptions; +import com.aspose.words.RevisionColor; +import com.aspose.words.RevisionTextEffect; +import com.aspose.words.IRevisionCriteria; +import com.aspose.ms.System.msString; +import com.aspose.words.ParagraphCollection; +import com.aspose.words.RevisionsView; +import com.aspose.words.FootnoteType; +import com.aspose.words.Shape; +import com.aspose.words.ShapeType; +import com.aspose.words.Comment; +import com.aspose.words.HeaderFooterType; +import com.aspose.words.Paragraph; +import com.aspose.words.StyleIdentifier; +import com.aspose.words.Footnote; +import com.aspose.words.NodeType; +import com.aspose.words.Table; +import com.aspose.words.FieldDate; +import com.aspose.words.CompareOptions; +import com.aspose.words.ComparisonTargetType; +import com.aspose.words.HorizontalAlignment; +import com.aspose.words.Granularity; +import com.aspose.words.RevisionGroupCollection; +import org.testng.annotations.DataProvider; + + +@Test +class ExRevision !Test class should be public in Java to run, please fix .Net source! extends ApiExampleBase +{ + @Test + public void revisions() throws Exception + { + //ExStart + //ExFor:Revision + //ExFor:Revision.Accept + //ExFor:Revision.Author + //ExFor:Revision.DateTime + //ExFor:Revision.Group + //ExFor:Revision.Reject + //ExFor:Revision.RevisionType + //ExFor:RevisionCollection + //ExFor:RevisionCollection.Item(Int32) + //ExFor:RevisionCollection.Count + //ExFor:RevisionType + //ExFor:Document.HasRevisions + //ExFor:Document.TrackRevisions + //ExFor:Document.Revisions + //ExSummary:Shows how to work with revisions in a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Normal editing of the document does not count as a revision. + builder.write("This does not count as a revision. "); + + Assert.assertFalse(doc.hasRevisions()); + + // To register our edits as revisions, we need to declare an author, and then start tracking them. + doc.startTrackRevisionsInternal("John Doe", new Date); + + builder.write("This is revision #1. "); + + Assert.assertTrue(doc.hasRevisions()); + Assert.assertEquals(1, doc.getRevisions().getCount()); + + // This flag corresponds to the "Review" -> "Tracking" -> "Track Changes" option in Microsoft Word. + // The "StartTrackRevisions" method does not affect its value, + // and the document is tracking revisions programmatically despite it having a value of "false". + // If we open this document using Microsoft Word, it will not be tracking revisions. + Assert.assertFalse(doc.getTrackRevisions()); + + // We have added text using the document builder, so the first revision is an insertion-type revision. + Revision revision = doc.getRevisions().get(0); + Assert.assertEquals("John Doe", revision.getAuthor()); + Assert.assertEquals("This is revision #1. ", revision.getParentNode().getText()); + Assert.assertEquals(RevisionType.INSERTION, revision.getRevisionType()); + Assert.assertEquals(revision.getDateTimeInternal().getDate(), new Date.getDate()); + Assert.assertEquals(doc.getRevisions().getGroups().get(0), revision.getGroup()); + + // Remove a run to create a deletion-type revision. + doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0).remove(); + + // Adding a new revision places it at the beginning of the revision collection. + Assert.assertEquals(RevisionType.DELETION, doc.getRevisions().get(0).getRevisionType()); + Assert.assertEquals(2, doc.getRevisions().getCount()); + + // Insert revisions show up in the document body even before we accept/reject the revision. + // Rejecting the revision will remove its nodes from the body. Conversely, nodes that make up delete revisions + // also linger in the document until we accept the revision. + Assert.assertEquals("This does not count as a revision. This is revision #1.", doc.getText().trim()); + + // Accepting the delete revision will remove its parent node from the paragraph text + // and then remove the collection's revision itself. + doc.getRevisions().get(0).accept(); + + Assert.assertEquals(1, doc.getRevisions().getCount()); + Assert.assertEquals("This is revision #1.", doc.getText().trim()); + + builder.writeln(""); + builder.write("This is revision #2."); + + // Now move the node to create a moving revision type. + Node node = doc.getFirstSection().getBody().getParagraphs().get(1); + Node endNode = doc.getFirstSection().getBody().getParagraphs().get(1).getNextSibling(); + Node referenceNode = doc.getFirstSection().getBody().getParagraphs().get(0); + + while (node != endNode) + { + Node nextNode = node.getNextSibling(); + doc.getFirstSection().getBody().insertBefore(node, referenceNode); + node = nextNode; + } + + Assert.assertEquals(RevisionType.MOVING, doc.getRevisions().get(0).getRevisionType()); + Assert.assertEquals(8, doc.getRevisions().getCount()); + Assert.assertEquals("This is revision #2.\rThis is revision #1. \rThis is revision #2.", doc.getText().trim()); + + // The moving revision is now at index 1. Reject the revision to discard its contents. + doc.getRevisions().get(1).reject(); + + Assert.assertEquals(6, doc.getRevisions().getCount()); + Assert.assertEquals("This is revision #1. \rThis is revision #2.", doc.getText().trim()); + //ExEnd + } + + @Test + public void revisionCollection() throws Exception + { + //ExStart + //ExFor:Revision.ParentStyle + //ExFor:RevisionCollection.GetEnumerator + //ExFor:RevisionCollection.Groups + //ExFor:RevisionCollection.RejectAll + //ExFor:RevisionGroupCollection.GetEnumerator + //ExSummary:Shows how to work with a document's collection of revisions. + Document doc = new Document(getMyDir() + "Revisions.docx"); + RevisionCollection revisions = doc.getRevisions(); + + // This collection itself has a collection of revision groups. + // Each group is a sequence of adjacent revisions. + Assert.assertEquals(7, revisions.getGroups().getCount()); //ExSkip + System.out.println("{revisions.Groups.Count} revision groups:"); + + // Iterate over the collection of groups and print the text that the revision concerns. + Iterator e = revisions.getGroups().iterator(); + try /*JAVA: was using*/ + { + while (e.hasNext()) + { + System.out.println("\tGroup type \"{e.Current.RevisionType}\", " + + $"author: {e.Current.Author}, contents: [{e.Current.Text.Trim()}]"); + } + } + finally { if (e != null) e.close(); } + + // Each Run that a revision affects gets a corresponding Revision object. + // The revisions' collection is considerably larger than the condensed form we printed above, + // depending on how many Runs we have segmented the document into during Microsoft Word editing. + Assert.assertEquals(11, revisions.getCount()); //ExSkip + System.out.println("\n{revisions.Count} revisions:"); + + Iterator e1 = revisions.iterator(); + try /*JAVA: was using*/ + { + while (e1.hasNext()) + { + // A StyleDefinitionChange strictly affects styles and not document nodes. This means the "ParentStyle" + // property will always be in use, while the ParentNode will always be null. + // Since all other changes affect nodes, ParentNode will conversely be in use, and ParentStyle will be null. + if (e1.next().getRevisionType() == RevisionType.STYLE_DEFINITION_CHANGE) + { + System.out.println("\tRevision type \"{e.Current.RevisionType}\", " + + $"author: {e.Current.Author}, style: [{e.Current.ParentStyle.Name}]"); + } + else + { + System.out.println("\tRevision type \"{e.Current.RevisionType}\", " + + $"author: {e.Current.Author}, contents: [{e.Current.ParentNode.GetText().Trim()}]"); + } + } + } + finally { if (e1 != null) e1.close(); } + + // Reject all revisions via the collection, reverting the document to its original form. + revisions.rejectAll(); + + Assert.assertEquals(0, revisions.getCount()); + //ExEnd + } + + @Test + public void getInfoAboutRevisionsInRevisionGroups() throws Exception + { + //ExStart + //ExFor:RevisionGroup + //ExFor:RevisionGroup.Author + //ExFor:RevisionGroup.RevisionType + //ExFor:RevisionGroup.Text + //ExFor:RevisionGroupCollection + //ExFor:RevisionGroupCollection.Count + //ExSummary:Shows how to print info about a group of revisions in a document. + Document doc = new Document(getMyDir() + "Revisions.docx"); + + Assert.assertEquals(7, doc.getRevisions().getGroups().getCount()); + + for (RevisionGroup group : doc.getRevisions().getGroups()) + { + System.out.println("Revision author: {group.Author}; Revision type: {group.RevisionType} \n\tRevision text: {group.Text}"); + } + //ExEnd + } + + @Test + public void getSpecificRevisionGroup() throws Exception + { + //ExStart + //ExFor:RevisionGroupCollection + //ExFor:RevisionGroupCollection.Item(Int32) + //ExSummary:Shows how to get a group of revisions in a document. + Document doc = new Document(getMyDir() + "Revisions.docx"); + + RevisionGroup revisionGroup = doc.getRevisions().getGroups().get(0); + //ExEnd + + Assert.assertEquals(RevisionType.DELETION, revisionGroup.getRevisionType()); + Assert.assertEquals("Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. ", revisionGroup.getText()); + } + + @Test + public void showRevisionBalloons() throws Exception + { + //ExStart + //ExFor:RevisionOptions.ShowInBalloons + //ExSummary:Shows how to display revisions in balloons. + Document doc = new Document(getMyDir() + "Revisions.docx"); + + // By default, text that is a revision has a different color to differentiate it from the other non-revision text. + // Set a revision option to show more details about each revision in a balloon on the page's right margin. + doc.getLayoutOptions().getRevisionOptions().setShowInBalloons(ShowInBalloons.FORMAT_AND_DELETE); + doc.save(getArtifactsDir() + "Revision.ShowRevisionBalloons.pdf"); + //ExEnd + } + + @Test + public void revisionOptions() throws Exception + { + //ExStart + //ExFor:ShowInBalloons + //ExFor:RevisionOptions.ShowInBalloons + //ExFor:RevisionOptions.CommentColor + //ExFor:RevisionOptions.DeletedTextColor + //ExFor:RevisionOptions.DeletedTextEffect + //ExFor:RevisionOptions.InsertedTextEffect + //ExFor:RevisionOptions.MovedFromTextColor + //ExFor:RevisionOptions.MovedFromTextEffect + //ExFor:RevisionOptions.MovedToTextColor + //ExFor:RevisionOptions.MovedToTextEffect + //ExFor:RevisionOptions.RevisedPropertiesColor + //ExFor:RevisionOptions.RevisedPropertiesEffect + //ExFor:RevisionOptions.RevisionBarsColor + //ExFor:RevisionOptions.RevisionBarsWidth + //ExFor:RevisionOptions.ShowOriginalRevision + //ExFor:RevisionOptions.ShowRevisionMarks + //ExFor:RevisionTextEffect + //ExSummary:Shows how to modify the appearance of revisions. + Document doc = new Document(getMyDir() + "Revisions.docx"); + + // Get the RevisionOptions object that controls the appearance of revisions. + RevisionOptions revisionOptions = doc.getLayoutOptions().getRevisionOptions(); + + // Render insertion revisions in green and italic. + revisionOptions.setInsertedTextColor(RevisionColor.GREEN); + revisionOptions.setInsertedTextEffect(RevisionTextEffect.ITALIC); + + // Render deletion revisions in red and bold. + revisionOptions.setDeletedTextColor(RevisionColor.RED); + revisionOptions.setDeletedTextEffect(RevisionTextEffect.BOLD); + + // The same text will appear twice in a movement revision: + // once at the departure point and once at the arrival destination. + // Render the text at the moved-from revision yellow with a double strike through + // and double-underlined blue at the moved-to revision. + revisionOptions.setMovedFromTextColor(RevisionColor.YELLOW); + revisionOptions.setMovedFromTextEffect(RevisionTextEffect.DOUBLE_STRIKE_THROUGH); + revisionOptions.setMovedToTextColor(RevisionColor.CLASSIC_BLUE); + revisionOptions.setMovedToTextEffect(RevisionTextEffect.DOUBLE_UNDERLINE); + + // Render format revisions in dark red and bold. + revisionOptions.setRevisedPropertiesColor(RevisionColor.DARK_RED); + revisionOptions.setRevisedPropertiesEffect(RevisionTextEffect.BOLD); + + // Place a thick dark blue bar on the left side of the page next to lines affected by revisions. + revisionOptions.setRevisionBarsColor(RevisionColor.DARK_BLUE); + revisionOptions.setRevisionBarsWidth(15.0f); + + // Show revision marks and original text. + revisionOptions.setShowOriginalRevision(true); + revisionOptions.setShowRevisionMarks(true); + + // Get movement, deletion, formatting revisions, and comments to show up in green balloons + // on the right side of the page. + revisionOptions.setShowInBalloons(ShowInBalloons.FORMAT); + revisionOptions.setCommentColor(RevisionColor.BRIGHT_GREEN); + + // These features are only applicable to formats such as .pdf or .jpg. + doc.save(getArtifactsDir() + "Revision.RevisionOptions.pdf"); + //ExEnd + } + + //ExStart:RevisionSpecifiedCriteria + //GistId:470c0da51e4317baae82ad9495747fed + //ExFor:RevisionCollection.Accept(IRevisionCriteria) + //ExFor:RevisionCollection.Reject(IRevisionCriteria) + //ExFor:IRevisionCriteria + //ExFor:IRevisionCriteria.IsMatch(Revision) + //ExSummary:Shows how to accept or reject revision based on criteria. + @Test //ExSkip + public void revisionSpecifiedCriteria() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.write("This does not count as a revision. "); + + // To register our edits as revisions, we need to declare an author, and then start tracking them. + doc.startTrackRevisionsInternal("John Doe", new Date); + builder.write("This is insertion revision #1. "); + doc.stopTrackRevisions(); + + doc.startTrackRevisionsInternal("Jane Doe", new Date); + builder.write("This is insertion revision #2. "); + // Remove a run "This does not count as a revision.". + doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0).remove(); + doc.stopTrackRevisions(); + + Assert.assertEquals(3, doc.getRevisions().getCount()); + // We have two revisions from different authors, so we need to accept only one. + doc.getRevisions().accept(new RevisionCriteria("John Doe", RevisionType.INSERTION)); + Assert.assertEquals(2, doc.getRevisions().getCount()); + // Reject revision with different author name and revision type. + doc.getRevisions().reject(new RevisionCriteria("Jane Doe", RevisionType.DELETION)); + Assert.assertEquals(1, doc.getRevisions().getCount()); + + doc.save(getArtifactsDir() + "Revision.RevisionSpecifiedCriteria.docx"); + } + + /// + /// Control when certain revision should be accepted/rejected. + /// + public static class RevisionCriteria implements IRevisionCriteria + { + private /*final*/ String AuthorName; + private /*final*/ /*RevisionType*/int _RevisionType; + + public RevisionCriteria(String authorName, /*RevisionType*/int revisionType) + { + AuthorName = authorName; + _RevisionType = revisionType; + } + + public boolean isMatch(Revision revision) + { + return msString.equals(revision.getAuthor(), AuthorName) && revision.getRevisionType() == _RevisionType; + } + } + //ExEnd:RevisionSpecifiedCriteria + + @Test + public void trackRevisions() throws Exception + { + //ExStart + //ExFor:Document.StartTrackRevisions(String) + //ExFor:Document.StartTrackRevisions(String, DateTime) + //ExFor:Document.StopTrackRevisions + //ExSummary:Shows how to track revisions while editing a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Editing a document usually does not count as a revision until we begin tracking them. + builder.write("Hello world! "); + + Assert.assertEquals(0, doc.getRevisions().getCount()); + Assert.assertFalse(doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(0).isInsertRevision()); + + doc.startTrackRevisions("John Doe"); + + builder.write("Hello again! "); + + Assert.assertEquals(1, doc.getRevisions().getCount()); + Assert.assertTrue(doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(1).isInsertRevision()); + Assert.assertEquals("John Doe", doc.getRevisions().get(0).getAuthor()); + Assert.assertTrue((DateTime.subtract(new Date, doc.getRevisions().get(0).getDateTimeInternal())).getMilliseconds() <= 10); + + // Stop tracking revisions to not count any future edits as revisions. + doc.stopTrackRevisions(); + builder.write("Hello again! "); + + Assert.assertEquals(1, doc.getRevisions().getCount()); + Assert.assertFalse(doc.getFirstSection().getBody().getParagraphs().get(0).getRuns().get(2).isInsertRevision()); + + // Creating revisions gives them a date and time of the operation. + // We can disable this by passing DateTime.MinValue when we start tracking revisions. + doc.startTrackRevisionsInternal("John Doe", DateTime.MinValue); + builder.write("Hello again! "); + + Assert.assertEquals(2, doc.getRevisions().getCount()); + Assert.assertEquals("John Doe", doc.getRevisions().get(1).getAuthor()); + Assert.assertEquals(DateTime.MinValue, doc.getRevisions().get(1).getDateTimeInternal()); + + // We can accept/reject these revisions programmatically + // by calling methods such as Document.AcceptAllRevisions, or each revision's Accept method. + // In Microsoft Word, we can process them manually via "Review" -> "Changes". + doc.save(getArtifactsDir() + "Revision.StartTrackRevisions.docx"); + //ExEnd + } + + @Test + public void acceptAllRevisions() throws Exception + { + //ExStart + //ExFor:Document.AcceptAllRevisions + //ExSummary:Shows how to accept all tracking changes in the document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Edit the document while tracking changes to create a few revisions. + doc.startTrackRevisions("John Doe"); + builder.write("Hello world! "); + builder.write("Hello again! "); + builder.write("This is another revision."); + doc.stopTrackRevisions(); + + Assert.assertEquals(3, doc.getRevisions().getCount()); + + // We can iterate through every revision and accept/reject it as a part of our document. + // If we know we wish to accept every revision, we can do it more straightforwardly so by calling this method. + doc.acceptAllRevisions(); + + Assert.assertEquals(0, doc.getRevisions().getCount()); + Assert.assertEquals("Hello world! Hello again! This is another revision.", doc.getText().trim()); + //ExEnd + } + + @Test + public void getRevisedPropertiesOfList() throws Exception + { + //ExStart + //ExFor:RevisionsView + //ExFor:Document.RevisionsView + //ExSummary:Shows how to switch between the revised and the original view of a document. + Document doc = new Document(getMyDir() + "Revisions at list levels.docx"); + doc.updateListLabels(); + + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + Assert.assertEquals("1.", paragraphs.get(0).getListLabel().getLabelString()); + Assert.assertEquals("a.", paragraphs.get(1).getListLabel().getLabelString()); + Assert.assertEquals("", paragraphs.get(2).getListLabel().getLabelString()); + + // View the document object as if all the revisions are accepted. Currently supports list labels. + doc.setRevisionsView(RevisionsView.FINAL); + + Assert.assertEquals("", paragraphs.get(0).getListLabel().getLabelString()); + Assert.assertEquals("1.", paragraphs.get(1).getListLabel().getLabelString()); + Assert.assertEquals("a.", paragraphs.get(2).getListLabel().getLabelString()); + //ExEnd + + doc.setRevisionsView(RevisionsView.ORIGINAL); + doc.acceptAllRevisions(); + + Assert.assertEquals("a.", paragraphs.get(0).getListLabel().getLabelString()); + Assert.assertEquals("", paragraphs.get(1).getListLabel().getLabelString()); + Assert.assertEquals("b.", paragraphs.get(2).getListLabel().getLabelString()); + } + + @Test + public void compare() throws Exception + { + //ExStart + //ExFor:Document.Compare(Document, String, DateTime) + //ExFor:RevisionCollection.AcceptAll + //ExSummary:Shows how to compare documents. + Document docOriginal = new Document(); + DocumentBuilder builder = new DocumentBuilder(docOriginal); + builder.writeln("This is the original document."); + + Document docEdited = new Document(); + builder = new DocumentBuilder(docEdited); + builder.writeln("This is the edited document."); + + // Comparing documents with revisions will throw an exception. + if (docOriginal.getRevisions().getCount() == 0 && docEdited.getRevisions().getCount() == 0) + docOriginal.compareInternal(docEdited, "authorName", new Date); + + // After the comparison, the original document will gain a new revision + // for every element that is different in the edited document. + Assert.assertEquals(2, docOriginal.getRevisions().getCount()); //ExSkip + for (Revision r : docOriginal.getRevisions()) + { + System.out.println("Revision type: {r.RevisionType}, on a node of type \"{r.ParentNode.NodeType}\""); + System.out.println("\tChanged text: \"{r.ParentNode.GetText()}\""); + } + + // Accepting these revisions will transform the original document into the edited document. + docOriginal.getRevisions().acceptAll(); + + Assert.assertEquals(docOriginal.getText(), docEdited.getText()); + //ExEnd + + docOriginal = DocumentHelper.saveOpen(docOriginal); + Assert.assertEquals(0, docOriginal.getRevisions().getCount()); + } + + @Test + public void compareDocumentWithRevisions() throws Exception + { + Document doc1 = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc1); + builder.writeln("Hello world! This text is not a revision."); + + Document docWithRevision = new Document(); + builder = new DocumentBuilder(docWithRevision); + + docWithRevision.startTrackRevisions("John Doe"); + builder.writeln("This is a revision."); + + Assert.Throws(() => docWithRevision.compareInternal(doc1, "John Doe", new Date)); + } + + @Test + public void compareOptions() throws Exception + { + //ExStart + //ExFor:CompareOptions + //ExFor:CompareOptions.CompareMoves + //ExFor:CompareOptions.IgnoreFormatting + //ExFor:CompareOptions.IgnoreCaseChanges + //ExFor:CompareOptions.IgnoreComments + //ExFor:CompareOptions.IgnoreTables + //ExFor:CompareOptions.IgnoreFields + //ExFor:CompareOptions.IgnoreFootnotes + //ExFor:CompareOptions.IgnoreTextboxes + //ExFor:CompareOptions.IgnoreHeadersAndFooters + //ExFor:CompareOptions.Target + //ExFor:ComparisonTargetType + //ExFor:Document.Compare(Document, String, DateTime, CompareOptions) + //ExSummary:Shows how to filter specific types of document elements when making a comparison. + // Create the original document and populate it with various kinds of elements. + Document docOriginal = new Document(); + DocumentBuilder builder = new DocumentBuilder(docOriginal); + + // Paragraph text referenced with an endnote: + builder.writeln("Hello world! This is the first paragraph."); + builder.insertFootnote(FootnoteType.ENDNOTE, "Original endnote text."); + + // Table: + builder.startTable(); + builder.insertCell(); + builder.write("Original cell 1 text"); + builder.insertCell(); + builder.write("Original cell 2 text"); + builder.endTable(); + + // Textbox: + Shape textBox = builder.insertShape(ShapeType.TEXT_BOX, 150.0, 20.0); + builder.moveTo(textBox.getFirstParagraph()); + builder.write("Original textbox contents"); + + // DATE field: + builder.moveTo(docOriginal.getFirstSection().getBody().appendParagraph("")); + builder.insertField(" DATE "); + + // Comment: + Comment newComment = new Comment(docOriginal, "John Doe", "J.D.", new Date); + newComment.setText("Original comment."); + builder.getCurrentParagraph().appendChild(newComment); + + // Header: + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.writeln("Original header contents."); + + // Create a clone of our document and perform a quick edit on each of the cloned document's elements. + Document docEdited = (Document)docOriginal.deepClone(true); + Paragraph firstParagraph = docEdited.getFirstSection().getBody().getFirstParagraph(); + + firstParagraph.getRuns().get(0).setText("hello world! this is the first paragraph, after editing."); + firstParagraph.getParagraphFormat().setStyle(docEdited.getStyles().getByStyleIdentifier(StyleIdentifier.HEADING_1)); + ((Footnote)docEdited.getChild(NodeType.FOOTNOTE, 0, true)).getFirstParagraph().getRuns().get(1).setText("Edited endnote text."); + ((Table)docEdited.getChild(NodeType.TABLE, 0, true)).getFirstRow().getCells().get(1).getFirstParagraph().getRuns().get(0).setText("Edited Cell 2 contents"); + ((Shape)docEdited.getChild(NodeType.SHAPE, 0, true)).getFirstParagraph().getRuns().get(0).setText("Edited textbox contents"); + ((FieldDate)docEdited.getRange().getFields().get(0)).setUseLunarCalendar(true); + ((Comment)docEdited.getChild(NodeType.COMMENT, 0, true)).getFirstParagraph().getRuns().get(0).setText("Edited comment."); + docEdited.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.HEADER_PRIMARY).getFirstParagraph().getRuns().get(0).setText("Edited header contents."); + + // Comparing documents creates a revision for every edit in the edited document. + // A CompareOptions object has a series of flags that can suppress revisions + // on each respective type of element, effectively ignoring their change. + CompareOptions compareOptions = new CompareOptions(); + { + compareOptions.setCompareMoves(false); + compareOptions.setIgnoreFormatting(false); + compareOptions.setIgnoreCaseChanges(false); + compareOptions.setIgnoreComments(false); + compareOptions.setIgnoreTables(false); + compareOptions.setIgnoreFields(false); + compareOptions.setIgnoreFootnotes(false); + compareOptions.setIgnoreTextboxes(false); + compareOptions.setIgnoreHeadersAndFooters(false); + compareOptions.setTarget(ComparisonTargetType.NEW); + } + + docOriginal.compareInternal(docEdited, "John Doe", new Date, compareOptions); + docOriginal.save(getArtifactsDir() + "Revision.CompareOptions.docx"); + //ExEnd + + docOriginal = new Document(getArtifactsDir() + "Revision.CompareOptions.docx"); + + TestUtil.verifyFootnote(FootnoteType.ENDNOTE, true, "", + "OriginalEdited endnote text.", (Footnote)docOriginal.getChild(NodeType.FOOTNOTE, 0, true)); + } + + @Test (dataProvider = "ignoreDmlUniqueIdDataProvider") + public void ignoreDmlUniqueId(boolean isIgnoreDmlUniqueId) throws Exception + { + //ExStart + //ExFor:CompareOptions.AdvancedOptions + //ExFor:AdvancedCompareOptions.IgnoreDmlUniqueId + //ExFor:CompareOptions.IgnoreDmlUniqueId + //ExSummary:Shows how to compare documents ignoring DML unique ID. + Document docA = new Document(getMyDir() + "DML unique ID original.docx"); + Document docB = new Document(getMyDir() + "DML unique ID compare.docx"); + + // By default, Aspose.Words do not ignore DML's unique ID, and the revisions count was 2. + // If we are ignoring DML's unique ID, and revisions count were 0. + CompareOptions compareOptions = new CompareOptions(); + compareOptions.getAdvancedOptions().setIgnoreDmlUniqueId(isIgnoreDmlUniqueId); + + docA.compareInternal(docB, "Aspose.Words", new Date, compareOptions); + + Assert.assertEquals(isIgnoreDmlUniqueId ? 0 : 2, docA.getRevisions().getCount()); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "ignoreDmlUniqueIdDataProvider") + public static Object[][] ignoreDmlUniqueIdDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void layoutOptionsRevisions() throws Exception + { + //ExStart + //ExFor:Document.LayoutOptions + //ExFor:LayoutOptions + //ExFor:LayoutOptions.RevisionOptions + //ExFor:RevisionColor + //ExFor:RevisionOptions + //ExFor:RevisionOptions.InsertedTextColor + //ExFor:RevisionOptions.ShowRevisionBars + //ExFor:RevisionOptions.RevisionBarsPosition + //ExSummary:Shows how to alter the appearance of revisions in a rendered output document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a revision, then change the color of all revisions to green. + builder.writeln("This is not a revision."); + doc.startTrackRevisionsInternal("John Doe", new Date); + Assert.assertEquals(RevisionColor.BY_AUTHOR, doc.getLayoutOptions().getRevisionOptions().getInsertedTextColor()); //ExSkip + Assert.assertTrue(doc.getLayoutOptions().getRevisionOptions().getShowRevisionBars()); //ExSkip + builder.writeln("This is a revision."); + doc.stopTrackRevisions(); + builder.writeln("This is not a revision."); + + // Remove the bar that appears to the left of every revised line. + doc.getLayoutOptions().getRevisionOptions().setInsertedTextColor(RevisionColor.BRIGHT_GREEN); + doc.getLayoutOptions().getRevisionOptions().setShowRevisionBars(false); + doc.getLayoutOptions().getRevisionOptions().setRevisionBarsPosition(HorizontalAlignment.RIGHT); + + doc.save(getArtifactsDir() + "Revision.LayoutOptionsRevisions.pdf"); + //ExEnd + } + + @Test (dataProvider = "granularityCompareOptionDataProvider") + public void granularityCompareOption(/*Granularity*/int granularity) throws Exception + { + //ExStart + //ExFor:CompareOptions.Granularity + //ExFor:Granularity + //ExSummary:Shows to specify a granularity while comparing documents. + Document docA = new Document(); + DocumentBuilder builderA = new DocumentBuilder(docA); + builderA.writeln("Alpha Lorem ipsum dolor sit amet, consectetur adipiscing elit"); + + Document docB = new Document(); + DocumentBuilder builderB = new DocumentBuilder(docB); + builderB.writeln("Lorems ipsum dolor sit amet consectetur - \"adipiscing\" elit"); + + // Specify whether changes are tracking + // by character ('Granularity.CharLevel'), or by word ('Granularity.WordLevel'). + CompareOptions compareOptions = new CompareOptions(); + compareOptions.setGranularity(granularity); + + docA.compareInternal(docB, "author", new Date, compareOptions); + + // The first document's collection of revision groups contains all the differences between documents. + RevisionGroupCollection groups = docA.getRevisions().getGroups(); + Assert.assertEquals(5, groups.getCount()); + //ExEnd + + if (granularity == Granularity.CHAR_LEVEL) + { + Assert.assertEquals(RevisionType.DELETION, groups.get(0).getRevisionType()); + Assert.assertEquals("Alpha ", groups.get(0).getText()); + + Assert.assertEquals(RevisionType.DELETION, groups.get(1).getRevisionType()); + Assert.assertEquals(",", groups.get(1).getText()); + + Assert.assertEquals(RevisionType.INSERTION, groups.get(2).getRevisionType()); + Assert.assertEquals("s", groups.get(2).getText()); + + Assert.assertEquals(RevisionType.INSERTION, groups.get(3).getRevisionType()); + Assert.assertEquals("- \"", groups.get(3).getText()); + + Assert.assertEquals(RevisionType.INSERTION, groups.get(4).getRevisionType()); + Assert.assertEquals("\"", groups.get(4).getText()); + } + else + { + Assert.assertEquals(RevisionType.DELETION, groups.get(0).getRevisionType()); + Assert.assertEquals("Alpha Lorem", groups.get(0).getText()); + + Assert.assertEquals(RevisionType.DELETION, groups.get(1).getRevisionType()); + Assert.assertEquals(",", groups.get(1).getText()); + + Assert.assertEquals(RevisionType.INSERTION, groups.get(2).getRevisionType()); + Assert.assertEquals("Lorems", groups.get(2).getText()); + + Assert.assertEquals(RevisionType.INSERTION, groups.get(3).getRevisionType()); + Assert.assertEquals("- \"", groups.get(3).getText()); + + Assert.assertEquals(RevisionType.INSERTION, groups.get(4).getRevisionType()); + Assert.assertEquals("\"", groups.get(4).getText()); + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "granularityCompareOptionDataProvider") + public static Object[][] granularityCompareOptionDataProvider() throws Exception + { + return new Object[][] + { + {Granularity.CHAR_LEVEL}, + {Granularity.WORD_LEVEL}, + }; + } + + @Test + public void ignoreStoreItemId() throws Exception + { + //ExStart:IgnoreStoreItemId + //GistId:65919861586e42e24f61a3ccb65f8f4e + //ExFor:AdvancedCompareOptions + //ExFor:AdvancedCompareOptions.IgnoreStoreItemId + //ExSummary:Shows how to compare SDT with same content but different store item id. + Document docA = new Document(getMyDir() + "Document with SDT 1.docx"); + Document docB = new Document(getMyDir() + "Document with SDT 2.docx"); + + // Configure options to compare SDT with same content but different store item id. + CompareOptions compareOptions = new CompareOptions(); + compareOptions.getAdvancedOptions().setIgnoreStoreItemId(false); + + docA.compareInternal(docB, "user", new Date, compareOptions); + Assert.assertEquals(8, docA.getRevisions().getCount()); + + compareOptions.getAdvancedOptions().setIgnoreStoreItemId(true); + + docA.getRevisions().rejectAll(); + docA.compareInternal(docB, "user", new Date, compareOptions); + Assert.assertEquals(0, docA.getRevisions().getCount()); + //ExEnd:IgnoreStoreItemId + } + + @Test + public void revisionCellColor() throws Exception + { + //ExStart:RevisionCellColor + //GistId:366eb64fd56dec3c2eaa40410e594182 + //ExFor:RevisionOptions.InsertCellColor + //ExFor:RevisionOptions.DeleteCellColor + //ExSummary:Shows how to work with insert/delete cell revision color. + Document doc = new Document(getMyDir() + "Cell revisions.docx"); + + doc.getLayoutOptions().getRevisionOptions().setInsertCellColor(RevisionColor.LIGHT_BLUE); + doc.getLayoutOptions().getRevisionOptions().setDeleteCellColor(RevisionColor.DARK_RED); + + doc.save(getArtifactsDir() + "Revision.RevisionCellColor.pdf"); + //ExEnd:RevisionCellColor + } +} + diff --git a/Examples/ApiExamples/JavaPorting/ExRtfLoadOptions.java b/Examples/ApiExamples/JavaPorting/ExRtfLoadOptions.java new file mode 100644 index 00000000..2fee3111 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExRtfLoadOptions.java @@ -0,0 +1,59 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.RtfLoadOptions; +import com.aspose.words.Document; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import org.testng.annotations.DataProvider; + + +@Test +public class ExRtfLoadOptions extends ApiExampleBase +{ + @Test (dataProvider = "recognizeUtf8TextDataProvider") + public void recognizeUtf8Text(boolean recognizeUtf8Text) throws Exception + { + //ExStart + //ExFor:RtfLoadOptions + //ExFor:RtfLoadOptions.#ctor + //ExFor:RtfLoadOptions.RecognizeUtf8Text + //ExSummary:Shows how to detect UTF-8 characters while loading an RTF document. + // Create an "RtfLoadOptions" object to modify how we load an RTF document. + RtfLoadOptions loadOptions = new RtfLoadOptions(); + + // Set the "RecognizeUtf8Text" property to "false" to assume that the document uses the ISO 8859-1 charset + // and loads every character in the document. + // Set the "RecognizeUtf8Text" property to "true" to parse any variable-length characters that may occur in the text. + loadOptions.setRecognizeUtf8Text(recognizeUtf8Text); + + Document doc = new Document(getMyDir() + "UTF-8 characters.rtf", loadOptions); + + Assert.assertEquals(recognizeUtf8Text + ? "“John Doe´s list of currency symbols”™\r" + + "€, ¢, £, ¥, ¤" + : "“John Doe´s list of currency symbolsâ€\u009dâ„¢\r" + + "€, ¢, £, Â¥, ¤", doc.getFirstSection().getBody().getText().trim()); + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "recognizeUtf8TextDataProvider") + public static Object[][] recognizeUtf8TextDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } +} diff --git a/Examples/ApiExamples/JavaPorting/ExRtfSaveOptions.java b/Examples/ApiExamples/JavaPorting/ExRtfSaveOptions.java new file mode 100644 index 00000000..54149669 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExRtfSaveOptions.java @@ -0,0 +1,145 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.RtfSaveOptions; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.SaveFormat; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.Shape; +import com.aspose.words.ImageType; +import com.aspose.words.NodeCollection; +import com.aspose.words.NodeType; +import org.testng.annotations.DataProvider; + + +@Test +public class ExRtfSaveOptions extends ApiExampleBase +{ + @Test (dataProvider = "exportImagesDataProvider") + public void exportImages(boolean exportImagesForOldReaders) throws Exception + { + //ExStart + //ExFor:RtfSaveOptions + //ExFor:RtfSaveOptions.ExportCompactSize + //ExFor:RtfSaveOptions.ExportImagesForOldReaders + //ExFor:RtfSaveOptions.SaveFormat + //ExSummary:Shows how to save a document to .rtf with custom options. + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // Create an "RtfSaveOptions" object to pass to the document's "Save" method to modify how we save it to an RTF. + RtfSaveOptions options = new RtfSaveOptions(); + + Assert.assertEquals(SaveFormat.RTF, options.getSaveFormat()); + + // Set the "ExportCompactSize" property to "true" to + // reduce the saved document's size at the cost of right-to-left text compatibility. + options.setExportCompactSize(true); + + // Set the "ExportImagesFotOldReaders" property to "true" to use extra keywords to ensure that our document is + // compatible with pre-Microsoft Word 97 readers and WordPad. + // Set the "ExportImagesFotOldReaders" property to "false" to reduce the size of the document, + // but prevent old readers from being able to read any non-metafile or BMP images that the document may contain. + options.setExportImagesForOldReaders(exportImagesForOldReaders); + + doc.save(getArtifactsDir() + "RtfSaveOptions.ExportImages.rtf", options); + //ExEnd + + if (exportImagesForOldReaders) + { + TestUtil.fileContainsString("nonshppict", getArtifactsDir() + "RtfSaveOptions.ExportImages.rtf"); + TestUtil.fileContainsString("shprslt", getArtifactsDir() + "RtfSaveOptions.ExportImages.rtf"); + } + else + { + if (isRunningOnMono()) + { + return; + } + Assert.Throws(() => + TestUtil.fileContainsString("nonshppict", getArtifactsDir() + "RtfSaveOptions.ExportImages.rtf")); + Assert.Throws(() => + TestUtil.fileContainsString("shprslt", getArtifactsDir() + "RtfSaveOptions.ExportImages.rtf")); + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "exportImagesDataProvider") + public static Object[][] exportImagesDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (groups = "SkipMono", dataProvider = "saveImagesAsWmfDataProvider") + public void saveImagesAsWmf(boolean saveImagesAsWmf) throws Exception + { + //ExStart + //ExFor:RtfSaveOptions.SaveImagesAsWmf + //ExSummary:Shows how to convert all images in a document to the Windows Metafile format as we save the document as an RTF. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Jpeg image:"); + Shape imageShape = builder.insertImage(getImageDir() + "Logo.jpg"); + + Assert.assertEquals(ImageType.JPEG, imageShape.getImageData().getImageType()); + + builder.insertParagraph(); + builder.writeln("Png image:"); + imageShape = builder.insertImage(getImageDir() + "Transparent background logo.png"); + + Assert.assertEquals(ImageType.PNG, imageShape.getImageData().getImageType()); + + // Create an "RtfSaveOptions" object to pass to the document's "Save" method to modify how we save it to an RTF. + RtfSaveOptions rtfSaveOptions = new RtfSaveOptions(); + + // Set the "SaveImagesAsWmf" property to "true" to convert all images in the document to WMF as we save it to RTF. + // Doing so will help readers such as WordPad to read our document. + // Set the "SaveImagesAsWmf" property to "false" to preserve the original format of all images in the document + // as we save it to RTF. This will preserve the quality of the images at the cost of compatibility with older RTF readers. + rtfSaveOptions.setSaveImagesAsWmf(saveImagesAsWmf); + + doc.save(getArtifactsDir() + "RtfSaveOptions.SaveImagesAsWmf.rtf", rtfSaveOptions); + + doc = new Document(getArtifactsDir() + "RtfSaveOptions.SaveImagesAsWmf.rtf"); + + NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); + + if (saveImagesAsWmf) + { + Assert.assertEquals(ImageType.WMF, ((Shape)shapes.get(0)).getImageData().getImageType()); + Assert.assertEquals(ImageType.WMF, ((Shape)shapes.get(1)).getImageData().getImageType()); + } + else + { + Assert.assertEquals(ImageType.JPEG, ((Shape)shapes.get(0)).getImageData().getImageType()); + Assert.assertEquals(ImageType.PNG, ((Shape)shapes.get(1)).getImageData().getImageType()); + } + //ExEnd + } + + //JAVA-added data provider for test method + @DataProvider(name = "saveImagesAsWmfDataProvider") + public static Object[][] saveImagesAsWmfDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } +} diff --git a/Examples/ApiExamples/JavaPorting/ExSavingCallback.java b/Examples/ApiExamples/JavaPorting/ExSavingCallback.java new file mode 100644 index 00000000..0780c237 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExSavingCallback.java @@ -0,0 +1,321 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.HtmlFixedSaveOptions; +import com.aspose.words.ImageSaveOptions; +import com.aspose.words.SaveFormat; +import com.aspose.words.PdfSaveOptions; +import com.aspose.words.PsSaveOptions; +import com.aspose.words.SvgSaveOptions; +import com.aspose.words.XamlFixedSaveOptions; +import com.aspose.words.XpsSaveOptions; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.BreakType; +import com.aspose.ms.System.IO.Directory; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.IPageSavingCallback; +import com.aspose.words.PageSavingArgs; +import com.aspose.ms.System.IO.FileStream; +import com.aspose.ms.System.IO.FileMode; +import com.aspose.words.HtmlSaveOptions; +import com.aspose.words.DocumentSplitCriteria; +import com.aspose.words.IDocumentPartSavingCallback; +import com.aspose.words.DocumentPartSavingArgs; +import com.aspose.words.IImageSavingCallback; +import com.aspose.words.ImageSavingArgs; +import com.aspose.words.CssStyleSheetType; +import com.aspose.words.ICssSavingCallback; +import com.aspose.words.CssSavingArgs; + + +@Test +class ExSavingCallback !Test class should be public in Java to run, please fix .Net source! extends ApiExampleBase +{ + @Test + public void checkThatAllMethodsArePresent() + { + HtmlFixedSaveOptions htmlFixedSaveOptions = new HtmlFixedSaveOptions(); + htmlFixedSaveOptions.setPageSavingCallback(new CustomFileNamePageSavingCallback()); + + ImageSaveOptions imageSaveOptions = new ImageSaveOptions(SaveFormat.PNG); + imageSaveOptions.setPageSavingCallback(new CustomFileNamePageSavingCallback()); + + PdfSaveOptions pdfSaveOptions = new PdfSaveOptions(); + pdfSaveOptions.setPageSavingCallback(new CustomFileNamePageSavingCallback()); + + PsSaveOptions psSaveOptions = new PsSaveOptions(); + psSaveOptions.setPageSavingCallback(new CustomFileNamePageSavingCallback()); + + SvgSaveOptions svgSaveOptions = new SvgSaveOptions(); + svgSaveOptions.setPageSavingCallback(new CustomFileNamePageSavingCallback()); + + XamlFixedSaveOptions xamlFixedSaveOptions = new XamlFixedSaveOptions(); + xamlFixedSaveOptions.setPageSavingCallback(new CustomFileNamePageSavingCallback()); + + XpsSaveOptions xpsSaveOptions = new XpsSaveOptions(); + xpsSaveOptions.setPageSavingCallback(new CustomFileNamePageSavingCallback()); + } + + //ExStart + //ExFor:IPageSavingCallback + //ExFor:IPageSavingCallback.PageSaving(PageSavingArgs) + //ExFor:PageSavingArgs + //ExFor:PageSavingArgs.PageFileName + //ExFor:PageSavingArgs.KeepPageStreamOpen + //ExFor:PageSavingArgs.PageIndex + //ExFor:PageSavingArgs.PageStream + //ExFor:FixedPageSaveOptions.PageSavingCallback + //ExSummary:Shows how to use a callback to save a document to HTML page by page. + @Test //ExSkip + public void pageFileNames() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Page 1."); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 2."); + builder.insertImage(getImageDir() + "Logo.jpg"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 3."); + + // Create an "HtmlFixedSaveOptions" object, which we can pass to the document's "Save" method + // to modify how we convert the document to HTML. + HtmlFixedSaveOptions htmlFixedSaveOptions = new HtmlFixedSaveOptions(); + + // We will save each page in this document to a separate HTML file in the local file system. + // Set a callback that allows us to name each output HTML document. + htmlFixedSaveOptions.setPageSavingCallback(new CustomFileNamePageSavingCallback()); + + doc.save(getArtifactsDir() + "SavingCallback.PageFileNames.html", htmlFixedSaveOptions); + + String[] filePaths = Directory.getFiles(getArtifactsDir()).Where( + s => s.StartsWith(ArtifactsDir + "SavingCallback.PageFileNames.Page_")).OrderBy(s => s).ToArray(); + + Assert.assertEquals(3, filePaths.length); + } + + /// + /// Saves all pages to a file and directory specified within. + /// + private static class CustomFileNamePageSavingCallback implements IPageSavingCallback + { + public void pageSaving(PageSavingArgs args) throws Exception + { + String outFileName = $"{ArtifactsDir}SavingCallback.PageFileNames.Page_{args.PageIndex}.html"; + + // Below are two ways of specifying where Aspose.Words will save each page of the document. + // 1 - Set a filename for the output page file: + args.setPageFileName(outFileName); + + // 2 - Create a custom stream for the output page file: + args.setPageStreamInternal(new FileStream(outFileName, FileMode.CREATE)); + + Assert.assertFalse(args.getKeepPageStreamOpen()); + } + } + //ExEnd + + //ExStart + //ExFor:DocumentPartSavingArgs + //ExFor:DocumentPartSavingArgs.Document + //ExFor:DocumentPartSavingArgs.DocumentPartFileName + //ExFor:DocumentPartSavingArgs.DocumentPartStream + //ExFor:DocumentPartSavingArgs.KeepDocumentPartStreamOpen + //ExFor:IDocumentPartSavingCallback + //ExFor:IDocumentPartSavingCallback.DocumentPartSaving(DocumentPartSavingArgs) + //ExFor:IImageSavingCallback + //ExFor:IImageSavingCallback.ImageSaving + //ExFor:ImageSavingArgs + //ExFor:ImageSavingArgs.ImageFileName + //ExFor:HtmlSaveOptions + //ExFor:HtmlSaveOptions.DocumentPartSavingCallback + //ExFor:HtmlSaveOptions.ImageSavingCallback + //ExSummary:Shows how to split a document into parts and save them. + @Test //ExSkip + public void documentPartsFileNames() throws Exception + { + Document doc = new Document(getMyDir() + "Rendering.docx"); + String outFileName = "SavingCallback.DocumentPartsFileNames.html"; + + // Create an "HtmlFixedSaveOptions" object, which we can pass to the document's "Save" method + // to modify how we convert the document to HTML. + HtmlSaveOptions options = new HtmlSaveOptions(); + + // If we save the document normally, there will be one output HTML + // document with all the source document's contents. + // Set the "DocumentSplitCriteria" property to "DocumentSplitCriteria.SectionBreak" to + // save our document to multiple HTML files: one for each section. + options.setDocumentSplitCriteria(DocumentSplitCriteria.SECTION_BREAK); + + // Assign a custom callback to the "DocumentPartSavingCallback" property to alter the document part saving logic. + options.setDocumentPartSavingCallback(new SavedDocumentPartRename(outFileName, options.getDocumentSplitCriteria())); + + // If we convert a document that contains images into html, we will end up with one html file which links to several images. + // Each image will be in the form of a file in the local file system. + // There is also a callback that can customize the name and file system location of each image. + options.setImageSavingCallback(new SavedImageRename(outFileName)); + + doc.save(getArtifactsDir() + outFileName, options); + } + + /// + /// Sets custom filenames for output documents that the saving operation splits a document into. + /// + private static class SavedDocumentPartRename implements IDocumentPartSavingCallback + { + public SavedDocumentPartRename(String outFileName, /*DocumentSplitCriteria*/int documentSplitCriteria) + { + mOutFileName = outFileName; + mDocumentSplitCriteria = documentSplitCriteria; + } + + public void /*IDocumentPartSavingCallback.*/documentPartSaving(DocumentPartSavingArgs args) throws Exception + { + // We can access the entire source document via the "Document" property. + Assert.assertTrue(args.getDocument().getOriginalFileName().endsWith("Rendering.docx")); + + String partType = ""; + + switch (mDocumentSplitCriteria) + { + case DocumentSplitCriteria.PAGE_BREAK: + partType = "Page"; + break; + case DocumentSplitCriteria.COLUMN_BREAK: + partType = "Column"; + break; + case DocumentSplitCriteria.SECTION_BREAK: + partType = "Section"; + break; + case DocumentSplitCriteria.HEADING_PARAGRAPH: + partType = "Paragraph from heading"; + break; + } + + String partFileName = $"{mOutFileName} part {++mCount}, of type {partType}{Path.GetExtension(args.DocumentPartFileName)}"; + + // Below are two ways of specifying where Aspose.Words will save each part of the document. + // 1 - Set a filename for the output part file: + args.setDocumentPartFileName(partFileName); + + // 2 - Create a custom stream for the output part file: + args.setDocumentPartStreamInternal(new FileStream(getArtifactsDir() + partFileName, FileMode.CREATE)); + + Assert.assertTrue(args.getDocumentPartStreamInternal().canWrite()); + Assert.assertFalse(args.getKeepDocumentPartStreamOpen()); + } + + private int mCount; + private /*final*/ String mOutFileName; + private /*final*/ /*DocumentSplitCriteria*/int mDocumentSplitCriteria; + } + + /// + /// Sets custom filenames for image files that an HTML conversion creates. + /// + public static class SavedImageRename implements IImageSavingCallback + { + public SavedImageRename(String outFileName) + { + mOutFileName = outFileName; + } + + public void /*IImageSavingCallback.*/imageSaving(ImageSavingArgs args) throws Exception + { + String imageFileName = $"{mOutFileName} shape {++mCount}, of type {args.CurrentShape.ShapeType}{Path.GetExtension(args.ImageFileName)}"; + + // Below are two ways of specifying where Aspose.Words will save each part of the document. + // 1 - Set a filename for the output image file: + args.setImageFileName(imageFileName); + + // 2 - Create a custom stream for the output image file: + args.ImageStream = new FileStream(getArtifactsDir() + imageFileName, FileMode.CREATE); + + Assert.That(args.ImageStream.CanWrite, assertTrue(); + Assert.assertTrue(args.isImageAvailable()); + Assert.assertFalse(args.getKeepImageStreamOpen()); + } + + private int mCount; + private /*final*/ String mOutFileName; + } + //ExEnd + + //ExStart + //ExFor:CssSavingArgs + //ExFor:CssSavingArgs.CssStream + //ExFor:CssSavingArgs.Document + //ExFor:CssSavingArgs.IsExportNeeded + //ExFor:CssSavingArgs.KeepCssStreamOpen + //ExFor:CssStyleSheetType + //ExFor:HtmlSaveOptions.CssSavingCallback + //ExFor:HtmlSaveOptions.CssStyleSheetFileName + //ExFor:HtmlSaveOptions.CssStyleSheetType + //ExFor:ICssSavingCallback + //ExFor:ICssSavingCallback.CssSaving(CssSavingArgs) + //ExSummary:Shows how to work with CSS stylesheets that an HTML conversion creates. + @Test //ExSkip + public void externalCssFilenames() throws Exception + { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // Create an "HtmlFixedSaveOptions" object, which we can pass to the document's "Save" method + // to modify how we convert the document to HTML. + HtmlSaveOptions options = new HtmlSaveOptions(); + + // Set the "CssStylesheetType" property to "CssStyleSheetType.External" to + // accompany a saved HTML document with an external CSS stylesheet file. + options.setCssStyleSheetType(CssStyleSheetType.EXTERNAL); + + // Below are two ways of specifying directories and filenames for output CSS stylesheets. + // 1 - Use the "CssStyleSheetFileName" property to assign a filename to our stylesheet: + options.setCssStyleSheetFileName(getArtifactsDir() + "SavingCallback.ExternalCssFilenames.css"); + + // 2 - Use a custom callback to name our stylesheet: + options.setCssSavingCallback(new CustomCssSavingCallback(getArtifactsDir() + "SavingCallback.ExternalCssFilenames.css", true, false)); + + doc.save(getArtifactsDir() + "SavingCallback.ExternalCssFilenames.html", options); + } + + /// + /// Sets a custom filename, along with other parameters for an external CSS stylesheet. + /// + private static class CustomCssSavingCallback implements ICssSavingCallback + { + public CustomCssSavingCallback(String cssDocFilename, boolean isExportNeeded, boolean keepCssStreamOpen) + { + mCssTextFileName = cssDocFilename; + mIsExportNeeded = isExportNeeded; + mKeepCssStreamOpen = keepCssStreamOpen; + } + + public void cssSaving(CssSavingArgs args) throws Exception + { + // We can access the entire source document via the "Document" property. + Assert.assertTrue(args.getDocument().getOriginalFileName().endsWith("Rendering.docx")); + + args.CssStream = new FileStream(mCssTextFileName, FileMode.CREATE); + args.isExportNeeded(mIsExportNeeded); + args.setKeepCssStreamOpen(mKeepCssStreamOpen); + + Assert.That(args.CssStream.CanWrite, assertTrue(); + } + + private /*final*/ String mCssTextFileName; + private /*final*/ boolean mIsExportNeeded; + private /*final*/ boolean mKeepCssStreamOpen; + } + //ExEnd +} diff --git a/Examples/ApiExamples/JavaPorting/ExSection.java b/Examples/ApiExamples/JavaPorting/ExSection.java new file mode 100644 index 00000000..8cc4b40c --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExSection.java @@ -0,0 +1,623 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.BreakType; +import com.aspose.words.TextFormFieldType; +import com.aspose.words.ProtectionType; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.Section; +import com.aspose.words.SectionStart; +import com.aspose.words.PaperSize; +import com.aspose.words.Body; +import com.aspose.words.Paragraph; +import com.aspose.words.ParagraphAlignment; +import com.aspose.words.Run; +import java.awt.Color; +import com.aspose.words.NodeType; +import com.aspose.words.HeaderFooterType; +import com.aspose.words.Node; +import com.aspose.ms.System.msConsole; +import com.aspose.words.HeaderFooter; +import com.aspose.words.ControlChar; +import com.aspose.words.ShapeType; +import com.aspose.ms.System.Threading.CurrentThread; +import com.aspose.ms.System.Globalization.msCultureInfo; +import com.aspose.words.HeaderFooterCollection; +import com.aspose.words.WatermarkType; + + +@Test +public class ExSection extends ApiExampleBase +{ + @Test + public void protect() throws Exception + { + //ExStart + //ExFor:Document.Protect(ProtectionType) + //ExFor:ProtectionType + //ExFor:Section.ProtectedForForms + //ExSummary:Shows how to turn off protection for a section. + Document doc = new Document(); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Section 1. Hello world!"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + + builder.writeln("Section 2. Hello again!"); + builder.write("Please enter text here: "); + builder.insertTextInput("TextInput1", TextFormFieldType.REGULAR, "", "Placeholder text", 0); + + // Apply write protection to every section in the document. + doc.protect(ProtectionType.ALLOW_ONLY_FORM_FIELDS); + + // Turn off write protection for the first section. + doc.getSections().get(0).setProtectedForForms(false); + + // In this output document, we will be able to edit the first section freely, + // and we will only be able to edit the contents of the form field in the second section. + doc.save(getArtifactsDir() + "Section.Protect.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Section.Protect.docx"); + + Assert.assertFalse(doc.getSections().get(0).getProtectedForForms()); + Assert.assertTrue(doc.getSections().get(1).getProtectedForForms()); + } + + @Test + public void addRemove() throws Exception + { + //ExStart + //ExFor:Document.Sections + //ExFor:Section.Clone + //ExFor:SectionCollection + //ExFor:NodeCollection.RemoveAt(Int32) + //ExSummary:Shows how to add and remove sections in a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Section 1"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.write("Section 2"); + + Assert.assertEquals("Section 1\fSection 2", doc.getText().trim()); + + // Delete the first section from the document. + doc.getSections().removeAt(0); + + Assert.assertEquals("Section 2", doc.getText().trim()); + + // Append a copy of what is now the first section to the end of the document. + int lastSectionIdx = doc.getSections().getCount() - 1; + Section newSection = doc.getSections().get(lastSectionIdx).deepClone(); + doc.getSections().add(newSection); + + Assert.assertEquals("Section 2\fSection 2", doc.getText().trim()); + //ExEnd + } + + @Test + public void firstAndLast() throws Exception + { + //ExStart + //ExFor:Document.FirstSection + //ExFor:Document.LastSection + //ExSummary:Shows how to create a new section with a document builder. + Document doc = new Document(); + + // A blank document contains one section by default, + // which contains child nodes that we can edit. + Assert.assertEquals(1, doc.getSections().getCount()); + + // Use a document builder to add text to the first section. + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello world!"); + + // Create a second section by inserting a section break. + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + + Assert.assertEquals(2, doc.getSections().getCount()); + + // Each section has its own page setup settings. + // We can split the text in the second section into two columns. + // This will not affect the text in the first section. + doc.getLastSection().getPageSetup().getTextColumns().setCount(2); + builder.writeln("Column 1."); + builder.insertBreak(BreakType.COLUMN_BREAK); + builder.writeln("Column 2."); + + Assert.assertEquals(1, doc.getFirstSection().getPageSetup().getTextColumns().getCount()); + Assert.assertEquals(2, doc.getLastSection().getPageSetup().getTextColumns().getCount()); + + doc.save(getArtifactsDir() + "Section.Create.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Section.Create.docx"); + + Assert.assertEquals(1, doc.getFirstSection().getPageSetup().getTextColumns().getCount()); + Assert.assertEquals(2, doc.getLastSection().getPageSetup().getTextColumns().getCount()); + } + + @Test + public void createManually() throws Exception + { + //ExStart + //ExFor:Node.GetText + //ExFor:CompositeNode.RemoveAllChildren + //ExFor:CompositeNode.AppendChild``1(``0) + //ExFor:Section + //ExFor:Section.#ctor + //ExFor:Section.PageSetup + //ExFor:PageSetup.SectionStart + //ExFor:PageSetup.PaperSize + //ExFor:SectionStart + //ExFor:PaperSize + //ExFor:Body + //ExFor:Body.#ctor + //ExFor:Paragraph + //ExFor:Paragraph.#ctor + //ExFor:Paragraph.ParagraphFormat + //ExFor:ParagraphFormat + //ExFor:ParagraphFormat.StyleName + //ExFor:ParagraphFormat.Alignment + //ExFor:ParagraphAlignment + //ExFor:Run + //ExFor:Run.#ctor(DocumentBase) + //ExFor:Run.Text + //ExFor:Inline.Font + //ExSummary:Shows how to construct an Aspose.Words document by hand. + Document doc = new Document(); + + // A blank document contains one section, one body and one paragraph. + // Call the "RemoveAllChildren" method to remove all those nodes, + // and end up with a document node with no children. + doc.removeAllChildren(); + + // This document now has no composite child nodes that we can add content to. + // If we wish to edit it, we will need to repopulate its node collection. + // First, create a new section, and then append it as a child to the root document node. + Section section = new Section(doc); + doc.appendChild(section); + + // Set some page setup properties for the section. + section.getPageSetup().setSectionStart(SectionStart.NEW_PAGE); + section.getPageSetup().setPaperSize(PaperSize.LETTER); + + // A section needs a body, which will contain and display all its contents + // on the page between the section's header and footer. + Body body = new Body(doc); + section.appendChild(body); + + // Create a paragraph, set some formatting properties, and then append it as a child to the body. + Paragraph para = new Paragraph(doc); + + para.getParagraphFormat().setStyleName("Heading 1"); + para.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + + body.appendChild(para); + + // Finally, add some content to do the document. Create a run, + // set its appearance and contents, and then append it as a child to the paragraph. + Run run = new Run(doc); + run.setText("Hello World!"); + run.getFont().setColor(Color.RED); + para.appendChild(run); + + Assert.assertEquals("Hello World!", doc.getText().trim()); + + doc.save(getArtifactsDir() + "Section.CreateManually.docx"); + //ExEnd + } + + @Test + public void ensureMinimum() throws Exception + { + //ExStart + //ExFor:NodeCollection.Add + //ExFor:Section.EnsureMinimum + //ExFor:SectionCollection.Item(Int32) + //ExSummary:Shows how to prepare a new section node for editing. + Document doc = new Document(); + + // A blank document comes with a section, which has a body, which in turn has a paragraph. + // We can add contents to this document by adding elements such as text runs, shapes, or tables to that paragraph. + Assert.assertEquals(NodeType.SECTION, doc.getChild(NodeType.ANY, 0, true).getNodeType()); + Assert.assertEquals(NodeType.BODY, doc.getSections().get(0).getChild(NodeType.ANY, 0, true).getNodeType()); + Assert.assertEquals(NodeType.PARAGRAPH, doc.getSections().get(0).getBody().getChild(NodeType.ANY, 0, true).getNodeType()); + + // If we add a new section like this, it will not have a body, or any other child nodes. + doc.getSections().add(new Section(doc)); + + Assert.assertEquals(0, doc.getSections().get(1).getChildNodes(NodeType.ANY, true).getCount()); + + // Run the "EnsureMinimum" method to add a body and a paragraph to this section to begin editing it. + doc.getLastSection().ensureMinimum(); + + Assert.assertEquals(NodeType.BODY, doc.getSections().get(1).getChild(NodeType.ANY, 0, true).getNodeType()); + Assert.assertEquals(NodeType.PARAGRAPH, doc.getSections().get(1).getBody().getChild(NodeType.ANY, 0, true).getNodeType()); + + doc.getSections().get(0).getBody().getFirstParagraph().appendChild(new Run(doc, "Hello world!")); + + Assert.assertEquals("Hello world!", doc.getText().trim()); + //ExEnd + } + + @Test + public void bodyEnsureMinimum() throws Exception + { + //ExStart + //ExFor:Section.Body + //ExFor:Body.EnsureMinimum + //ExSummary:Clears main text from all sections from the document leaving the sections themselves. + Document doc = new Document(); + + // A blank document contains one section, one body and one paragraph. + // Call the "RemoveAllChildren" method to remove all those nodes, + // and end up with a document node with no children. + doc.removeAllChildren(); + + // This document now has no composite child nodes that we can add content to. + // If we wish to edit it, we will need to repopulate its node collection. + // First, create a new section, and then append it as a child to the root document node. + Section section = new Section(doc); + doc.appendChild(section); + + // A section needs a body, which will contain and display all its contents + // on the page between the section's header and footer. + Body body = new Body(doc); + section.appendChild(body); + + // This body has no children, so we cannot add runs to it yet. + Assert.assertEquals(0, doc.getFirstSection().getBody().getChildNodes(NodeType.ANY, true).getCount()); + + // Call the "EnsureMinimum" to make sure that this body contains at least one empty paragraph. + body.ensureMinimum(); + + // Now, we can add runs to the body, and get the document to display them. + body.getFirstParagraph().appendChild(new Run(doc, "Hello world!")); + + Assert.assertEquals("Hello world!", doc.getText().trim()); + //ExEnd + } + + @Test + public void bodyChildNodes() throws Exception + { + //ExStart + //ExFor:Body.NodeType + //ExFor:HeaderFooter.NodeType + //ExFor:Document.FirstSection + //ExSummary:Shows how to iterate through the children of a composite node. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Section 1"); + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.write("Primary header"); + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + builder.write("Primary footer"); + + Section section = doc.getFirstSection(); + + // A Section is a composite node and can contain child nodes, + // but only if those child nodes are of a "Body" or "HeaderFooter" node type. + for (Node node : (Iterable) section) + { + switch (node.getNodeType()) + { + case NodeType.BODY: + { + Body body = (Body)node; + + System.out.println("Body:"); + System.out.println("\t\"{body.GetText().Trim()}\""); + break; + } + case NodeType.HEADER_FOOTER: + { + HeaderFooter headerFooter = (HeaderFooter)node; + + System.out.println("HeaderFooter type: {headerFooter.HeaderFooterType}:"); + System.out.println("\t\"{headerFooter.GetText().Trim()}\""); + break; + } + default: + { + throw new Exception("Unexpected node type in a section."); + } + } + } + //ExEnd + } + + @Test + public void clear() throws Exception + { + //ExStart + //ExFor:NodeCollection.Clear + //ExSummary:Shows how to remove all sections from a document. + Document doc = new Document(getMyDir() + "Document.docx"); + + // This document has one section with a few child nodes containing and displaying all the document's contents. + Assert.assertEquals(1, doc.getSections().getCount()); + Assert.assertEquals(17, doc.getSections().get(0).getChildNodes(NodeType.ANY, true).getCount()); + Assert.assertEquals("Hello World!\r\rHello Word!\r\r\rHello World!", doc.getText().trim()); + + // Clear the collection of sections, which will remove all of the document's children. + doc.getSections().clear(); + + Assert.assertEquals(0, doc.getChildNodes(NodeType.ANY, true).getCount()); + Assert.assertEquals("", doc.getText().trim()); + //ExEnd + } + + @Test + public void prependAppendContent() throws Exception + { + //ExStart + //ExFor:Section.AppendContent + //ExFor:Section.PrependContent + //ExSummary:Shows how to append the contents of a section to another section. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Section 1"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.write("Section 2"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.write("Section 3"); + + Section section = doc.getSections().get(2); + + Assert.assertEquals("Section 3" + ControlChar.SECTION_BREAK, section.getText()); + + // Insert the contents of the first section to the beginning of the third section. + Section sectionToPrepend = doc.getSections().get(0); + section.prependContent(sectionToPrepend); + + // Insert the contents of the second section to the end of the third section. + Section sectionToAppend = doc.getSections().get(1); + section.appendContent(sectionToAppend); + + // The "PrependContent" and "AppendContent" methods did not create any new sections. + Assert.assertEquals(3, doc.getSections().getCount()); + Assert.assertEquals("Section 1" + ControlChar.PARAGRAPH_BREAK + + "Section 3" + ControlChar.PARAGRAPH_BREAK + + "Section 2" + ControlChar.SECTION_BREAK, section.getText()); + //ExEnd + } + + @Test + public void clearContent() throws Exception + { + //ExStart + //ExFor:Section.ClearContent + //ExSummary:Shows how to clear the contents of a section. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Hello world!"); + + Assert.assertEquals("Hello world!", doc.getText().trim()); + Assert.assertEquals(1, doc.getFirstSection().getBody().getParagraphs().getCount()); + + // Running the "ClearContent" method will remove all the section contents + // but leave a blank paragraph to add content again. + doc.getFirstSection().clearContent(); + + Assert.assertEquals("", doc.getText().trim()); + Assert.assertEquals(1, doc.getFirstSection().getBody().getParagraphs().getCount()); + //ExEnd + } + + @Test + public void clearHeadersFooters() throws Exception + { + //ExStart + //ExFor:Section.ClearHeadersFooters + //ExSummary:Shows how to clear the contents of all headers and footers in a section. + Document doc = new Document(); + + Assert.assertEquals(0, doc.getFirstSection().getHeadersFooters().getCount()); + + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.writeln("This is the primary header."); + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + builder.writeln("This is the primary footer."); + + Assert.assertEquals(2, doc.getFirstSection().getHeadersFooters().getCount()); + + Assert.assertEquals("This is the primary header.", doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.HEADER_PRIMARY).getText().trim()); + Assert.assertEquals("This is the primary footer.", doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY).getText().trim()); + + // Empty all the headers and footers in this section of all their contents. + // The headers and footers themselves will still be present but will have nothing to display. + doc.getFirstSection().clearHeadersFooters(); + + Assert.assertEquals(2, doc.getFirstSection().getHeadersFooters().getCount()); + + Assert.assertEquals("", doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.HEADER_PRIMARY).getText().trim()); + Assert.assertEquals("", doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY).getText().trim()); + //ExEnd + } + + @Test + public void deleteHeaderFooterShapes() throws Exception + { + //ExStart + //ExFor:Section.DeleteHeaderFooterShapes + //ExSummary:Shows how to remove all shapes from all headers footers in a section. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a primary header with a shape. + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.insertShape(ShapeType.RECTANGLE, 100.0, 100.0); + + // Create a primary footer with an image. + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + builder.insertImage(getImageDir() + "Logo icon.ico"); + + Assert.assertEquals(1, doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.HEADER_PRIMARY).getChildNodes(NodeType.SHAPE, true).getCount()); + Assert.assertEquals(1, doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY).getChildNodes(NodeType.SHAPE, true).getCount()); + + // Remove all shapes from the headers and footers in the first section. + doc.getFirstSection().deleteHeaderFooterShapes(); + + Assert.assertEquals(0, doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.HEADER_PRIMARY).getChildNodes(NodeType.SHAPE, true).getCount()); + Assert.assertEquals(0, doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY).getChildNodes(NodeType.SHAPE, true).getCount()); + //ExEnd + } + + @Test + public void sectionsCloneSection() throws Exception + { + Document doc = new Document(getMyDir() + "Document.docx"); + Section cloneSection = doc.getSections().get(0).deepClone(); + } + + @Test + public void sectionsImportSection() throws Exception + { + Document srcDoc = new Document(getMyDir() + "Document.docx"); + Document dstDoc = new Document(); + + Section sourceSection = srcDoc.getSections().get(0); + Section newSection = (Section) dstDoc.importNode(sourceSection, true); + dstDoc.getSections().add(newSection); + } + + @Test + public void migrateFrom2XImportSection() throws Exception + { + Document srcDoc = new Document(); + Document dstDoc = new Document(); + + Section sourceSection = srcDoc.getSections().get(0); + Section newSection = (Section) dstDoc.importNode(sourceSection, true); + dstDoc.getSections().add(newSection); + } + + @Test + public void modifyPageSetupInAllSections() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Section 1"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.write("Section 2"); + + // It is important to understand that a document can contain many sections, + // and each section has its page setup. In this case, we want to modify them all. + for (Section section : (Iterable
          ) doc.getChildNodes(NodeType.SECTION, true)) + section.getPageSetup().setPaperSize(PaperSize.LETTER); + + doc.save(getArtifactsDir() + "Section.ModifyPageSetupInAllSections.doc"); + } + + @Test + public void cultureInfoPageSetupDefaults() throws Exception + { + CurrentThread.setCurrentCulture(new msCultureInfo("en-us")); + + Document docEn = new Document(); + + // Assert that page defaults comply with current culture info. + Section sectionEn = docEn.getSections().get(0); + Assert.assertEquals(72.0, sectionEn.getPageSetup().getLeftMargin()); // 2.54 cm + Assert.assertEquals(72.0, sectionEn.getPageSetup().getRightMargin()); // 2.54 cm + Assert.assertEquals(72.0, sectionEn.getPageSetup().getTopMargin()); // 2.54 cm + Assert.assertEquals(72.0, sectionEn.getPageSetup().getBottomMargin()); // 2.54 cm + Assert.assertEquals(36.0, sectionEn.getPageSetup().getHeaderDistance()); // 1.27 cm + Assert.assertEquals(36.0, sectionEn.getPageSetup().getFooterDistance()); // 1.27 cm + Assert.assertEquals(36.0, sectionEn.getPageSetup().getTextColumns().getSpacing()); // 1.27 cm + + // Change the culture and assert that the page defaults are changed. + CurrentThread.setCurrentCulture(new msCultureInfo("de-de")); + + Document docDe = new Document(); + + Section sectionDe = docDe.getSections().get(0); + Assert.assertEquals(70.85, sectionDe.getPageSetup().getLeftMargin()); // 2.5 cm + Assert.assertEquals(70.85, sectionDe.getPageSetup().getRightMargin()); // 2.5 cm + Assert.assertEquals(70.85, sectionDe.getPageSetup().getTopMargin()); // 2.5 cm + Assert.assertEquals(56.7, sectionDe.getPageSetup().getBottomMargin()); // 2 cm + Assert.assertEquals(35.4, sectionDe.getPageSetup().getHeaderDistance()); // 1.25 cm + Assert.assertEquals(35.4, sectionDe.getPageSetup().getFooterDistance()); // 1.25 cm + Assert.assertEquals(35.4, sectionDe.getPageSetup().getTextColumns().getSpacing()); // 1.25 cm + + // Change page defaults. + sectionDe.getPageSetup().setLeftMargin(90.0); // 3.17 cm + sectionDe.getPageSetup().setRightMargin(90.0); // 3.17 cm + sectionDe.getPageSetup().setTopMargin(72.0); // 2.54 cm + sectionDe.getPageSetup().setBottomMargin(72.0); // 2.54 cm + sectionDe.getPageSetup().setHeaderDistance(35.4); // 1.25 cm + sectionDe.getPageSetup().setFooterDistance(35.4); // 1.25 cm + sectionDe.getPageSetup().getTextColumns().setSpacing(35.4); // 1.25 cm + + docDe = DocumentHelper.saveOpen(docDe); + + Section sectionDeAfter = docDe.getSections().get(0); + Assert.assertEquals(90.0, sectionDeAfter.getPageSetup().getLeftMargin()); // 3.17 cm + Assert.assertEquals(90.0, sectionDeAfter.getPageSetup().getRightMargin()); // 3.17 cm + Assert.assertEquals(72.0, sectionDeAfter.getPageSetup().getTopMargin()); // 2.54 cm + Assert.assertEquals(72.0, sectionDeAfter.getPageSetup().getBottomMargin()); // 2.54 cm + Assert.assertEquals(35.4, sectionDeAfter.getPageSetup().getHeaderDistance()); // 1.25 cm + Assert.assertEquals(35.4, sectionDeAfter.getPageSetup().getFooterDistance()); // 1.25 cm + Assert.assertEquals(35.4, sectionDeAfter.getPageSetup().getTextColumns().getSpacing()); // 1.25 cm + } + + @Test + public void preserveWatermarks() throws Exception + { + //ExStart:PreserveWatermarks + //GistId:708ce40a68fac5003d46f6b4acfd5ff1 + //ExFor:Section.ClearHeadersFooters(bool) + //ExSummary:Shows how to clear the contents of header and footer with or without a watermark. + Document doc = new Document(getMyDir() + "Header and footer types.docx"); + + // Add a plain text watermark. + doc.getWatermark().setText("Aspose Watermark"); + + // Make sure the headers and footers have content. + HeaderFooterCollection headersFooters = doc.getFirstSection().getHeadersFooters(); + Assert.assertEquals("First header", headersFooters.getByHeaderFooterType(HeaderFooterType.HEADER_FIRST).getText().trim()); + Assert.assertEquals("Second header", headersFooters.getByHeaderFooterType(HeaderFooterType.HEADER_EVEN).getText().trim()); + Assert.assertEquals("Third header", headersFooters.getByHeaderFooterType(HeaderFooterType.HEADER_PRIMARY).getText().trim()); + Assert.assertEquals("First footer", headersFooters.getByHeaderFooterType(HeaderFooterType.FOOTER_FIRST).getText().trim()); + Assert.assertEquals("Second footer", headersFooters.getByHeaderFooterType(HeaderFooterType.FOOTER_EVEN).getText().trim()); + Assert.assertEquals("Third footer", headersFooters.getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY).getText().trim()); + + // Removes all header and footer content except watermarks. + doc.getFirstSection().clearHeadersFooters(true); + + headersFooters = doc.getFirstSection().getHeadersFooters(); + Assert.assertEquals("", headersFooters.getByHeaderFooterType(HeaderFooterType.HEADER_FIRST).getText().trim()); + Assert.assertEquals("", headersFooters.getByHeaderFooterType(HeaderFooterType.HEADER_EVEN).getText().trim()); + Assert.assertEquals("", headersFooters.getByHeaderFooterType(HeaderFooterType.HEADER_PRIMARY).getText().trim()); + Assert.assertEquals("", headersFooters.getByHeaderFooterType(HeaderFooterType.FOOTER_FIRST).getText().trim()); + Assert.assertEquals("", headersFooters.getByHeaderFooterType(HeaderFooterType.FOOTER_EVEN).getText().trim()); + Assert.assertEquals("", headersFooters.getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY).getText().trim()); + Assert.assertEquals(WatermarkType.TEXT, doc.getWatermark().getType()); + + // Removes all header and footer content including watermarks. + doc.getFirstSection().clearHeadersFooters(false); + Assert.assertEquals(WatermarkType.NONE, doc.getWatermark().getType()); + //ExEnd:PreserveWatermarks + } +} diff --git a/Examples/ApiExamples/JavaPorting/ExShape.java b/Examples/ApiExamples/JavaPorting/ExShape.java new file mode 100644 index 00000000..b504af9a --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExShape.java @@ -0,0 +1,3694 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.Shape; +import com.aspose.words.ShapeType; +import org.testng.Assert; +import com.aspose.ms.System.IO.File; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.NodeType; +import com.aspose.ms.System.Drawing.msColor; +import java.awt.Color; +import com.aspose.words.Underline; +import com.aspose.words.WrapType; +import com.aspose.words.GroupShape; +import com.aspose.ms.System.Drawing.RectangleF; +import com.aspose.ms.System.Drawing.msSize; +import com.aspose.ms.System.Drawing.msPoint; +import com.aspose.words.DashStyle; +import com.aspose.words.Paragraph; +import com.aspose.ms.System.Drawing.msPointF; +import com.aspose.words.BreakType; +import com.aspose.words.NodeCollection; +import com.aspose.words.RelativeHorizontalPosition; +import com.aspose.words.RelativeVerticalPosition; +import com.aspose.words.FlipOrientation; +import com.aspose.ms.System.Convert; +import com.aspose.words.PresetTexture; +import com.aspose.words.TextureAlignment; +import com.aspose.words.OoxmlSaveOptions; +import com.aspose.words.OoxmlCompliance; +import com.aspose.words.GradientStyle; +import com.aspose.words.GradientVariant; +import com.aspose.words.GradientStopCollection; +import com.aspose.words.GradientStop; +import com.aspose.words.Fill; +import com.aspose.ms.System.msConsole; +import com.aspose.words.PatternType; +import com.aspose.words.ThemeColor; +import com.aspose.words.WrapSide; +import com.aspose.words.HorizontalAlignment; +import com.aspose.words.VerticalAlignment; +import com.aspose.words.ParagraphAlignment; +import com.aspose.words.Run; +import com.aspose.words.OleControl; +import com.aspose.words.Forms2OleControl; +import com.aspose.words.Forms2OleControlType; +import com.aspose.words.OleFormat; +import com.aspose.ms.System.IO.FileStream; +import com.aspose.ms.System.IO.FileMode; +import com.aspose.ms.System.IO.FileInfo; +import com.aspose.ms.System.IO.Path; +import com.aspose.ms.System.IO.MemoryStream; +import com.aspose.words.Forms2OleControlCollection; +import com.aspose.words.OfficeMath; +import com.aspose.words.ImageSaveOptions; +import com.aspose.words.SaveFormat; +import com.aspose.words.OfficeMathDisplayType; +import com.aspose.words.OfficeMathJustification; +import com.aspose.words.MathObjectType; +import com.aspose.words.ShapeMarkupLanguage; +import com.aspose.ms.System.Drawing.msSizeF; +import com.aspose.words.MsWordVersion; +import com.aspose.words.Stroke; +import com.aspose.words.JoinStyle; +import com.aspose.words.EndCap; +import com.aspose.words.ShapeLineStyle; +import com.aspose.words.OlePackage; +import com.aspose.words.HeightRule; +import java.text.MessageFormat; +import java.util.ArrayList; +import com.aspose.words.Table; +import com.aspose.words.TableStyle; +import com.aspose.words.StyleType; +import com.aspose.words.LineStyle; +import com.aspose.words.DocumentVisitor; +import com.aspose.ms.System.Text.msStringBuilder; +import com.aspose.words.VisitorAction; +import com.aspose.words.SignatureLineOptions; +import com.aspose.words.SignatureLine; +import com.aspose.words.LayoutFlow; +import com.aspose.words.TextBox; +import com.aspose.words.TextBoxWrapMode; +import com.aspose.words.TextBoxAnchor; +import com.aspose.words.TextPathAlignment; +import com.aspose.words.ShapeRenderer; +import com.aspose.words.OfficeMathRenderer; +import com.aspose.ms.System.Drawing.Rectangle; +import com.aspose.words.ShadowType; +import com.aspose.words.RelativeHorizontalSize; +import com.aspose.words.RelativeVerticalSize; +import com.aspose.words.TextBoxControl; +import com.aspose.words.ReflectionFormat; +import com.aspose.words.SoftEdgeFormat; +import com.aspose.words.AdjustmentCollection; +import com.aspose.words.Adjustment; +import com.aspose.words.ShadowFormat; +import com.aspose.words.OptionButtonControl; +import com.aspose.words.CheckBoxControl; +import com.aspose.words.CommandButtonControl; +import org.testng.annotations.DataProvider; + + +/// +/// Examples using shapes in documents. +/// +@Test +public class ExShape extends ApiExampleBase +{ + @Test + public void altText() throws Exception + { + //ExStart + //ExFor:ShapeBase.AlternativeText + //ExFor:ShapeBase.Name + //ExSummary:Shows how to use a shape's alternative text. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + Shape shape = builder.insertShape(ShapeType.CUBE, 150.0, 150.0); + shape.setName("MyCube"); + + shape.setAlternativeText("Alt text for MyCube."); + + // We can access the alternative text of a shape by right-clicking it, and then via "Format AutoShape" -> "Alt Text". + doc.save(getArtifactsDir() + "Shape.AltText.docx"); + + // Save the document to HTML, and then delete the linked image that belongs to our shape. + // The browser that is reading our HTML will display the alt text in place of the missing image. + doc.save(getArtifactsDir() + "Shape.AltText.html"); + Assert.assertTrue(File.exists(getArtifactsDir() + "Shape.AltText.001.png")); //ExSkip + File.delete(getArtifactsDir() + "Shape.AltText.001.png"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.AltText.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.CUBE, "MyCube", 150.0d, 150.0d, 0.0, 0.0, shape); + Assert.assertEquals("Alt text for MyCube.", shape.getAlternativeText()); + Assert.assertEquals("Times New Roman", shape.getFont().getName()); + + doc = new Document(getArtifactsDir() + "Shape.AltText.html"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.IMAGE, "", 151.5d, 151.5d, 0.0, 0.0, shape); + Assert.assertEquals("Alt text for MyCube.", shape.getAlternativeText()); + + TestUtil.fileContainsString( + "\"Alt", + getArtifactsDir() + "Shape.AltText.html"); + } + + @Test (dataProvider = "fontDataProvider") + public void font(boolean hideShape) throws Exception + { + //ExStart + //ExFor:ShapeBase.Font + //ExFor:ShapeBase.ParentParagraph + //ExSummary:Shows how to insert a text box, and set the font of its contents. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + + Shape shape = builder.insertShape(ShapeType.TEXT_BOX, 300.0, 50.0); + builder.moveTo(shape.getLastParagraph()); + builder.write("This text is inside the text box."); + + // Set the "Hidden" property of the shape's "Font" object to "true" to hide the text box from sight + // and collapse the space that it would normally occupy. + // Set the "Hidden" property of the shape's "Font" object to "false" to leave the text box visible. + shape.getFont().setHidden(hideShape); + + // If the shape is visible, we will modify its appearance via the font object. + if (!hideShape) + { + shape.getFont().setHighlightColor(msColor.getLightGray()); + shape.getFont().setColor(Color.RED); + shape.getFont().setUnderline(Underline.DASH); + } + + // Move the builder out of the text box back into the main document. + builder.moveTo(shape.getParentParagraph()); + + builder.writeln("\nThis text is outside the text box."); + + doc.save(getArtifactsDir() + "Shape.Font.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.Font.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(hideShape, shape.getFont().getHidden()); + + if (hideShape) + { + Assert.assertEquals(msColor.Empty.getRGB(), shape.getFont().getHighlightColor().getRGB()); + Assert.assertEquals(msColor.Empty.getRGB(), shape.getFont().getColor().getRGB()); + Assert.assertEquals(Underline.NONE, shape.getFont().getUnderline()); + } + else + { + Assert.assertEquals(msColor.getSilver().getRGB(), shape.getFont().getHighlightColor().getRGB()); + Assert.assertEquals(Color.RED.getRGB(), shape.getFont().getColor().getRGB()); + Assert.assertEquals(Underline.DASH, shape.getFont().getUnderline()); + } + + TestUtil.verifyShape(ShapeType.TEXT_BOX, "TextBox 100002", 300.0d, 50.0d, 0.0, 0.0, shape); + Assert.assertEquals("This text is inside the text box.", shape.getText().trim()); + Assert.assertEquals("Hello world!\rThis text is inside the text box.\r\rThis text is outside the text box.", doc.getText().trim()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "fontDataProvider") + public static Object[][] fontDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void rotate() throws Exception + { + //ExStart + //ExFor:ShapeBase.CanHaveImage + //ExFor:ShapeBase.Rotation + //ExSummary:Shows how to insert and rotate an image. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a shape with an image. + Shape shape = builder.insertImage(getImageDir() + "Logo.jpg"); + Assert.assertTrue(shape.canHaveImage()); + Assert.assertTrue(shape.hasImage()); + + // Rotate the image 45 degrees clockwise. + shape.setRotation(45.0); + + doc.save(getArtifactsDir() + "Shape.Rotate.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.Rotate.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.IMAGE, "", 300.0d, 300.0d, 0.0, 0.0, shape); + Assert.assertTrue(shape.canHaveImage()); + Assert.assertTrue(shape.hasImage()); + Assert.assertEquals(45.0d, shape.getRotation()); + } + + @Test + public void coordinates() throws Exception + { + //ExStart + //ExFor:ShapeBase.DistanceBottom + //ExFor:ShapeBase.DistanceLeft + //ExFor:ShapeBase.DistanceRight + //ExFor:ShapeBase.DistanceTop + //ExSummary:Shows how to set the wrapping distance for a text that surrounds a shape. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a rectangle and, get the text to wrap tightly around its bounds. + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 150.0, 150.0); + shape.setWrapType(WrapType.TIGHT); + + // Set the minimum distance between the shape and surrounding text to 40pt from all sides. + shape.setDistanceTop(40.0); + shape.setDistanceBottom(40.0); + shape.setDistanceLeft(40.0); + shape.setDistanceRight(40.0); + + // Move the shape closer to the center of the page, and then rotate the shape 60 degrees clockwise. + shape.setTop(75.0); + shape.setLeft(150.0); + shape.setRotation(60.0); + + // Add text that will wrap around the shape. + builder.getFont().setSize(24.0); + builder.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " + + "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."); + + doc.save(getArtifactsDir() + "Shape.Coordinates.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.Coordinates.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.RECTANGLE, "Rectangle 100002", 150.0d, 150.0d, 75.0d, 150.0d, shape); + Assert.assertEquals(40.0d, shape.getDistanceBottom()); + Assert.assertEquals(40.0d, shape.getDistanceLeft()); + Assert.assertEquals(40.0d, shape.getDistanceRight()); + Assert.assertEquals(40.0d, shape.getDistanceTop()); + Assert.assertEquals(60.0d, shape.getRotation()); + } + + @Test + public void groupShape() throws Exception + { + //ExStart + //ExFor:ShapeBase.Bounds + //ExFor:ShapeBase.CoordOrigin + //ExFor:ShapeBase.CoordSize + //ExSummary:Shows how to create and populate a group shape. + Document doc = new Document(); + + // Create a group shape. A group shape can display a collection of child shape nodes. + // In Microsoft Word, clicking within the group shape's boundary or on one of the group shape's child shapes will + // select all the other child shapes within this group and allow us to scale and move all the shapes at once. + GroupShape group = new GroupShape(doc); + + Assert.assertEquals(WrapType.NONE, group.getWrapType()); + + // Create a 400pt x 400pt group shape and place it at the document's floating shape coordinate origin. + group.setBoundsInternal(new RectangleF(0f, 0f, 400f, 400f)); + + // Set the group's internal coordinate plane size to 500 x 500pt. + // The top left corner of the group will have an x and y coordinate of (0, 0), + // and the bottom right corner will have an x and y coordinate of (500, 500). + group.setCoordSizeInternal(msSize.ctor(500, 500)); + + // Set the coordinates of the top left corner of the group to (-250, -250). + // The group's center will now have an x and y coordinate value of (0, 0), + // and the bottom right corner will be at (250, 250). + group.setCoordOriginInternal(msPoint.ctor(-250, -250)); + + // Create a rectangle that will display the boundary of this group shape and add it to the group. + Shape child1 = new Shape(doc, ShapeType.RECTANGLE); + { + child1.setWidth(msSize.getWidth(group.getCoordSizeInternal())); + child1.setHeight(msSize.getHeight(group.getCoordSizeInternal())); + child1.setLeft(msPoint.getX(group.getCoordOriginInternal())); + child1.setTop(msPoint.getY(group.getCoordOriginInternal())); + } + group.appendChild(child1); + + // Once a shape is a part of a group shape, we can access it as a child node and then modify it. + ((Shape)group.getChild(NodeType.SHAPE, 0, true)).getStroke().setDashStyle(DashStyle.DASH); + + // Create a small red star and insert it into the group. + // Line up the shape with the group's coordinate origin, which we have moved to the center. + Shape child2 = new Shape(doc, ShapeType.STAR); + { + child2.setWidth(20.0); + child2.setHeight(20.0); + child2.setLeft(-10); + child2.setTop(-10); + child2.setFillColor(Color.RED); + } + group.appendChild(child2); + + // Insert a rectangle, and then insert a slightly smaller rectangle in the same place with an image. + // Newer shapes that we add to the group overlap older shapes. The light blue rectangle will partially overlap the red star, + // and then the shape with the image will overlap the light blue rectangle, using it as a frame. + // We cannot use the "ZOrder" properties of shapes to manipulate their arrangement within a group shape. + Shape child3 = new Shape(doc, ShapeType.RECTANGLE); + { + child3.setWidth(250.0); + child3.setHeight(250.0); + child3.setLeft(-250); + child3.setTop(-250); + child3.setFillColor(msColor.getLightBlue()); + } + group.appendChild(child3); + + Shape child4 = new Shape(doc, ShapeType.IMAGE); + { + child4.setWidth(200.0); + child4.setHeight(200.0); + child4.setLeft(-225); + child4.setTop(-225); + } + group.appendChild(child4); + + ((Shape)group.getChild(NodeType.SHAPE, 3, true)).getImageData().setImage(getImageDir() + "Logo.jpg"); + + // Insert a text box into the group shape. Set the "Left" property so that the text box's right edge + // touches the right boundary of the group shape. Set the "Top" property so that the text box sits outside + // the boundary of the group shape, with its top size lined up along the group shape's bottom margin. + Shape child5 = new Shape(doc, ShapeType.TEXT_BOX); + { + child5.setWidth(200.0); + child5.setHeight(50.0); + child5.setLeft(msSize.getWidth(group.getCoordSizeInternal()) + msPoint.getX(group.getCoordOriginInternal()) - 200); + child5.setTop(msSize.getHeight(group.getCoordSizeInternal()) + msPoint.getY(group.getCoordOriginInternal())); + } + group.appendChild(child5); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertNode(group); + builder.moveTo(((Shape)group.getChild(NodeType.SHAPE, 4, true)).appendChild(new Paragraph(doc))); + builder.write("Hello world!"); + + doc.save(getArtifactsDir() + "Shape.GroupShape.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.GroupShape.docx"); + group = (GroupShape)doc.getChild(NodeType.GROUP_SHAPE, 0, true); + + Assert.assertEquals(new RectangleF(0f, 0f, 400f, 400f), group.getBoundsInternal()); + Assert.assertEquals(msSize.ctor(500, 500), group.getCoordSizeInternal()); + Assert.assertEquals(msPoint.ctor(-250, -250), group.getCoordOriginInternal()); + + TestUtil.verifyShape(ShapeType.RECTANGLE, "", 500.0d, 500.0d, -250.0d, -250.0d, (Shape)group.getChild(NodeType.SHAPE, 0, true)); + TestUtil.verifyShape(ShapeType.STAR, "", 20.0d, 20.0d, -10.0d, -10.0d, (Shape)group.getChild(NodeType.SHAPE, 1, true)); + TestUtil.verifyShape(ShapeType.RECTANGLE, "", 250.0d, 250.0d, -250.0d, -250.0d, (Shape)group.getChild(NodeType.SHAPE, 2, true)); + TestUtil.verifyShape(ShapeType.IMAGE, "", 200.0d, 200.0d, -225.0d, -225.0d, (Shape)group.getChild(NodeType.SHAPE, 3, true)); + TestUtil.verifyShape(ShapeType.TEXT_BOX, "", 200.0d, 50.0d, 250.0d, 50.0d, (Shape)group.getChild(NodeType.SHAPE, 4, true)); + } + + @Test + public void isTopLevel() throws Exception + { + //ExStart + //ExFor:ShapeBase.IsTopLevel + //ExSummary:Shows how to tell whether a shape is a part of a group shape. + Document doc = new Document(); + + Shape shape = new Shape(doc, ShapeType.RECTANGLE); + shape.setWidth(200.0); + shape.setHeight(200.0); + shape.setWrapType(WrapType.NONE); + + // A shape by default is not part of any group shape, and therefore has the "IsTopLevel" property set to "true". + Assert.assertTrue(shape.isTopLevel()); + + GroupShape group = new GroupShape(doc); + group.appendChild(shape); + + // Once we assimilate a shape into a group shape, the "IsTopLevel" property changes to "false". + Assert.assertFalse(shape.isTopLevel()); + //ExEnd + } + + @Test + public void localToParent() throws Exception + { + //ExStart + //ExFor:ShapeBase.CoordOrigin + //ExFor:ShapeBase.CoordSize + //ExFor:ShapeBase.LocalToParent(PointF) + //ExSummary:Shows how to translate the x and y coordinate location on a shape's coordinate plane to a location on the parent shape's coordinate plane. + Document doc = new Document(); + + // Insert a group shape, and place it 100 points below and to the right of + // the document's x and Y coordinate origin point. + GroupShape group = new GroupShape(doc); + group.setBoundsInternal(new RectangleF(100f, 100f, 500f, 500f)); + + // Use the "LocalToParent" method to determine that (0, 0) on the group's internal x and y coordinates + // lies on (100, 100) of its parent shape's coordinate system. The group shape's parent is the document itself. + Assert.assertEquals(msPointF.ctor(100f, 100f), group.localToParentInternal(msPointF.ctor(0f, 0f))); + + // By default, a shape's internal coordinate plane has the top left corner at (0, 0), + // and the bottom right corner at (1000, 1000). Due to its size, our group shape covers an area of 500pt x 500pt + // in the document's plane. This means that a movement of 1pt on the document's coordinate plane will translate + // to a movement of 2pts on the group shape's coordinate plane. + Assert.assertEquals(msPointF.ctor(150f, 150f), group.localToParentInternal(msPointF.ctor(100f, 100f))); + Assert.assertEquals(msPointF.ctor(200f, 200f), group.localToParentInternal(msPointF.ctor(200f, 200f))); + Assert.assertEquals(msPointF.ctor(250f, 250f), group.localToParentInternal(msPointF.ctor(300f, 300f))); + + // Move the group shape's x and y axis origin from the top left corner to the center. + // This will offset the group's internal coordinates relative to the document's coordinates even further. + group.setCoordOriginInternal(msPoint.ctor(-250, -250)); + + Assert.assertEquals(msPointF.ctor(375f, 375f), group.localToParentInternal(msPointF.ctor(300f, 300f))); + + // Changing the scale of the coordinate plane will also affect relative locations. + group.setCoordSizeInternal(msSize.ctor(500, 500)); + + Assert.assertEquals(msPointF.ctor(650f, 650f), group.localToParentInternal(msPointF.ctor(300f, 300f))); + + // If we wish to add a shape to this group while defining its location based on a location in the document, + // we will need to first confirm a location in the group shape that will match the document's location. + Assert.assertEquals(msPointF.ctor(700f, 700f), group.localToParentInternal(msPointF.ctor(350f, 350f))); + + Shape shape = new Shape(doc, ShapeType.RECTANGLE); + { + shape.setWidth(100.0); + shape.setHeight(100.0); + shape.setLeft(700.0); + shape.setTop(700.0); + } + + group.appendChild(shape); + doc.getFirstSection().getBody().getFirstParagraph().appendChild(group); + + doc.save(getArtifactsDir() + "Shape.LocalToParent.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.LocalToParent.docx"); + group = (GroupShape)doc.getChild(NodeType.GROUP_SHAPE, 0, true); + + Assert.assertEquals(new RectangleF(100f, 100f, 500f, 500f), group.getBoundsInternal()); + Assert.assertEquals(msSize.ctor(500, 500), group.getCoordSizeInternal()); + Assert.assertEquals(msPoint.ctor(-250, -250), group.getCoordOriginInternal()); + } + + @Test (dataProvider = "anchorLockedDataProvider") + public void anchorLocked(boolean anchorLocked) throws Exception + { + //ExStart + //ExFor:ShapeBase.AnchorLocked + //ExSummary:Shows how to lock or unlock a shape's paragraph anchor. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + + builder.write("Our shape will have an anchor attached to this paragraph."); + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 200.0, 160.0); + shape.setWrapType(WrapType.NONE); + builder.insertBreak(BreakType.PARAGRAPH_BREAK); + + builder.writeln("Hello again!"); + + // Set the "AnchorLocked" property to "true" to prevent the shape's anchor + // from moving when moving the shape in Microsoft Word. + // Set the "AnchorLocked" property to "false" to allow any movement of the shape + // to also move its anchor to any other paragraph that the shape ends up close to. + shape.setAnchorLocked(anchorLocked); + + // If the shape does not have a visible anchor symbol to its left, + // we will need to enable visible anchors via "Options" -> "Display" -> "Object Anchors". + doc.save(getArtifactsDir() + "Shape.AnchorLocked.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.AnchorLocked.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(anchorLocked, shape.getAnchorLocked()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "anchorLockedDataProvider") + public static Object[][] anchorLockedDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void deleteAllShapes() throws Exception + { + //ExStart + //ExFor:Shape + //ExSummary:Shows how to delete all shapes from a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert two shapes along with a group shape with another shape inside it. + builder.insertShape(ShapeType.RECTANGLE, 400.0, 200.0); + builder.insertShape(ShapeType.STAR, 300.0, 300.0); + + GroupShape group = new GroupShape(doc); + group.setBoundsInternal(new RectangleF(100f, 50f, 200f, 100f)); + group.setCoordOriginInternal(msPoint.ctor(-1000, -500)); + + Shape subShape = new Shape(doc, ShapeType.CUBE); + subShape.setWidth(500.0); + subShape.setHeight(700.0); + subShape.setLeft(0.0); + subShape.setTop(0.0); + + group.appendChild(subShape); + builder.insertNode(group); + + Assert.assertEquals(3, doc.getChildNodes(NodeType.SHAPE, true).getCount()); + Assert.assertEquals(1, doc.getChildNodes(NodeType.GROUP_SHAPE, true).getCount()); + + // Remove all Shape nodes from the document. + NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); + shapes.clear(); + + // All shapes are gone, but the group shape is still in the document. + Assert.assertEquals(1, doc.getChildNodes(NodeType.GROUP_SHAPE, true).getCount()); + Assert.assertEquals(0, doc.getChildNodes(NodeType.SHAPE, true).getCount()); + + // Remove all group shapes separately. + NodeCollection groupShapes = doc.getChildNodes(NodeType.GROUP_SHAPE, true); + groupShapes.clear(); + + Assert.assertEquals(0, doc.getChildNodes(NodeType.GROUP_SHAPE, true).getCount()); + Assert.assertEquals(0, doc.getChildNodes(NodeType.SHAPE, true).getCount()); + //ExEnd + } + + @Test + public void isInline() throws Exception + { + //ExStart + //ExFor:ShapeBase.IsInline + //ExSummary:Shows how to determine whether a shape is inline or floating. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are two wrapping types that shapes may have. + // 1 - Inline: + builder.write("Hello world! "); + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 100.0, 100.0); + shape.setFillColor(msColor.getLightBlue()); + builder.write(" Hello again."); + + // An inline shape sits inside a paragraph among other paragraph elements, such as runs of text. + // In Microsoft Word, we may click and drag the shape to any paragraph as if it is a character. + // If the shape is large, it will affect vertical paragraph spacing. + // We cannot move this shape to a place with no paragraph. + Assert.assertEquals(WrapType.INLINE, shape.getWrapType()); + Assert.assertTrue(shape.isInline()); + + // 2 - Floating: + shape = builder.insertShape(ShapeType.RECTANGLE, RelativeHorizontalPosition.LEFT_MARGIN, 200.0, + RelativeVerticalPosition.TOP_MARGIN, 200.0, 100.0, 100.0, WrapType.NONE); + shape.setFillColor(msColor.getOrange()); + + // A floating shape belongs to the paragraph that we insert it into, + // which we can determine by an anchor symbol that appears when we click the shape. + // If the shape does not have a visible anchor symbol to its left, + // we will need to enable visible anchors via "Options" -> "Display" -> "Object Anchors". + // In Microsoft Word, we may left click and drag this shape freely to any location. + Assert.assertEquals(WrapType.NONE, shape.getWrapType()); + Assert.assertFalse(shape.isInline()); + + doc.save(getArtifactsDir() + "Shape.IsInline.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.IsInline.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.RECTANGLE, "Rectangle 100002", 100.0, 100.0, 0.0, 0.0, shape); + Assert.assertEquals(msColor.getLightBlue().getRGB(), shape.getFillColor().getRGB()); + Assert.assertEquals(WrapType.INLINE, shape.getWrapType()); + Assert.assertTrue(shape.isInline()); + + shape = (Shape)doc.getChild(NodeType.SHAPE, 1, true); + + TestUtil.verifyShape(ShapeType.RECTANGLE, "Rectangle 100004", 100.0, 100.0, 200.0, 200.0, shape); + Assert.assertEquals(msColor.getOrange().getRGB(), shape.getFillColor().getRGB()); + Assert.assertEquals(WrapType.NONE, shape.getWrapType()); + Assert.assertFalse(shape.isInline()); + } + + @Test + public void bounds() throws Exception + { + //ExStart + //ExFor:ShapeBase.Bounds + //ExFor:ShapeBase.BoundsInPoints + //ExSummary:Shows how to verify shape containing block boundaries. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertShape(ShapeType.LINE, RelativeHorizontalPosition.LEFT_MARGIN, 50.0, + RelativeVerticalPosition.TOP_MARGIN, 50.0, 100.0, 100.0, WrapType.NONE); + shape.setStrokeColor(msColor.getOrange()); + + // Even though the line itself takes up little space on the document page, + // it occupies a rectangular containing block, the size of which we can determine using the "Bounds" properties. + Assert.assertEquals(new RectangleF(50f, 50f, 100f, 100f), shape.getBoundsInternal()); + Assert.assertEquals(new RectangleF(50f, 50f, 100f, 100f), shape.getBoundsInPointsInternal()); + + // Create a group shape, and then set the size of its containing block using the "Bounds" property. + GroupShape group = new GroupShape(doc); + group.setBoundsInternal(new RectangleF(0f, 100f, 250f, 250f)); + + Assert.assertEquals(new RectangleF(0f, 100f, 250f, 250f), group.getBoundsInPointsInternal()); + + // Create a rectangle, verify the size of its bounding block, and then add it to the group shape. + shape = new Shape(doc, ShapeType.RECTANGLE); + { + shape.setWidth(100.0); + shape.setHeight(100.0); + shape.setLeft(700.0); + shape.setTop(700.0); + } + + Assert.assertEquals(new RectangleF(700f, 700f, 100f, 100f), shape.getBoundsInPointsInternal()); + + group.appendChild(shape); + + // The group shape's coordinate plane has its origin on the top left-hand side corner of its containing block, + // and the x and y coordinates of (1000, 1000) on the bottom right-hand side corner. + // Our group shape is 250x250pt in size, so every 4pt on the group shape's coordinate plane + // translates to 1pt in the document body's coordinate plane. + // Every shape that we insert will also shrink in size by a factor of 4. + // The change in the shape's "BoundsInPoints" property will reflect this. + Assert.assertEquals(new RectangleF(175f, 275f, 25f, 25f), shape.getBoundsInPointsInternal()); + + doc.getFirstSection().getBody().getFirstParagraph().appendChild(group); + + // Insert a shape and place it outside of the bounds of the group shape's containing block. + shape = new Shape(doc, ShapeType.RECTANGLE); + { + shape.setWidth(100.0); + shape.setHeight(100.0); + shape.setLeft(1000.0); + shape.setTop(1000.0); + } + + group.appendChild(shape); + + // The group shape's footprint in the document body has increased, but the containing block remains the same. + Assert.assertEquals(new RectangleF(0f, 100f, 250f, 250f), group.getBoundsInPointsInternal()); + Assert.assertEquals(new RectangleF(250f, 350f, 25f, 25f), shape.getBoundsInPointsInternal()); + + doc.save(getArtifactsDir() + "Shape.Bounds.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.Bounds.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.LINE, "Line 100002", 100.0, 100.0, 50.0, 50.0, shape); + Assert.assertEquals(msColor.getOrange().getRGB(), shape.getStrokeColor().getRGB()); + Assert.assertEquals(new RectangleF(50f, 50f, 100f, 100f), shape.getBoundsInPointsInternal()); + + group = (GroupShape)doc.getChild(NodeType.GROUP_SHAPE, 0, true); + + Assert.assertEquals(new RectangleF(0f, 100f, 250f, 250f), group.getBoundsInternal()); + Assert.assertEquals(new RectangleF(0f, 100f, 250f, 250f), group.getBoundsInPointsInternal()); + Assert.assertEquals(msSize.ctor(1000, 1000), group.getCoordSizeInternal()); + Assert.assertEquals(msPoint.ctor(0, 0), group.getCoordOriginInternal()); + + shape = (Shape)doc.getChild(NodeType.SHAPE, 1, true); + + TestUtil.verifyShape(ShapeType.RECTANGLE, "", 100.0, 100.0, 700.0, 700.0, shape); + Assert.assertEquals(new RectangleF(175f, 275f, 25f, 25f), shape.getBoundsInPointsInternal()); + + shape = (Shape)doc.getChild(NodeType.SHAPE, 2, true); + + TestUtil.verifyShape(ShapeType.RECTANGLE, "", 100.0, 100.0, 1000.0, 1000.0, shape); + Assert.assertEquals(new RectangleF(250f, 350f, 25f, 25f), shape.getBoundsInPointsInternal()); + } + + @Test + public void flipShapeOrientation() throws Exception + { + //ExStart + //ExFor:ShapeBase.FlipOrientation + //ExFor:FlipOrientation + //ExSummary:Shows how to flip a shape on an axis. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert an image shape and leave its orientation in its default state. + Shape shape = builder.insertShape(ShapeType.RECTANGLE, RelativeHorizontalPosition.LEFT_MARGIN, 100.0, + RelativeVerticalPosition.TOP_MARGIN, 100.0, 100.0, 100.0, WrapType.NONE); + shape.getImageData().setImage(getImageDir() + "Logo.jpg"); + + Assert.assertEquals(FlipOrientation.NONE, shape.getFlipOrientation()); + + shape = builder.insertShape(ShapeType.RECTANGLE, RelativeHorizontalPosition.LEFT_MARGIN, 250.0, + RelativeVerticalPosition.TOP_MARGIN, 100.0, 100.0, 100.0, WrapType.NONE); + shape.getImageData().setImage(getImageDir() + "Logo.jpg"); + + // Set the "FlipOrientation" property to "FlipOrientation.Horizontal" to flip the second shape on the y-axis, + // making it into a horizontal mirror image of the first shape. + shape.setFlipOrientation(FlipOrientation.HORIZONTAL); + + shape = builder.insertShape(ShapeType.RECTANGLE, RelativeHorizontalPosition.LEFT_MARGIN, 100.0, + RelativeVerticalPosition.TOP_MARGIN, 250.0, 100.0, 100.0, WrapType.NONE); + shape.getImageData().setImage(getImageDir() + "Logo.jpg"); + + // Set the "FlipOrientation" property to "FlipOrientation.Horizontal" to flip the third shape on the x-axis, + // making it into a vertical mirror image of the first shape. + shape.setFlipOrientation(FlipOrientation.VERTICAL); + + shape = builder.insertShape(ShapeType.RECTANGLE, RelativeHorizontalPosition.LEFT_MARGIN, 250.0, + RelativeVerticalPosition.TOP_MARGIN, 250.0, 100.0, 100.0, WrapType.NONE); + shape.getImageData().setImage(getImageDir() + "Logo.jpg"); + + // Set the "FlipOrientation" property to "FlipOrientation.Horizontal" to flip the fourth shape on both the x and y axes, + // making it into a horizontal and vertical mirror image of the first shape. + shape.setFlipOrientation(FlipOrientation.BOTH); + + doc.save(getArtifactsDir() + "Shape.FlipShapeOrientation.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.FlipShapeOrientation.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.RECTANGLE, "Rectangle 100002", 100.0, 100.0, 100.0, 100.0, shape); + Assert.assertEquals(FlipOrientation.NONE, shape.getFlipOrientation()); + + shape = (Shape)doc.getChild(NodeType.SHAPE, 1, true); + + TestUtil.verifyShape(ShapeType.RECTANGLE, "Rectangle 100004", 100.0, 100.0, 100.0, 250.0, shape); + Assert.assertEquals(FlipOrientation.HORIZONTAL, shape.getFlipOrientation()); + + shape = (Shape)doc.getChild(NodeType.SHAPE, 2, true); + + TestUtil.verifyShape(ShapeType.RECTANGLE, "Rectangle 100006", 100.0, 100.0, 250.0, 100.0, shape); + Assert.assertEquals(FlipOrientation.VERTICAL, shape.getFlipOrientation()); + + shape = (Shape)doc.getChild(NodeType.SHAPE, 3, true); + + TestUtil.verifyShape(ShapeType.RECTANGLE, "Rectangle 100008", 100.0, 100.0, 250.0, 250.0, shape); + Assert.assertEquals(FlipOrientation.BOTH, shape.getFlipOrientation()); + } + + @Test + public void fill() throws Exception + { + //ExStart + //ExFor:ShapeBase.Fill + //ExFor:Shape.FillColor + //ExFor:Shape.StrokeColor + //ExFor:Fill + //ExFor:Fill.Opacity + //ExSummary:Shows how to fill a shape with a solid color. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Write some text, and then cover it with a floating shape. + builder.getFont().setSize(32.0); + builder.writeln("Hello world!"); + + Shape shape = builder.insertShape(ShapeType.CLOUD_CALLOUT, RelativeHorizontalPosition.LEFT_MARGIN, 25.0, + RelativeVerticalPosition.TOP_MARGIN, 25.0, 250.0, 150.0, WrapType.NONE); + + // Use the "StrokeColor" property to set the color of the outline of the shape. + shape.setStrokeColor(Color.CadetBlue); + + // Use the "FillColor" property to set the color of the inside area of the shape. + shape.setFillColor(msColor.getLightBlue()); + + // The "Opacity" property determines how transparent the color is on a 0-1 scale, + // with 1 being fully opaque, and 0 being invisible. + // The shape fill by default is fully opaque, so we cannot see the text that this shape is on top of. + Assert.assertEquals(1.0d, shape.getFill().getOpacity()); + + // Set the shape fill color's opacity to a lower value so that we can see the text underneath it. + shape.getFill().setOpacity(0.3); + + doc.save(getArtifactsDir() + "Shape.Fill.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.Fill.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.CLOUD_CALLOUT, "CloudCallout 100002", 250.0d, 150.0d, 25.0d, 25.0d, shape); + Color colorWithOpacity = new Color((msColor.getLightBlue().getRed()), (msColor.getLightBlue().getGreen()), (msColor.getLightBlue().getBlue()), (Convert.toInt32(255.0 * shape.getFill().getOpacity()))); + Assert.assertEquals(colorWithOpacity.getRGB(), shape.getFillColor().getRGB()); + Assert.assertEquals(Color.CadetBlue.getRGB(), shape.getStrokeColor().getRGB()); + Assert.assertEquals(0.3d, 0.01d, shape.getFill().getOpacity()); + } + + @Test + public void textureFill() throws Exception + { + //ExStart + //ExFor:Fill.PresetTexture + //ExFor:Fill.TextureAlignment + //ExFor:TextureAlignment + //ExSummary:Shows how to fill and tiling the texture inside the shape. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 80.0, 80.0); + + // Apply texture alignment to the shape fill. + shape.getFill().presetTextured(PresetTexture.CANVAS); + shape.getFill().setTextureAlignment(TextureAlignment.TOP_RIGHT); + + // Use the compliance option to define the shape using DML if you want to get "TextureAlignment" + // property after the document saves. + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setCompliance(OoxmlCompliance.ISO_29500_2008_STRICT); } + + doc.save(getArtifactsDir() + "Shape.TextureFill.docx", saveOptions); + + doc = new Document(getArtifactsDir() + "Shape.TextureFill.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(TextureAlignment.TOP_RIGHT, shape.getFill().getTextureAlignment()); + Assert.assertEquals(PresetTexture.CANVAS, shape.getFill().getPresetTexture()); + //ExEnd + } + + @Test + public void gradientFill() throws Exception + { + //ExStart + //ExFor:Fill.OneColorGradient(Color, GradientStyle, GradientVariant, Double) + //ExFor:Fill.OneColorGradient(GradientStyle, GradientVariant, Double) + //ExFor:Fill.TwoColorGradient(Color, Color, GradientStyle, GradientVariant) + //ExFor:Fill.TwoColorGradient(GradientStyle, GradientVariant) + //ExFor:Fill.BackColor + //ExFor:Fill.GradientStyle + //ExFor:Fill.GradientVariant + //ExFor:Fill.GradientAngle + //ExFor:GradientStyle + //ExFor:GradientVariant + //ExSummary:Shows how to fill a shape with a gradients. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 80.0, 80.0); + // Apply One-color gradient fill to the shape with ForeColor of gradient fill. + shape.getFill().oneColorGradient(Color.RED, GradientStyle.HORIZONTAL, GradientVariant.VARIANT_2, 0.1); + + Assert.assertEquals(Color.RED.getRGB(), shape.getFill().getForeColor().getRGB()); + Assert.assertEquals(GradientStyle.HORIZONTAL, shape.getFill().getGradientStyle()); + Assert.assertEquals(GradientVariant.VARIANT_2, shape.getFill().getGradientVariant()); + Assert.assertEquals(270, shape.getFill().getGradientAngle()); + + shape = builder.insertShape(ShapeType.RECTANGLE, 80.0, 80.0); + // Apply Two-color gradient fill to the shape. + shape.getFill().twoColorGradient(GradientStyle.FROM_CORNER, GradientVariant.VARIANT_4); + // Change BackColor of gradient fill. + shape.getFill().setBackColor(Color.YELLOW); + // Note that changes "GradientAngle" for "GradientStyle.FromCorner/GradientStyle.FromCenter" + // gradient fill don't get any effect, it will work only for linear gradient. + shape.getFill().setGradientAngle(15.0); + + Assert.assertEquals(Color.YELLOW.getRGB(), shape.getFill().getBackColor().getRGB()); + Assert.assertEquals(GradientStyle.FROM_CORNER, shape.getFill().getGradientStyle()); + Assert.assertEquals(GradientVariant.VARIANT_4, shape.getFill().getGradientVariant()); + Assert.assertEquals(0, shape.getFill().getGradientAngle()); + + // Use the compliance option to define the shape using DML if you want to get "GradientStyle", + // "GradientVariant" and "GradientAngle" properties after the document saves. + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setCompliance(OoxmlCompliance.ISO_29500_2008_STRICT); } + + doc.save(getArtifactsDir() + "Shape.GradientFill.docx", saveOptions); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.GradientFill.docx"); + Shape firstShape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(Color.RED.getRGB(), firstShape.getFill().getForeColor().getRGB()); + Assert.assertEquals(GradientStyle.HORIZONTAL, firstShape.getFill().getGradientStyle()); + Assert.assertEquals(GradientVariant.VARIANT_2, firstShape.getFill().getGradientVariant()); + Assert.assertEquals(270, firstShape.getFill().getGradientAngle()); + + Shape secondShape = (Shape)doc.getChild(NodeType.SHAPE, 1, true); + + Assert.assertEquals(Color.YELLOW.getRGB(), secondShape.getFill().getBackColor().getRGB()); + Assert.assertEquals(GradientStyle.FROM_CORNER, secondShape.getFill().getGradientStyle()); + Assert.assertEquals(GradientVariant.VARIANT_4, secondShape.getFill().getGradientVariant()); + Assert.assertEquals(0, secondShape.getFill().getGradientAngle()); + } + + @Test + public void gradientStops() throws Exception + { + //ExStart + //ExFor:Fill.GradientStops + //ExFor:GradientStopCollection + //ExFor:GradientStopCollection.Insert(Int32, GradientStop) + //ExFor:GradientStopCollection.Add(GradientStop) + //ExFor:GradientStopCollection.RemoveAt(Int32) + //ExFor:GradientStopCollection.Remove(GradientStop) + //ExFor:GradientStopCollection.Item(Int32) + //ExFor:GradientStopCollection.Count + //ExFor:GradientStop + //ExFor:GradientStop.#ctor(Color, Double) + //ExFor:GradientStop.#ctor(Color, Double, Double) + //ExFor:GradientStop.BaseColor + //ExFor:GradientStop.Color + //ExFor:GradientStop.Position + //ExFor:GradientStop.Transparency + //ExFor:GradientStop.Remove + //ExSummary:Shows how to add gradient stops to the gradient fill. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 80.0, 80.0); + shape.getFill().twoColorGradient(msColor.getGreen(), Color.RED, GradientStyle.HORIZONTAL, GradientVariant.VARIANT_2); + + // Get gradient stops collection. + GradientStopCollection gradientStops = shape.getFill().getGradientStops(); + + // Change first gradient stop. + gradientStops.get(0).setColor(msColor.getAqua()); + gradientStops.get(0).setPosition(0.1); + gradientStops.get(0).setTransparency(0.25); + + // Add new gradient stop to the end of collection. + GradientStop gradientStop = new GradientStop(msColor.getBrown(), 0.5); + gradientStops.add(gradientStop); + + // Remove gradient stop at index 1. + gradientStops.removeAt(1); + // And insert new gradient stop at the same index 1. + gradientStops.insert(1, new GradientStop(msColor.getChocolate(), 0.75, 0.3)); + + // Remove last gradient stop in the collection. + gradientStop = gradientStops.get(2); + gradientStops.remove(gradientStop); + + Assert.assertEquals(2, gradientStops.getCount()); + + Assert.assertEquals(new Color((0), (255), (255), (255)), gradientStops.get(0).getBaseColor()); + Assert.assertEquals(msColor.getAqua().getRGB(), gradientStops.get(0).getColor().getRGB()); + Assert.assertEquals(0.1d, 0.01d, gradientStops.get(0).getPosition()); + Assert.assertEquals(0.25d, 0.01d, gradientStops.get(0).getTransparency()); + + Assert.assertEquals(msColor.getChocolate().getRGB(), gradientStops.get(1).getColor().getRGB()); + Assert.assertEquals(0.75d, 0.01d, gradientStops.get(1).getPosition()); + Assert.assertEquals(0.3d, 0.01d, gradientStops.get(1).getTransparency()); + + // Use the compliance option to define the shape using DML + // if you want to get "GradientStops" property after the document saves. + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setCompliance(OoxmlCompliance.ISO_29500_2008_STRICT); } + + doc.save(getArtifactsDir() + "Shape.GradientStops.docx", saveOptions); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.GradientStops.docx"); + + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + gradientStops = shape.getFill().getGradientStops(); + + Assert.assertEquals(2, gradientStops.getCount()); + + Assert.assertEquals(msColor.getAqua().getRGB(), gradientStops.get(0).getColor().getRGB()); + Assert.assertEquals(0.1d, 0.01d, gradientStops.get(0).getPosition()); + Assert.assertEquals(0.25d, 0.01d, gradientStops.get(0).getTransparency()); + + Assert.assertEquals(msColor.getChocolate().getRGB(), gradientStops.get(1).getColor().getRGB()); + Assert.assertEquals(0.75d, 0.01d, gradientStops.get(1).getPosition()); + Assert.assertEquals(0.3d, 0.01d, gradientStops.get(1).getTransparency()); + } + + @Test + public void fillPattern() throws Exception + { + //ExStart + //ExFor:PatternType + //ExFor:Fill.Pattern + //ExFor:Fill.Patterned(PatternType) + //ExFor:Fill.Patterned(PatternType, Color, Color) + //ExSummary:Shows how to set pattern for a shape. + Document doc = new Document(getMyDir() + "Shape stroke pattern border.docx"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + Fill fill = shape.getFill(); + + System.out.println("Pattern value is: {0}",fill.getPattern()); + + // There are several ways specified fill to a pattern. + // 1 - Apply pattern to the shape fill: + fill.patterned(PatternType.DIAGONAL_BRICK); + + // 2 - Apply pattern with foreground and background colors to the shape fill: + fill.patterned(PatternType.DIAGONAL_BRICK, msColor.getAqua(), msColor.getBisque()); + + doc.save(getArtifactsDir() + "Shape.FillPattern.docx"); + //ExEnd + } + + @Test + public void fillThemeColor() throws Exception + { + //ExStart + //ExFor:Fill.ForeThemeColor + //ExFor:Fill.BackThemeColor + //ExFor:Fill.BackTintAndShade + //ExSummary:Shows how to set theme color for foreground/background shape color. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertShape(ShapeType.ROUND_RECTANGLE, 80.0, 80.0); + + Fill fill = shape.getFill(); + fill.setForeThemeColor(ThemeColor.DARK_1); + fill.setBackThemeColor(ThemeColor.BACKGROUND_2); + + // Note: do not use "BackThemeColor" and "BackTintAndShade" for font fill. + if (fill.getBackTintAndShade() == 0) + fill.setBackTintAndShade(0.2); + + doc.save(getArtifactsDir() + "Shape.FillThemeColor.docx"); + //ExEnd + } + + @Test + public void fillTintAndShade() throws Exception + { + //ExStart + //ExFor:Fill.ForeTintAndShade + //ExSummary:Shows how to manage lightening and darkening foreground font color. + Document doc = new Document(getMyDir() + "Big document.docx"); + + Fill textFill = doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0).getFont().getFill(); + textFill.setForeThemeColor(ThemeColor.ACCENT_1); + if (textFill.getForeTintAndShade() == 0) + textFill.setForeTintAndShade(0.5); + + doc.save(getArtifactsDir() + "Shape.FillTintAndShade.docx"); + //ExEnd + } + + @Test + public void title() throws Exception + { + //ExStart + //ExFor:ShapeBase.Title + //ExSummary:Shows how to set the title of a shape. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a shape, give it a title, and then add it to the document. + Shape shape = new Shape(doc, ShapeType.CUBE); + shape.setWidth(200.0); + shape.setHeight(200.0); + shape.setTitle("My cube"); + + builder.insertNode(shape); + + // When we save a document with a shape that has a title, + // Aspose.Words will store that title in the shape's Alt Text. + doc.save(getArtifactsDir() + "Shape.Title.docx"); + + doc = new Document(getArtifactsDir() + "Shape.Title.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals("", shape.getTitle()); + Assert.assertEquals("Title: My cube", shape.getAlternativeText()); + //ExEnd + + TestUtil.verifyShape(ShapeType.CUBE, "", 200.0d, 200.0d, 0.0d, 0.0d, shape); + } + + @Test + public void replaceTextboxesWithImages() throws Exception + { + //ExStart + //ExFor:WrapSide + //ExFor:ShapeBase.WrapSide + //ExFor:NodeCollection + //ExFor:CompositeNode.InsertAfter``1(``0,Node) + //ExFor:NodeCollection.ToArray + //ExSummary:Shows how to replace all textbox shapes with image shapes. + Document doc = new Document(getMyDir() + "Textboxes in drawing canvas.docx"); + + Shape[] shapes = doc.getChildNodes(NodeType.SHAPE, true).OfType().ToArray(); + + Assert.That(shapes.Count(s => s.ShapeType == ShapeType.TextBox), assertEquals(3, ); + Assert.That(shapes.Count(s => s.ShapeType == ShapeType.Image), assertEquals(1, ); + + for (Shape shape : shapes) + { + if (shape.getShapeType() == ShapeType.TEXT_BOX) + { + Shape replacementShape = new Shape(doc, ShapeType.IMAGE); + replacementShape.getImageData().setImage(getImageDir() + "Logo.jpg"); + replacementShape.setLeft(shape.getLeft()); + replacementShape.setTop(shape.getTop()); + replacementShape.setWidth(shape.getWidth()); + replacementShape.setHeight(shape.getHeight()); + replacementShape.setRelativeHorizontalPosition(shape.getRelativeHorizontalPosition()); + replacementShape.setRelativeVerticalPosition(shape.getRelativeVerticalPosition()); + replacementShape.setHorizontalAlignment(shape.getHorizontalAlignment()); + replacementShape.setVerticalAlignment(shape.getVerticalAlignment()); + replacementShape.setWrapType(shape.getWrapType()); + replacementShape.setWrapSide(shape.getWrapSide()); + + shape.getParentNode().insertAfter(replacementShape, shape); + shape.remove(); + } + } + + shapes = doc.getChildNodes(NodeType.SHAPE, true).OfType().ToArray(); + + Assert.That(shapes.Count(s => s.ShapeType == ShapeType.TextBox), assertEquals(0, ); + Assert.That(shapes.Count(s => s.ShapeType == ShapeType.Image), assertEquals(4, ); + + doc.save(getArtifactsDir() + "Shape.ReplaceTextboxesWithImages.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.ReplaceTextboxesWithImages.docx"); + Shape outShape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(WrapSide.BOTH, outShape.getWrapSide()); + } + + @Test + public void createTextBox() throws Exception + { + //ExStart + //ExFor:Shape.#ctor(DocumentBase, ShapeType) + //ExFor:Story.FirstParagraph + //ExFor:Shape.FirstParagraph + //ExFor:ShapeBase.WrapType + //ExSummary:Shows how to create and format a text box. + Document doc = new Document(); + + // Create a floating text box. + Shape textBox = new Shape(doc, ShapeType.TEXT_BOX); + textBox.setWrapType(WrapType.NONE); + textBox.setHeight(50.0); + textBox.setWidth(200.0); + + // Set the horizontal, and vertical alignment of the text inside the shape. + textBox.setHorizontalAlignment(HorizontalAlignment.CENTER); + textBox.setVerticalAlignment(VerticalAlignment.TOP); + + // Add a paragraph to the text box and add a run of text that the text box will display. + textBox.appendChild(new Paragraph(doc)); + Paragraph para = textBox.getFirstParagraph(); + para.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + Run run = new Run(doc); + run.setText("Hello world!"); + para.appendChild(run); + + doc.getFirstSection().getBody().getFirstParagraph().appendChild(textBox); + + doc.save(getArtifactsDir() + "Shape.CreateTextBox.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.CreateTextBox.docx"); + textBox = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.TEXT_BOX, "", 200.0d, 50.0d, 0.0d, 0.0d, textBox); + Assert.assertEquals(WrapType.NONE, textBox.getWrapType()); + Assert.assertEquals(HorizontalAlignment.CENTER, textBox.getHorizontalAlignment()); + Assert.assertEquals(VerticalAlignment.TOP, textBox.getVerticalAlignment()); + Assert.assertEquals("Hello world!", textBox.getText().trim()); + } + + @Test + public void zOrder() throws Exception + { + //ExStart + //ExFor:ShapeBase.ZOrder + //ExSummary:Shows how to manipulate the order of shapes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert three different colored rectangles that partially overlap each other. + // When we insert a shape that overlaps another shape, Aspose.Words places the newer shape on top of the old one. + // The light green rectangle will overlap the light blue rectangle and partially obscure it, + // and the light blue rectangle will obscure the orange rectangle. + Shape shape = builder.insertShape(ShapeType.RECTANGLE, RelativeHorizontalPosition.LEFT_MARGIN, 100.0, + RelativeVerticalPosition.TOP_MARGIN, 100.0, 200.0, 200.0, WrapType.NONE); + shape.setFillColor(msColor.getOrange()); + + shape = builder.insertShape(ShapeType.RECTANGLE, RelativeHorizontalPosition.LEFT_MARGIN, 150.0, + RelativeVerticalPosition.TOP_MARGIN, 150.0, 200.0, 200.0, WrapType.NONE); + shape.setFillColor(msColor.getLightBlue()); + + shape = builder.insertShape(ShapeType.RECTANGLE, RelativeHorizontalPosition.LEFT_MARGIN, 200.0, + RelativeVerticalPosition.TOP_MARGIN, 200.0, 200.0, 200.0, WrapType.NONE); + shape.setFillColor(msColor.getLightGreen()); + + Shape[] shapes = doc.getChildNodes(NodeType.SHAPE, true).OfType().ToArray(); + + // The "ZOrder" property of a shape determines its stacking priority among other overlapping shapes. + // If two overlapping shapes have different "ZOrder" values, + // Microsoft Word will place the shape with a higher value over the shape with the lower value. + // Set the "ZOrder" values of our shapes to place the first orange rectangle over the second light blue one + // and the second light blue rectangle over the third light green rectangle. + // This will reverse their original stacking order. + shapes[0].setZOrder(3); + shapes[1].setZOrder(2); + shapes[2].setZOrder(1); + + doc.save(getArtifactsDir() + "Shape.ZOrder.docx"); + //ExEnd + } + + @Test + public void getActiveXControlProperties() throws Exception + { + //ExStart + //ExFor:OleControl + //ExFor:OleControl.IsForms2OleControl + //ExFor:OleControl.Name + //ExFor:OleFormat.OleControl + //ExFor:Forms2OleControl + //ExFor:Forms2OleControl.Caption + //ExFor:Forms2OleControl.Value + //ExFor:Forms2OleControl.Enabled + //ExFor:Forms2OleControl.Type + //ExFor:Forms2OleControl.ChildNodes + //ExFor:Forms2OleControl.GroupName + //ExSummary:Shows how to verify the properties of an ActiveX control. + Document doc = new Document(getMyDir() + "ActiveX controls.docx"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + OleControl oleControl = shape.getOleFormat().getOleControl(); + + Assert.assertEquals("CheckBox1", oleControl.getName()); + + if (oleControl.isForms2OleControl()) + { + Forms2OleControl checkBox = (Forms2OleControl)oleControl; + Assert.assertEquals("First", checkBox.getCaption()); + Assert.assertEquals("0", checkBox.getValue()); + Assert.assertEquals(true, checkBox.getEnabled()); + Assert.assertEquals(Forms2OleControlType.CHECK_BOX, checkBox.getType()); + Assert.assertEquals(null, checkBox.getChildNodes()); + Assert.assertEquals("", checkBox.getGroupName()); + + // Note, that you can't set GroupName for a Frame. + checkBox.setGroupName("Aspose group name"); + } + //ExEnd + + doc.save(getArtifactsDir() + "Shape.GetActiveXControlProperties.docx"); + doc = new Document(getArtifactsDir() + "Shape.GetActiveXControlProperties.docx"); + + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + Forms2OleControl forms2OleControl = (Forms2OleControl)shape.getOleFormat().getOleControl(); + + Assert.assertEquals("Aspose group name", forms2OleControl.getGroupName()); + } + + @Test + public void getOleObjectRawData() throws Exception + { + //ExStart + //ExFor:OleFormat.GetRawData + //ExSummary:Shows how to access the raw data of an embedded OLE object. + Document doc = new Document(getMyDir() + "OLE objects.docx"); + + for (Shape shape : (Iterable) doc.getChildNodes(NodeType.SHAPE, true)) + { + OleFormat oleFormat = shape.getOleFormat(); + if (oleFormat != null) + { + System.out.println("This is {(oleFormat.IsLink ? "); + byte[] oleRawData = oleFormat.getRawData(); + + Assert.assertEquals(24576, oleRawData.length); + } + } + //ExEnd + } + + @Test + public void linkedChartSourceFullName() throws Exception + { + //ExStart + //ExFor:Chart.SourceFullName + //ExSummary:Shows how to get/set the full name of the external xls/xlsx document if the chart is linked. + Document doc = new Document(getMyDir() + "Shape with linked chart.docx"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + String sourceFullName = shape.getChart().getSourceFullName(); + Assert.assertTrue(sourceFullName.contains("Examples\\Data\\Spreadsheet.xlsx")); + //ExEnd + } + + @Test + public void oleControl() throws Exception + { + //ExStart + //ExFor:OleFormat + //ExFor:OleFormat.AutoUpdate + //ExFor:OleFormat.IsLocked + //ExFor:OleFormat.ProgId + //ExFor:OleFormat.Save(Stream) + //ExFor:OleFormat.Save(String) + //ExFor:OleFormat.SuggestedExtension + //ExSummary:Shows how to extract embedded OLE objects into files. + Document doc = new Document(getMyDir() + "OLE spreadsheet.docm"); + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + // The OLE object in the first shape is a Microsoft Excel spreadsheet. + OleFormat oleFormat = shape.getOleFormat(); + + Assert.assertEquals("Excel.Sheet.12", oleFormat.getProgId()); + + // Our object is neither auto updating nor locked from updates. + Assert.assertFalse(oleFormat.getAutoUpdate()); + Assert.assertEquals(false, oleFormat.isLocked()); + + // If we plan on saving the OLE object to a file in the local file system, + // we can use the "SuggestedExtension" property to determine which file extension to apply to the file. + Assert.assertEquals(".xlsx", oleFormat.getSuggestedExtension()); + + // Below are two ways of saving an OLE object to a file in the local file system. + // 1 - Save it via a stream: + FileStream fs = new FileStream(getArtifactsDir() + "OLE spreadsheet extracted via stream" + oleFormat.getSuggestedExtension(), FileMode.CREATE); + try /*JAVA: was using*/ + { + oleFormat.save(fs); + } + finally { if (fs != null) fs.close(); } + + // 2 - Save it directly to a filename: + oleFormat.save(getArtifactsDir() + "OLE spreadsheet saved directly" + oleFormat.getSuggestedExtension()); + //ExEnd + + Assert.assertTrue(new FileInfo(getArtifactsDir() + "OLE spreadsheet extracted via stream.xlsx").getLength() < 8400); + Assert.assertTrue(new FileInfo(getArtifactsDir() + "OLE spreadsheet saved directly.xlsx").getLength() < 8400); + } + + @Test + public void oleLinks() throws Exception + { + //ExStart + //ExFor:OleFormat.IconCaption + //ExFor:OleFormat.GetOleEntry(String) + //ExFor:OleFormat.IsLink + //ExFor:OleFormat.OleIcon + //ExFor:OleFormat.SourceFullName + //ExFor:OleFormat.SourceItem + //ExSummary:Shows how to insert linked and unlinked OLE objects. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Embed a Microsoft Visio drawing into the document as an OLE object. + builder.insertOleObjectInternal(getImageDir() + "Microsoft Visio drawing.vsd", "Package", false, false, null); + + // Insert a link to the file in the local file system and display it as an icon. + builder.insertOleObjectInternal(getImageDir() + "Microsoft Visio drawing.vsd", "Package", true, true, null); + + // Inserting OLE objects creates shapes that store these objects. + Shape[] shapes = doc.getChildNodes(NodeType.SHAPE, true).OfType().ToArray(); + + Assert.assertEquals(2, shapes.length); + Assert.That(shapes.Count(s => s.ShapeType == ShapeType.OleObject), assertEquals(2, ); + + // If a shape contains an OLE object, it will have a valid "OleFormat" property, + // which we can use to verify some aspects of the shape. + OleFormat oleFormat = shapes[0].getOleFormat(); + + Assert.assertEquals(false, oleFormat.isLink()); + Assert.assertEquals(false, oleFormat.getOleIcon()); + + oleFormat = shapes[1].getOleFormat(); + + Assert.assertEquals(true, oleFormat.isLink()); + Assert.assertEquals(true, oleFormat.getOleIcon()); + + Assert.assertTrue(oleFormat.getSourceFullName().endsWith("Images" + Path.DirectorySeparatorChar + "Microsoft Visio drawing.vsd")); + Assert.assertEquals("", oleFormat.getSourceItem()); + + Assert.assertEquals("Microsoft Visio drawing.vsd", oleFormat.getIconCaption()); + + doc.save(getArtifactsDir() + "Shape.OleLinks.docx"); + + // If the object contains OLE data, we can access it using a stream. + MemoryStream stream = oleFormat.getOleEntryInternal("\u0001CompObj"); + try /*JAVA: was using*/ + { + byte[] oleEntryBytes = stream.toArray(); + Assert.assertEquals(76, oleEntryBytes.length); + } + finally { if (stream != null) stream.close(); } + //ExEnd + } + + @Test + public void oleControlCollection() throws Exception + { + //ExStart + //ExFor:OleFormat.Clsid + //ExFor:Forms2OleControlCollection + //ExFor:Forms2OleControlCollection.Count + //ExFor:Forms2OleControlCollection.Item(Int32) + //ExSummary:Shows how to access an OLE control embedded in a document and its child controls. + Document doc = new Document(getMyDir() + "OLE ActiveX controls.docm"); + + // Shapes store and display OLE objects in the document's body. + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals("6e182020-f460-11ce-9bcd-00aa00608e01", shape.getOleFormat().getClsidInternal().toString()); + + Forms2OleControl oleControl = (Forms2OleControl)shape.getOleFormat().getOleControl(); + + // Some OLE controls may contain child controls, such as the one in this document with three options buttons. + Forms2OleControlCollection oleControlCollection = oleControl.getChildNodes(); + + Assert.assertEquals(3, oleControlCollection.getCount()); + + Assert.assertEquals("C#", oleControlCollection.get(0).getCaption()); + Assert.assertEquals("1", oleControlCollection.get(0).getValue()); + + Assert.assertEquals("Visual Basic", oleControlCollection.get(1).getCaption()); + Assert.assertEquals("0", oleControlCollection.get(1).getValue()); + + Assert.assertEquals("Delphi", oleControlCollection.get(2).getCaption()); + Assert.assertEquals("0", oleControlCollection.get(2).getValue()); + //ExEnd + } + + @Test + public void suggestedFileName() throws Exception + { + //ExStart + //ExFor:OleFormat.SuggestedFileName + //ExSummary:Shows how to get an OLE object's suggested file name. + Document doc = new Document(getMyDir() + "OLE shape.rtf"); + + Shape oleShape = (Shape)doc.getFirstSection().getBody().getChild(NodeType.SHAPE, 0, true); + + // OLE objects can provide a suggested filename and extension, + // which we can use when saving the object's contents into a file in the local file system. + String suggestedFileName = oleShape.getOleFormat().getSuggestedFileName(); + + Assert.assertEquals("CSV.csv", suggestedFileName); + + FileStream fileStream = new FileStream(getArtifactsDir() + suggestedFileName, FileMode.CREATE); + try /*JAVA: was using*/ + { + oleShape.getOleFormat().save(fileStream); + } + finally { if (fileStream != null) fileStream.close(); } + //ExEnd + } + + @Test + public void objectDidNotHaveSuggestedFileName() throws Exception + { + Document doc = new Document(getMyDir() + "ActiveX controls.docx"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + Assert.assertEquals("", shape.getOleFormat().getSuggestedFileName()); + } + + @Test + public void renderOfficeMath() throws Exception + { + //ExStart + //ExFor:ImageSaveOptions.Scale + //ExFor:OfficeMath.GetMathRenderer + //ExFor:NodeRendererBase.Save(String, ImageSaveOptions) + //ExSummary:Shows how to render an Office Math object into an image file in the local file system. + Document doc = new Document(getMyDir() + "Office math.docx"); + + OfficeMath math = (OfficeMath)doc.getChild(NodeType.OFFICE_MATH, 0, true); + + // Create an "ImageSaveOptions" object to pass to the node renderer's "Save" method to modify + // how it renders the OfficeMath node into an image. + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.PNG); + + // Set the "Scale" property to 5 to render the object to five times its original size. + saveOptions.setScale(5f); + + math.getMathRenderer().save(getArtifactsDir() + "Shape.RenderOfficeMath.png", saveOptions); + //ExEnd + if (isRunningOnMono()) + TestUtil.verifyImage(735, 128, getArtifactsDir() + "Shape.RenderOfficeMath.png"); + else + TestUtil.verifyImage(813, 87, getArtifactsDir() + "Shape.RenderOfficeMath.png"); + } + + @Test + public void officeMathDisplayException() throws Exception + { + Document doc = new Document(getMyDir() + "Office math.docx"); + + OfficeMath officeMath = (OfficeMath)doc.getChild(NodeType.OFFICE_MATH, 0, true); + officeMath.setDisplayType(OfficeMathDisplayType.DISPLAY); + + Assert.Throws(() => officeMath.setJustification(OfficeMathJustification.INLINE)); + } + + @Test + public void officeMathDefaultValue() throws Exception + { + Document doc = new Document(getMyDir() + "Office math.docx"); + + OfficeMath officeMath = (OfficeMath)doc.getChild(NodeType.OFFICE_MATH, 6, true); + + Assert.assertEquals(OfficeMathDisplayType.INLINE, officeMath.getDisplayType()); + Assert.assertEquals(OfficeMathJustification.INLINE, officeMath.getJustification()); + } + + @Test + public void officeMath() throws Exception + { + //ExStart + //ExFor:OfficeMath + //ExFor:OfficeMath.DisplayType + //ExFor:OfficeMath.Justification + //ExFor:OfficeMath.NodeType + //ExFor:OfficeMath.ParentParagraph + //ExFor:OfficeMathDisplayType + //ExFor:OfficeMathJustification + //ExSummary:Shows how to set office math display formatting. + Document doc = new Document(getMyDir() + "Office math.docx"); + + OfficeMath officeMath = (OfficeMath)doc.getChild(NodeType.OFFICE_MATH, 0, true); + + // OfficeMath nodes that are children of other OfficeMath nodes are always inline. + // The node we are working with is the base node to change its location and display type. + Assert.assertEquals(MathObjectType.O_MATH_PARA, officeMath.getMathObjectType()); + Assert.assertEquals(NodeType.OFFICE_MATH, officeMath.getNodeType()); + Assert.assertEquals(officeMath.getParentNode(), officeMath.getParentParagraph()); + + // Change the location and display type of the OfficeMath node. + officeMath.setDisplayType(OfficeMathDisplayType.DISPLAY); + officeMath.setJustification(OfficeMathJustification.LEFT); + + doc.save(getArtifactsDir() + "Shape.OfficeMath.docx"); + //ExEnd + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "Shape.OfficeMath.docx", getGoldsDir() + "Shape.OfficeMath Gold.docx")); + } + + @Test + public void cannotBeSetDisplayWithInlineJustification() throws Exception + { + Document doc = new Document(getMyDir() + "Office math.docx"); + + OfficeMath officeMath = (OfficeMath)doc.getChild(NodeType.OFFICE_MATH, 0, true); + officeMath.setDisplayType(OfficeMathDisplayType.DISPLAY); + + Assert.Throws(() => officeMath.setJustification(OfficeMathJustification.INLINE)); + } + + @Test + public void cannotBeSetInlineDisplayWithJustification() throws Exception + { + Document doc = new Document(getMyDir() + "Office math.docx"); + + OfficeMath officeMath = (OfficeMath)doc.getChild(NodeType.OFFICE_MATH, 0, true); + officeMath.setDisplayType(OfficeMathDisplayType.INLINE); + + Assert.Throws(() => officeMath.setJustification(OfficeMathJustification.CENTER)); + } + + @Test + public void officeMathDisplayNestedObjects() throws Exception + { + Document doc = new Document(getMyDir() + "Office math.docx"); + + OfficeMath officeMath = (OfficeMath)doc.getChild(NodeType.OFFICE_MATH, 0, true); + + Assert.assertEquals(OfficeMathDisplayType.DISPLAY, officeMath.getDisplayType()); + Assert.assertEquals(OfficeMathJustification.CENTER, officeMath.getJustification()); + } + + @Test (dataProvider = "workWithMathObjectTypeDataProvider") + public void workWithMathObjectType(int index, /*MathObjectType*/int objectType) throws Exception + { + Document doc = new Document(getMyDir() + "Office math.docx"); + + OfficeMath officeMath = (OfficeMath)doc.getChild(NodeType.OFFICE_MATH, index, true); + Assert.assertEquals(objectType, officeMath.getMathObjectType()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "workWithMathObjectTypeDataProvider") + public static Object[][] workWithMathObjectTypeDataProvider() throws Exception + { + return new Object[][] + { + {0, MathObjectType.O_MATH_PARA}, + {1, MathObjectType.O_MATH}, + {2, MathObjectType.SUPERCRIPT}, + {3, MathObjectType.ARGUMENT}, + {4, MathObjectType.SUPERSCRIPT_PART}, + }; + } + + @Test (dataProvider = "aspectRatioDataProvider") + public void aspectRatio(boolean lockAspectRatio) throws Exception + { + //ExStart + //ExFor:ShapeBase.AspectRatioLocked + //ExSummary:Shows how to lock/unlock a shape's aspect ratio. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a shape. If we open this document in Microsoft Word, we can left click the shape to reveal + // eight sizing handles around its perimeter, which we can click and drag to change its size. + Shape shape = builder.insertImage(getImageDir() + "Logo.jpg"); + + // Set the "AspectRatioLocked" property to "true" to preserve the shape's aspect ratio + // when using any of the four diagonal sizing handles, which change both the image's height and width. + // Using any orthogonal sizing handles that either change the height or width will still change the aspect ratio. + // Set the "AspectRatioLocked" property to "false" to allow us to + // freely change the image's aspect ratio with all sizing handles. + shape.setAspectRatioLocked(lockAspectRatio); + + doc.save(getArtifactsDir() + "Shape.AspectRatio.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.AspectRatio.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(lockAspectRatio, shape.getAspectRatioLocked()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "aspectRatioDataProvider") + public static Object[][] aspectRatioDataProvider() throws Exception + { + return new Object[][] + { + {true}, + {false}, + }; + } + + @Test + public void markupLanguageByDefault() throws Exception + { + //ExStart + //ExFor:ShapeBase.MarkupLanguage + //ExFor:ShapeBase.SizeInPoints + //ExSummary:Shows how to verify a shape's size and markup language. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertImage(getImageDir() + "Transparent background logo.png"); + + Assert.assertEquals(ShapeMarkupLanguage.DML, shape.getMarkupLanguage()); + Assert.assertEquals(msSizeF.ctor(300f, 300f), shape.getSizeInPointsInternal()); + //ExEnd + } + + @Test (dataProvider = "markupLanguageForDifferentMsWordVersionsDataProvider") + public void markupLanguageForDifferentMsWordVersions(/*MsWordVersion*/int msWordVersion, + /*ShapeMarkupLanguage*/byte shapeMarkupLanguage) throws Exception + { + Document doc = new Document(); + doc.getCompatibilityOptions().optimizeFor(msWordVersion); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertImage(getImageDir() + "Transparent background logo.png"); + + for (Shape shape : doc.getChildNodes(NodeType.SHAPE, true).OfType() !!Autoporter error: Undefined expression type ) + { + Assert.assertEquals(shapeMarkupLanguage, shape.getMarkupLanguage()); + } + } + + //JAVA-added data provider for test method + @DataProvider(name = "markupLanguageForDifferentMsWordVersionsDataProvider") + public static Object[][] markupLanguageForDifferentMsWordVersionsDataProvider() throws Exception + { + return new Object[][] + { + {MsWordVersion.WORD_2000, ShapeMarkupLanguage.VML}, + {MsWordVersion.WORD_2002, ShapeMarkupLanguage.VML}, + {MsWordVersion.WORD_2003, ShapeMarkupLanguage.VML}, + {MsWordVersion.WORD_2007, ShapeMarkupLanguage.VML}, + {MsWordVersion.WORD_2010, ShapeMarkupLanguage.DML}, + {MsWordVersion.WORD_2013, ShapeMarkupLanguage.DML}, + {MsWordVersion.WORD_2016, ShapeMarkupLanguage.DML}, + }; + } + + @Test + public void stroke() throws Exception + { + //ExStart + //ExFor:Stroke + //ExFor:Stroke.On + //ExFor:Stroke.Weight + //ExFor:Stroke.JoinStyle + //ExFor:Stroke.LineStyle + //ExFor:Stroke.Fill + //ExFor:ShapeLineStyle + //ExSummary:Shows how change stroke properties. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertShape(ShapeType.RECTANGLE, RelativeHorizontalPosition.LEFT_MARGIN, 100.0, + RelativeVerticalPosition.TOP_MARGIN, 100.0, 200.0, 200.0, WrapType.NONE); + + // Basic shapes, such as the rectangle, have two visible parts. + // 1 - The fill, which applies to the area within the outline of the shape: + shape.getFill().setForeColor(Color.WHITE); + + // 2 - The stroke, which marks the outline of the shape: + // Modify various properties of this shape's stroke. + Stroke stroke = shape.getStroke(); + stroke.setOn(true); + stroke.setWeight(5.0); + stroke.setColor(Color.RED); + stroke.setDashStyle(DashStyle.SHORT_DASH_DOT_DOT); + stroke.setJoinStyle(JoinStyle.MITER); + stroke.setEndCap(EndCap.SQUARE); + stroke.setLineStyle(ShapeLineStyle.TRIPLE); + stroke.getFill().twoColorGradient(Color.RED, Color.BLUE, GradientStyle.VERTICAL, GradientVariant.VARIANT_1); + + doc.save(getArtifactsDir() + "Shape.Stroke.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.Stroke.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + stroke = shape.getStroke(); + + Assert.assertEquals(true, stroke.getOn()); + Assert.assertEquals(5, stroke.getWeight()); + Assert.assertEquals(Color.RED.getRGB(), stroke.getColor().getRGB()); + Assert.assertEquals(DashStyle.SHORT_DASH_DOT_DOT, stroke.getDashStyle()); + Assert.assertEquals(JoinStyle.MITER, stroke.getJoinStyle()); + Assert.assertEquals(EndCap.SQUARE, stroke.getEndCap()); + Assert.assertEquals(ShapeLineStyle.TRIPLE, stroke.getLineStyle()); + } + + @Test (description = "WORDSNET-16067") + public void insertOleObjectAsHtmlFile() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertOleObjectInternal("http://www.aspose.com", "htmlfile", true, false, null); + + doc.save(getArtifactsDir() + "Shape.InsertOleObjectAsHtmlFile.docx"); + } + + @Test (description = "WORDSNET-16085") + public void insertOlePackage() throws Exception + { + //ExStart + //ExFor:OlePackage + //ExFor:OleFormat.OlePackage + //ExFor:OlePackage.FileName + //ExFor:OlePackage.DisplayName + //ExSummary:Shows how insert an OLE object into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // OLE objects allow us to open other files in the local file system using another installed application + // in our operating system by double-clicking on the shape that contains the OLE object in the document body. + // In this case, our external file will be a ZIP archive. + byte[] zipFileBytes = File.readAllBytes(getDatabaseDir() + "cat001.zip"); + + MemoryStream stream = new MemoryStream(zipFileBytes); + try /*JAVA: was using*/ + { + Shape shape = builder.insertOleObjectInternal(stream, "Package", true, null); + + shape.getOleFormat().getOlePackage().setFileName("Package file name.zip"); + shape.getOleFormat().getOlePackage().setDisplayName("Package display name.zip"); + } + finally { if (stream != null) stream.close(); } + + doc.save(getArtifactsDir() + "Shape.InsertOlePackage.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.InsertOlePackage.docx"); + Shape getShape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals("Package file name.zip", getShape.getOleFormat().getOlePackage().getFileName()); + Assert.assertEquals("Package display name.zip", getShape.getOleFormat().getOlePackage().getDisplayName()); + } + + @Test + public void getAccessToOlePackage() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape oleObject = builder.insertOleObjectInternal(getMyDir() + "Spreadsheet.xlsx", false, false, null); + Shape oleObjectAsOlePackage = + builder.insertOleObjectInternal(getMyDir() + "Spreadsheet.xlsx", "Excel.Sheet", false, false, null); + + Assert.assertEquals(null, oleObject.getOleFormat().getOlePackage()); + Assert.assertEquals(OlePackage.class, oleObjectAsOlePackage.getOleFormat().getOlePackage().getClass()); + } + + @Test + public void resize() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 200.0, 300.0); + shape.setHeight(300.0); + shape.setWidth(500.0); + shape.setRotation(30.0); + + doc.save(getArtifactsDir() + "Shape.Resize.docx"); + } + + @Test + public void calendar() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startTable(); + builder.getRowFormat().setHeight(100.0); + builder.getRowFormat().setHeightRule(HeightRule.EXACTLY); + + for (int i = 0; i < 31; i++) + { + if (i != 0 && i % 7 == 0) builder.endRow(); + builder.insertCell(); + builder.write("Cell contents"); + } + + builder.endTable(); + + NodeCollection runs = doc.getChildNodes(NodeType.RUN, true); + int num = 1; + + for (Run run : runs.OfType() !!Autoporter error: Undefined expression type ) + { + Shape watermark = new Shape(doc, ShapeType.TEXT_PLAIN_TEXT); + { + watermark.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE); + watermark.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE); + watermark.setWidth(30.0); + watermark.setHeight(30.0); + watermark.setHorizontalAlignment(HorizontalAlignment.CENTER); + watermark.setVerticalAlignment(VerticalAlignment.CENTER); + watermark.setRotation(-40); + } + + + watermark.getFill().setForeColor(Color.Gainsboro); + watermark.setStrokeColor(Color.Gainsboro); + + watermark.getTextPath().setText(MessageFormat.format("{0}", num)); + watermark.getTextPath().setFontFamily("Arial"); + + watermark.setName("Watermark_{num++}"); + + watermark.setBehindText(true); + + builder.moveTo(run); + builder.insertNode(watermark); + } + + doc.save(getArtifactsDir() + "Shape.Calendar.docx"); + + doc = new Document(getArtifactsDir() + "Shape.Calendar.docx"); + ArrayList shapes = doc.getChildNodes(NodeType.SHAPE, true).Cast().ToList(); + + Assert.assertEquals(31, shapes.size()); + + for (Shape shape : shapes) + TestUtil.verifyShape(ShapeType.TEXT_PLAIN_TEXT, $"Watermark_{shapes.IndexOf(shape) + 1}", + 30.0d, 30.0d, 0.0d, 0.0d, shape); + } + + @Test (dataProvider = "isLayoutInCellDataProvider") + public void isLayoutInCell(boolean isLayoutInCell) throws Exception + { + //ExStart + //ExFor:ShapeBase.IsLayoutInCell + //ExSummary:Shows how to determine how to display a shape in a table cell. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + builder.insertCell(); + builder.endTable(); + + TableStyle tableStyle = (TableStyle)doc.getStyles().add(StyleType.TABLE, "MyTableStyle1"); + tableStyle.setBottomPadding(20.0); + tableStyle.setLeftPadding(10.0); + tableStyle.setRightPadding(10.0); + tableStyle.setTopPadding(20.0); + tableStyle.getBorders().setColor(Color.BLACK); + tableStyle.getBorders().setLineStyle(LineStyle.SINGLE); + + table.setStyle(tableStyle); + + builder.moveTo(table.getFirstRow().getFirstCell().getFirstParagraph()); + + Shape shape = builder.insertShape(ShapeType.RECTANGLE, RelativeHorizontalPosition.LEFT_MARGIN, 50.0, + RelativeVerticalPosition.TOP_MARGIN, 100.0, 100.0, 100.0, WrapType.NONE); + + // Set the "IsLayoutInCell" property to "true" to display the shape as an inline element inside the cell's paragraph. + // The coordinate origin that will determine the shape's location will be the top left corner of the shape's cell. + // If we re-size the cell, the shape will move to maintain the same position starting from the cell's top left. + // Set the "IsLayoutInCell" property to "false" to display the shape as an independent floating shape. + // The coordinate origin that will determine the shape's location will be the top left corner of the page, + // and the shape will not respond to any re-sizing of its cell. + shape.isLayoutInCell(isLayoutInCell); + + // We can only apply the "IsLayoutInCell" property to floating shapes. + shape.setWrapType(WrapType.NONE); + + doc.save(getArtifactsDir() + "Shape.LayoutInTableCell.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.LayoutInTableCell.docx"); + table = doc.getFirstSection().getBody().getTables().get(0); + shape = (Shape)table.getFirstRow().getFirstCell().getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(isLayoutInCell, shape.isLayoutInCell()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "isLayoutInCellDataProvider") + public static Object[][] isLayoutInCellDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void shapeInsertion() throws Exception + { + //ExStart + //ExFor:DocumentBuilder.InsertShape(ShapeType, RelativeHorizontalPosition, double, RelativeVerticalPosition, double, double, double, WrapType) + //ExFor:DocumentBuilder.InsertShape(ShapeType, double, double) + //ExFor:OoxmlCompliance + //ExFor:OoxmlSaveOptions.Compliance + //ExSummary:Shows how to insert DML shapes into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are two wrapping types that shapes may have. + // 1 - Floating: + builder.insertShape(ShapeType.TOP_CORNERS_ROUNDED, RelativeHorizontalPosition.PAGE, 100.0, + RelativeVerticalPosition.PAGE, 100.0, 50.0, 50.0, WrapType.NONE); + + // 2 - Inline: + builder.insertShape(ShapeType.DIAGONAL_CORNERS_ROUNDED, 50.0, 50.0); + + // If you need to create "non-primitive" shapes, such as SingleCornerSnipped, TopCornersSnipped, DiagonalCornersSnipped, + // TopCornersOneRoundedOneSnipped, SingleCornerRounded, TopCornersRounded, or DiagonalCornersRounded, + // then save the document with "Strict" or "Transitional" compliance, which allows saving shape as DML. + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(SaveFormat.DOCX); + saveOptions.setCompliance(OoxmlCompliance.ISO_29500_2008_TRANSITIONAL); + + doc.save(getArtifactsDir() + "Shape.ShapeInsertion.docx", saveOptions); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.ShapeInsertion.docx"); + ArrayList shapes = doc.getChildNodes(NodeType.SHAPE, true).Cast().ToList(); + + TestUtil.verifyShape(ShapeType.TOP_CORNERS_ROUNDED, "TopCornersRounded 100002", 50.0d, 50.0d, 100.0d, 100.0d, shapes.get(0)); + TestUtil.verifyShape(ShapeType.DIAGONAL_CORNERS_ROUNDED, "DiagonalCornersRounded 100004", 50.0d, 50.0d, 0.0d, 0.0d, shapes.get(1)); + } + + //ExStart + //ExFor:Shape.Accept(DocumentVisitor) + //ExFor:Shape.AcceptStart(DocumentVisitor) + //ExFor:Shape.AcceptEnd(DocumentVisitor) + //ExFor:Shape.Chart + //ExFor:Shape.ExtrusionEnabled + //ExFor:Shape.Filled + //ExFor:Shape.HasChart + //ExFor:Shape.OleFormat + //ExFor:Shape.ShadowEnabled + //ExFor:Shape.StoryType + //ExFor:Shape.StrokeColor + //ExFor:Shape.Stroked + //ExFor:Shape.StrokeWeight + //ExSummary:Shows how to iterate over all the shapes in a document. + @Test //ExSkip + public void visitShapes() throws Exception + { + Document doc = new Document(getMyDir() + "Revision shape.docx"); + Assert.assertEquals(2, doc.getChildNodes(NodeType.SHAPE, true).getCount()); //ExSkip + + ShapeAppearancePrinter visitor = new ShapeAppearancePrinter(); + doc.accept(visitor); + + System.out.println(visitor.getText()); + } + + /// + /// Logs appearance-related information about visited shapes. + /// + private static class ShapeAppearancePrinter extends DocumentVisitor + { + public ShapeAppearancePrinter() + { + mShapesVisited = 0; + mTextIndentLevel = 0; + mStringBuilder = new StringBuilder(); + } + + /// + /// Appends a line to the StringBuilder with one prepended tab character for each indent level. + /// + private void appendLine(String text) + { + for (int i = 0; i < mTextIndentLevel; i++) mStringBuilder.append('\t'); + + msStringBuilder.appendLine(mStringBuilder, text); + } + + /// + /// Return all the text that the StringBuilder has accumulated. + /// + public String getText() + { + return $"Shapes visited: {mShapesVisited}\n{mStringBuilder}"; + } + + /// + /// Called when this visitor visits the start of a Shape node. + /// + public /*override*/ /*VisitorAction*/int visitShapeStart(Shape shape) + { + appendLine($"Shape found: {shape.ShapeType}"); + + mTextIndentLevel++; + + if (shape.hasChart()) + appendLine($"Has chart: {shape.Chart.Title.Text}"); + + appendLine($"Extrusion enabled: {shape.ExtrusionEnabled}"); + appendLine($"Shadow enabled: {shape.ShadowEnabled}"); + appendLine($"StoryType: {shape.StoryType}"); + + if (shape.getStroked()) + { + Assert.assertEquals(shape.getStroke().getColor(), shape.getStrokeColor()); + appendLine($"Stroke colors: {shape.Stroke.Color}, {shape.Stroke.Color2}"); + appendLine($"Stroke weight: {shape.StrokeWeight}"); + } + + if (shape.getFilled()) + appendLine($"Filled: {shape.FillColor}"); + + if (shape.getOleFormat() != null) + appendLine($"Ole found of type: {shape.OleFormat.ProgId}"); + + if (shape.getSignatureLine() != null) + appendLine($"Found signature line for: {shape.SignatureLine.Signer}, {shape.SignatureLine.SignerTitle}"); + + return VisitorAction.CONTINUE; + } + + /// + /// Called when this visitor visits the end of a Shape node. + /// + public /*override*/ /*VisitorAction*/int visitShapeEnd(Shape shape) + { + mTextIndentLevel--; + mShapesVisited++; + appendLine($"End of {shape.ShapeType}"); + + return VisitorAction.CONTINUE; + } + + /// + /// Called when this visitor visits the start of a GroupShape node. + /// + public /*override*/ /*VisitorAction*/int visitGroupShapeStart(GroupShape groupShape) + { + appendLine($"Shape group found: {groupShape.ShapeType}"); + mTextIndentLevel++; + + return VisitorAction.CONTINUE; + } + + /// + /// Called when this visitor visits the end of a GroupShape node. + /// + public /*override*/ /*VisitorAction*/int visitGroupShapeEnd(GroupShape groupShape) + { + mTextIndentLevel--; + appendLine($"End of {groupShape.ShapeType}"); + + return VisitorAction.CONTINUE; + } + + private int mShapesVisited; + private int mTextIndentLevel; + private /*final*/ StringBuilder mStringBuilder; + } + //ExEnd + + @Test + public void signatureLine() throws Exception + { + //ExStart + //ExFor:Shape.SignatureLine + //ExFor:ShapeBase.IsSignatureLine + //ExFor:SignatureLine + //ExFor:SignatureLine.AllowComments + //ExFor:SignatureLine.DefaultInstructions + //ExFor:SignatureLine.Email + //ExFor:SignatureLine.Instructions + //ExFor:SignatureLine.ShowDate + //ExFor:SignatureLine.Signer + //ExFor:SignatureLine.SignerTitle + //ExSummary:Shows how to create a line for a signature and insert it into a document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + SignatureLineOptions options = new SignatureLineOptions(); + { + options.setAllowComments(true); + options.setDefaultInstructions(true); + options.setEmail("john.doe@management.com"); + options.setInstructions("Please sign here"); + options.setShowDate(true); + options.setSigner("John Doe"); + options.setSignerTitle("Senior Manager"); + } + + // Insert a shape that will contain a signature line, whose appearance we will + // customize using the "SignatureLineOptions" object we have created above. + // If we insert a shape whose coordinates originate at the bottom right hand corner of the page, + // we will need to supply negative x and y coordinates to bring the shape into view. + Shape shape = builder.insertSignatureLine(options, RelativeHorizontalPosition.RIGHT_MARGIN, -170.0, + RelativeVerticalPosition.BOTTOM_MARGIN, -60.0, WrapType.NONE); + + Assert.assertTrue(shape.isSignatureLine()); + + // Verify the properties of our signature line via its Shape object. + SignatureLine signatureLine = shape.getSignatureLine(); + + Assert.assertEquals("john.doe@management.com", signatureLine.getEmail()); + Assert.assertEquals("John Doe", signatureLine.getSigner()); + Assert.assertEquals("Senior Manager", signatureLine.getSignerTitle()); + Assert.assertEquals("Please sign here", signatureLine.getInstructions()); + Assert.assertTrue(signatureLine.getShowDate()); + Assert.assertTrue(signatureLine.getAllowComments()); + Assert.assertTrue(signatureLine.getDefaultInstructions()); + + doc.save(getArtifactsDir() + "Shape.SignatureLine.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.SignatureLine.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.IMAGE, "", 192.75d, 96.75d, -60.0d, -170.0d, shape); + Assert.assertTrue(shape.isSignatureLine()); + + signatureLine = shape.getSignatureLine(); + + Assert.assertEquals("john.doe@management.com", signatureLine.getEmail()); + Assert.assertEquals("John Doe", signatureLine.getSigner()); + Assert.assertEquals("Senior Manager", signatureLine.getSignerTitle()); + Assert.assertEquals("Please sign here", signatureLine.getInstructions()); + Assert.assertTrue(signatureLine.getShowDate()); + Assert.assertTrue(signatureLine.getAllowComments()); + Assert.assertTrue(signatureLine.getDefaultInstructions()); + Assert.assertFalse(signatureLine.isSigned()); + Assert.assertFalse(signatureLine.isValid()); + } + + @Test (dataProvider = "textBoxLayoutFlowDataProvider") + public void textBoxLayoutFlow(/*LayoutFlow*/int layoutFlow) throws Exception + { + //ExStart + //ExFor:Shape.TextBox + //ExFor:Shape.LastParagraph + //ExFor:TextBox + //ExFor:TextBox.LayoutFlow + //ExSummary:Shows how to set the orientation of text inside a text box. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape textBoxShape = builder.insertShape(ShapeType.TEXT_BOX, 150.0, 100.0); + TextBox textBox = textBoxShape.getTextBox(); + + // Move the document builder to inside the TextBox and add text. + builder.moveTo(textBoxShape.getLastParagraph()); + builder.writeln("Hello world!"); + builder.write("Hello again!"); + + // Set the "LayoutFlow" property to set an orientation for the text contents of this text box. + textBox.setLayoutFlow(layoutFlow); + + doc.save(getArtifactsDir() + "Shape.TextBoxLayoutFlow.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.TextBoxLayoutFlow.docx"); + textBoxShape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.TEXT_BOX, "TextBox 100002", 150.0d, 100.0d, 0.0d, 0.0d, textBoxShape); + + /*LayoutFlow*/int expectedLayoutFlow; + + switch (layoutFlow) + { + case LayoutFlow.BOTTOM_TO_TOP: + case LayoutFlow.HORIZONTAL: + case LayoutFlow.TOP_TO_BOTTOM_IDEOGRAPHIC: + case LayoutFlow.VERTICAL: + expectedLayoutFlow = layoutFlow; + break; + case LayoutFlow.TOP_TO_BOTTOM: + expectedLayoutFlow = LayoutFlow.VERTICAL; + break; + default: + expectedLayoutFlow = LayoutFlow.HORIZONTAL; + break; + } + + TestUtil.verifyTextBox(expectedLayoutFlow, false, TextBoxWrapMode.SQUARE, 3.6d, 3.6d, 7.2d, 7.2d, textBoxShape.getTextBox()); + Assert.assertEquals("Hello world!\rHello again!", textBoxShape.getText().trim()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "textBoxLayoutFlowDataProvider") + public static Object[][] textBoxLayoutFlowDataProvider() throws Exception + { + return new Object[][] + { + {LayoutFlow.VERTICAL}, + {LayoutFlow.HORIZONTAL}, + {LayoutFlow.HORIZONTAL_IDEOGRAPHIC}, + {LayoutFlow.BOTTOM_TO_TOP}, + {LayoutFlow.TOP_TO_BOTTOM}, + {LayoutFlow.TOP_TO_BOTTOM_IDEOGRAPHIC}, + }; + } + + @Test + public void textBoxFitShapeToText() throws Exception + { + //ExStart + //ExFor:TextBox + //ExFor:TextBox.FitShapeToText + //ExSummary:Shows how to get a text box to resize itself to fit its contents tightly. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape textBoxShape = builder.insertShape(ShapeType.TEXT_BOX, 150.0, 100.0); + TextBox textBox = textBoxShape.getTextBox(); + + // Apply these values to both these members to get the parent shape to fit + // tightly around the text contents, ignoring the dimensions we have set. + textBox.setFitShapeToText(true); + textBox.setTextBoxWrapMode(TextBoxWrapMode.NONE); + + builder.moveTo(textBoxShape.getLastParagraph()); + builder.write("Text fit tightly inside textbox."); + + doc.save(getArtifactsDir() + "Shape.TextBoxFitShapeToText.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.TextBoxFitShapeToText.docx"); + textBoxShape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.TEXT_BOX, "TextBox 100002", 150.0d, 100.0d, 0.0d, 0.0d, textBoxShape); + TestUtil.verifyTextBox(LayoutFlow.HORIZONTAL, true, TextBoxWrapMode.NONE, 3.6d, 3.6d, 7.2d, 7.2d, textBoxShape.getTextBox()); + Assert.assertEquals("Text fit tightly inside textbox.", textBoxShape.getText().trim()); + } + + @Test + public void textBoxMargins() throws Exception + { + //ExStart + //ExFor:TextBox + //ExFor:TextBox.InternalMarginBottom + //ExFor:TextBox.InternalMarginLeft + //ExFor:TextBox.InternalMarginRight + //ExFor:TextBox.InternalMarginTop + //ExSummary:Shows how to set internal margins for a text box. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert another textbox with specific margins. + Shape textBoxShape = builder.insertShape(ShapeType.TEXT_BOX, 100.0, 100.0); + TextBox textBox = textBoxShape.getTextBox(); + textBox.setInternalMarginTop(15.0); + textBox.setInternalMarginBottom(15.0); + textBox.setInternalMarginLeft(15.0); + textBox.setInternalMarginRight(15.0); + + builder.moveTo(textBoxShape.getLastParagraph()); + builder.write("Text placed according to textbox margins."); + + doc.save(getArtifactsDir() + "Shape.TextBoxMargins.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.TextBoxMargins.docx"); + textBoxShape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.TEXT_BOX, "TextBox 100002", 100.0d, 100.0d, 0.0d, 0.0d, textBoxShape); + TestUtil.verifyTextBox(LayoutFlow.HORIZONTAL, false, TextBoxWrapMode.SQUARE, 15.0d, 15.0d, 15.0d, 15.0d, textBoxShape.getTextBox()); + Assert.assertEquals("Text placed according to textbox margins.", textBoxShape.getText().trim()); + } + + @Test (dataProvider = "textBoxContentsWrapModeDataProvider") + public void textBoxContentsWrapMode(/*TextBoxWrapMode*/int textBoxWrapMode) throws Exception + { + //ExStart + //ExFor:TextBox.TextBoxWrapMode + //ExFor:TextBoxWrapMode + //ExSummary:Shows how to set a wrapping mode for the contents of a text box. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape textBoxShape = builder.insertShape(ShapeType.TEXT_BOX, 300.0, 300.0); + TextBox textBox = textBoxShape.getTextBox(); + + // Set the "TextBoxWrapMode" property to "TextBoxWrapMode.None" to increase the text box's width + // to accommodate text, should it be large enough. + // Set the "TextBoxWrapMode" property to "TextBoxWrapMode.Square" to + // wrap all text inside the text box, preserving its dimensions. + textBox.setTextBoxWrapMode(textBoxWrapMode); + + builder.moveTo(textBoxShape.getLastParagraph()); + builder.getFont().setSize(32.0); + builder.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + + doc.save(getArtifactsDir() + "Shape.TextBoxContentsWrapMode.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.TextBoxContentsWrapMode.docx"); + textBoxShape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.TEXT_BOX, "TextBox 100002", 300.0d, 300.0d, 0.0d, 0.0d, textBoxShape); + TestUtil.verifyTextBox(LayoutFlow.HORIZONTAL, false, textBoxWrapMode, 3.6d, 3.6d, 7.2d, 7.2d, textBoxShape.getTextBox()); + Assert.assertEquals("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", textBoxShape.getText().trim()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "textBoxContentsWrapModeDataProvider") + public static Object[][] textBoxContentsWrapModeDataProvider() throws Exception + { + return new Object[][] + { + {TextBoxWrapMode.NONE}, + {TextBoxWrapMode.SQUARE}, + }; + } + + @Test + public void textBoxShapeType() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Set compatibility options to correctly using of VerticalAnchor property. + doc.getCompatibilityOptions().optimizeFor(MsWordVersion.WORD_2016); + + Shape textBoxShape = builder.insertShape(ShapeType.TEXT_BOX, 100.0, 100.0); + // Not all formats are compatible with this one. + // For most of the incompatible formats, AW generated warnings on save, so use doc.WarningCallback to check it. + textBoxShape.getTextBox().setVerticalAnchor(TextBoxAnchor.BOTTOM); + + builder.moveTo(textBoxShape.getLastParagraph()); + builder.write("Text placed bottom"); + + doc.save(getArtifactsDir() + "Shape.TextBoxShapeType.docx"); + } + + @Test + public void createLinkBetweenTextBoxes() throws Exception + { + //ExStart + //ExFor:TextBox.IsValidLinkTarget(TextBox) + //ExFor:TextBox.Next + //ExFor:TextBox.Previous + //ExFor:TextBox.BreakForwardLink + //ExSummary:Shows how to link text boxes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape textBoxShape1 = builder.insertShape(ShapeType.TEXT_BOX, 100.0, 100.0); + TextBox textBox1 = textBoxShape1.getTextBox(); + builder.writeln(); + + Shape textBoxShape2 = builder.insertShape(ShapeType.TEXT_BOX, 100.0, 100.0); + TextBox textBox2 = textBoxShape2.getTextBox(); + builder.writeln(); + + Shape textBoxShape3 = builder.insertShape(ShapeType.TEXT_BOX, 100.0, 100.0); + TextBox textBox3 = textBoxShape3.getTextBox(); + builder.writeln(); + + Shape textBoxShape4 = builder.insertShape(ShapeType.TEXT_BOX, 100.0, 100.0); + TextBox textBox4 = textBoxShape4.getTextBox(); + + // Create links between some of the text boxes. + if (textBox1.isValidLinkTarget(textBox2)) + textBox1.setNext(textBox2); + + if (textBox2.isValidLinkTarget(textBox3)) + textBox2.setNext(textBox3); + + // Only an empty text box may have a link. + Assert.assertTrue(textBox3.isValidLinkTarget(textBox4)); + + builder.moveTo(textBoxShape4.getLastParagraph()); + builder.write("Hello world!"); + + Assert.assertFalse(textBox3.isValidLinkTarget(textBox4)); + + if (textBox1.getNext() != null && textBox1.getPrevious() == null) + System.out.println("This TextBox is the head of the sequence"); + + if (textBox2.getNext() != null && textBox2.getPrevious() != null) + System.out.println("This TextBox is the middle of the sequence"); + + if (textBox3.getNext() == null && textBox3.getPrevious() != null) + { + System.out.println("This TextBox is the tail of the sequence"); + + // Break the forward link between textBox2 and textBox3, and then verify that they are no longer linked. + textBox3.getPrevious().breakForwardLink(); + Assert.assertTrue(textBox2.getNext() == null); + Assert.assertTrue(textBox3.getPrevious() == null); + } + + doc.save(getArtifactsDir() + "Shape.CreateLinkBetweenTextBoxes.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.CreateLinkBetweenTextBoxes.docx"); + ArrayList shapes = doc.getChildNodes(NodeType.SHAPE, true).OfType().ToList(); + + TestUtil.verifyShape(ShapeType.TEXT_BOX, "TextBox 100002", 100.0d, 100.0d, 0.0d, 0.0d, shapes.get(0)); + TestUtil.verifyTextBox(LayoutFlow.HORIZONTAL, false, TextBoxWrapMode.SQUARE, 3.6d, 3.6d, 7.2d, 7.2d, shapes.get(0).getTextBox()); + Assert.assertEquals("", shapes.get(0).getText().trim()); + + TestUtil.verifyShape(ShapeType.TEXT_BOX, "TextBox 100004", 100.0d, 100.0d, 0.0d, 0.0d, shapes.get(1)); + TestUtil.verifyTextBox(LayoutFlow.HORIZONTAL, false, TextBoxWrapMode.SQUARE, 3.6d, 3.6d, 7.2d, 7.2d, shapes.get(1).getTextBox()); + Assert.assertEquals("", shapes.get(1).getText().trim()); + + TestUtil.verifyShape(ShapeType.RECTANGLE, "TextBox 100006", 100.0d, 100.0d, 0.0d, 0.0d, shapes.get(2)); + TestUtil.verifyTextBox(LayoutFlow.HORIZONTAL, false, TextBoxWrapMode.SQUARE, 3.6d, 3.6d, 7.2d, 7.2d, shapes.get(2).getTextBox()); + Assert.assertEquals("", shapes.get(2).getText().trim()); + + TestUtil.verifyShape(ShapeType.TEXT_BOX, "TextBox 100008", 100.0d, 100.0d, 0.0d, 0.0d, shapes.get(3)); + TestUtil.verifyTextBox(LayoutFlow.HORIZONTAL, false, TextBoxWrapMode.SQUARE, 3.6d, 3.6d, 7.2d, 7.2d, shapes.get(3).getTextBox()); + Assert.assertEquals("Hello world!", shapes.get(3).getText().trim()); + } + + @Test (dataProvider = "verticalAnchorDataProvider") + public void verticalAnchor(/*TextBoxAnchor*/int verticalAnchor) throws Exception + { + //ExStart + //ExFor:CompatibilityOptions + //ExFor:CompatibilityOptions.OptimizeFor(MsWordVersion) + //ExFor:TextBoxAnchor + //ExFor:TextBox.VerticalAnchor + //ExSummary:Shows how to vertically align the text contents of a text box. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertShape(ShapeType.TEXT_BOX, 200.0, 200.0); + + // Set the "VerticalAnchor" property to "TextBoxAnchor.Top" to + // align the text in this text box with the top side of the shape. + // Set the "VerticalAnchor" property to "TextBoxAnchor.Middle" to + // align the text in this text box to the center of the shape. + // Set the "VerticalAnchor" property to "TextBoxAnchor.Bottom" to + // align the text in this text box to the bottom of the shape. + shape.getTextBox().setVerticalAnchor(verticalAnchor); + + builder.moveTo(shape.getFirstParagraph()); + builder.write("Hello world!"); + + // The vertical aligning of text inside text boxes is available from Microsoft Word 2007 onwards. + doc.getCompatibilityOptions().optimizeFor(MsWordVersion.WORD_2007); + doc.save(getArtifactsDir() + "Shape.VerticalAnchor.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.VerticalAnchor.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + TestUtil.verifyShape(ShapeType.TEXT_BOX, "TextBox 100002", 200.0d, 200.0d, 0.0d, 0.0d, shape); + TestUtil.verifyTextBox(LayoutFlow.HORIZONTAL, false, TextBoxWrapMode.SQUARE, 3.6d, 3.6d, 7.2d, 7.2d, shape.getTextBox()); + Assert.assertEquals(verticalAnchor, shape.getTextBox().getVerticalAnchor()); + Assert.assertEquals("Hello world!", shape.getText().trim()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "verticalAnchorDataProvider") + public static Object[][] verticalAnchorDataProvider() throws Exception + { + return new Object[][] + { + {TextBoxAnchor.TOP}, + {TextBoxAnchor.MIDDLE}, + {TextBoxAnchor.BOTTOM}, + }; + } + + //ExStart + //ExFor:Shape.TextPath + //ExFor:ShapeBase.IsWordArt + //ExFor:TextPath + //ExFor:TextPath.Bold + //ExFor:TextPath.FitPath + //ExFor:TextPath.FitShape + //ExFor:TextPath.FontFamily + //ExFor:TextPath.Italic + //ExFor:TextPath.Kerning + //ExFor:TextPath.On + //ExFor:TextPath.ReverseRows + //ExFor:TextPath.RotateLetters + //ExFor:TextPath.SameLetterHeights + //ExFor:TextPath.Shadow + //ExFor:TextPath.SmallCaps + //ExFor:TextPath.Spacing + //ExFor:TextPath.StrikeThrough + //ExFor:TextPath.Text + //ExFor:TextPath.TextPathAlignment + //ExFor:TextPath.Trim + //ExFor:TextPath.Underline + //ExFor:TextPath.XScale + //ExFor:TextPath.Size + //ExFor:TextPathAlignment + //ExSummary:Shows how to work with WordArt. + @Test //ExSkip + public void insertTextPaths() throws Exception + { + Document doc = new Document(); + + // Insert a WordArt object to display text in a shape that we can re-size and move by using the mouse in Microsoft Word. + // Provide a "ShapeType" as an argument to set a shape for the WordArt. + Shape shape = appendWordArt(doc, "Hello World! This text is bold, and italic.", + "Arial", 480.0, 24.0, Color.WHITE, Color.BLACK, ShapeType.TEXT_PLAIN_TEXT); + + // Apply the "Bold" and "Italic" formatting settings to the text using the respective properties. + shape.getTextPath().setBold(true); + shape.getTextPath().setItalic(true); + + // Below are various other text formatting-related properties. + Assert.assertFalse(shape.getTextPath().getUnderline()); + Assert.assertFalse(shape.getTextPath().getShadow()); + Assert.assertFalse(shape.getTextPath().getStrikeThrough()); + Assert.assertFalse(shape.getTextPath().getReverseRows()); + Assert.assertFalse(shape.getTextPath().getXScale()); + Assert.assertFalse(shape.getTextPath().getTrim()); + Assert.assertFalse(shape.getTextPath().getSmallCaps()); + + Assert.assertEquals(36.0, shape.getTextPath().getSize()); + Assert.assertEquals("Hello World! This text is bold, and italic.", shape.getTextPath().getText()); + Assert.assertEquals(ShapeType.TEXT_PLAIN_TEXT, shape.getShapeType()); + + // Use the "On" property to show/hide the text. + shape = appendWordArt(doc, "On set to \"true\"", "Calibri", 150.0, 24.0, Color.YELLOW, Color.RED, ShapeType.TEXT_PLAIN_TEXT); + shape.getTextPath().setOn(true); + + shape = appendWordArt(doc, "On set to \"false\"", "Calibri", 150.0, 24.0, Color.YELLOW, Color.Purple, ShapeType.TEXT_PLAIN_TEXT); + shape.getTextPath().setOn(false); + + // Use the "Kerning" property to enable/disable kerning spacing between certain characters. + shape = appendWordArt(doc, "Kerning: VAV", "Times New Roman", 90.0, 24.0, msColor.getOrange(), Color.RED, ShapeType.TEXT_PLAIN_TEXT); + shape.getTextPath().setKerning(true); + + shape = appendWordArt(doc, "No kerning: VAV", "Times New Roman", 100.0, 24.0, msColor.getOrange(), Color.RED, ShapeType.TEXT_PLAIN_TEXT); + shape.getTextPath().setKerning(false); + + // Use the "Spacing" property to set the custom spacing between characters on a scale from 0.0 (none) to 1.0 (default). + shape = appendWordArt(doc, "Spacing set to 0.1", "Calibri", 120.0, 24.0, msColor.getBlueViolet(), Color.BLUE, ShapeType.TEXT_CASCADE_DOWN); + shape.getTextPath().setSpacing(0.1); + + // Set the "RotateLetters" property to "true" to rotate each character 90 degrees counterclockwise. + shape = appendWordArt(doc, "RotateLetters", "Calibri", 200.0, 36.0, msColor.getGreenYellow(), msColor.getGreen(), ShapeType.TEXT_WAVE); + shape.getTextPath().setRotateLetters(true); + + // Set the "SameLetterHeights" property to "true" to get the x-height of each character to equal the cap height. + shape = appendWordArt(doc, "Same character height for lower and UPPER case", "Calibri", 300.0, 24.0, Color.DeepSkyBlue, Color.DodgerBlue, ShapeType.TEXT_SLANT_UP); + shape.getTextPath().setSameLetterHeights(true); + + // By default, the text's size will always scale to fit the containing shape's size, overriding the text size setting. + shape = appendWordArt(doc, "FitShape on", "Calibri", 160.0, 24.0, msColor.getLightBlue(), Color.BLUE, ShapeType.TEXT_PLAIN_TEXT); + Assert.assertTrue(shape.getTextPath().getFitShape()); + shape.getTextPath().setSize(24.0); + + // If we set the "FitShape: property to "false", the text will keep the size + // which the "Size" property specifies regardless of the size of the shape. + // Use the "TextPathAlignment" property also to align the text to a side of the shape. + shape = appendWordArt(doc, "FitShape off", "Calibri", 160.0, 24.0, msColor.getLightBlue(), Color.BLUE, ShapeType.TEXT_PLAIN_TEXT); + shape.getTextPath().setFitShape(false); + shape.getTextPath().setSize(24.0); + shape.getTextPath().setTextPathAlignment(TextPathAlignment.RIGHT); + + doc.save(getArtifactsDir() + "Shape.InsertTextPaths.docx"); + testInsertTextPaths(getArtifactsDir() + "Shape.InsertTextPaths.docx"); //ExSkip + } + + /// + /// Insert a new paragraph with a WordArt shape inside it. + /// + private static Shape appendWordArt(Document doc, String text, String textFontFamily, double shapeWidth, double shapeHeight, Color wordArtFill, Color line, /*ShapeType*/int wordArtShapeType) + { + // Create an inline Shape, which will serve as a container for our WordArt. + // The shape can only be a valid WordArt shape if we assign a WordArt-designated ShapeType to it. + // These types will have "WordArt object" in the description, + // and their enumerator constant names will all start with "Text". + Shape shape = new Shape(doc, wordArtShapeType); + { + shape.setWrapType(WrapType.INLINE); + shape.setWidth(shapeWidth); + shape.setHeight(shapeHeight); + shape.setFillColor(wordArtFill); + shape.setStrokeColor(line); + } + + shape.getTextPath().setText(text); + shape.getTextPath().setFontFamily(textFontFamily); + + Paragraph para = (Paragraph)doc.getFirstSection().getBody().appendChild(new Paragraph(doc)); + para.appendChild(shape); + return shape; + } + //ExEnd + + private void testInsertTextPaths(String filename) throws Exception + { + Document doc = new Document(filename); + ArrayList shapes = doc.getChildNodes(NodeType.SHAPE, true).OfType().ToList(); + + TestUtil.verifyShape(ShapeType.TEXT_PLAIN_TEXT, "", 480.0, 24.0, 0.0d, 0.0d, shapes.get(0)); + Assert.assertTrue(shapes.get(0).getTextPath().getBold()); + Assert.assertTrue(shapes.get(0).getTextPath().getItalic()); + + TestUtil.verifyShape(ShapeType.TEXT_PLAIN_TEXT, "", 150.0, 24.0, 0.0d, 0.0d, shapes.get(1)); + Assert.assertTrue(shapes.get(1).getTextPath().getOn()); + + TestUtil.verifyShape(ShapeType.TEXT_PLAIN_TEXT, "", 150.0, 24.0, 0.0d, 0.0d, shapes.get(2)); + Assert.assertFalse(shapes.get(2).getTextPath().getOn()); + + TestUtil.verifyShape(ShapeType.TEXT_PLAIN_TEXT, "", 90.0, 24.0, 0.0d, 0.0d, shapes.get(3)); + Assert.assertTrue(shapes.get(3).getTextPath().getKerning()); + + TestUtil.verifyShape(ShapeType.TEXT_PLAIN_TEXT, "", 100.0, 24.0, 0.0d, 0.0d, shapes.get(4)); + Assert.assertFalse(shapes.get(4).getTextPath().getKerning()); + + TestUtil.verifyShape(ShapeType.TEXT_CASCADE_DOWN, "", 120.0, 24.0, 0.0d, 0.0d, shapes.get(5)); + Assert.assertEquals(0.1d, 0.01d, shapes.get(5).getTextPath().getSpacing()); + + TestUtil.verifyShape(ShapeType.TEXT_WAVE, "", 200.0, 36.0, 0.0d, 0.0d, shapes.get(6)); + Assert.assertTrue(shapes.get(6).getTextPath().getRotateLetters()); + + TestUtil.verifyShape(ShapeType.TEXT_SLANT_UP, "", 300.0, 24.0, 0.0d, 0.0d, shapes.get(7)); + Assert.assertTrue(shapes.get(7).getTextPath().getSameLetterHeights()); + + TestUtil.verifyShape(ShapeType.TEXT_PLAIN_TEXT, "", 160.0, 24.0, 0.0d, 0.0d, shapes.get(8)); + Assert.assertTrue(shapes.get(8).getTextPath().getFitShape()); + Assert.assertEquals(24.0d, shapes.get(8).getTextPath().getSize()); + + TestUtil.verifyShape(ShapeType.TEXT_PLAIN_TEXT, "", 160.0, 24.0, 0.0d, 0.0d, shapes.get(9)); + Assert.assertFalse(shapes.get(9).getTextPath().getFitShape()); + Assert.assertEquals(24.0d, shapes.get(9).getTextPath().getSize()); + Assert.assertEquals(TextPathAlignment.RIGHT, shapes.get(9).getTextPath().getTextPathAlignment()); + } + + @Test + public void shapeRevision() throws Exception + { + //ExStart + //ExFor:ShapeBase.IsDeleteRevision + //ExFor:ShapeBase.IsInsertRevision + //ExSummary:Shows how to work with revision shapes. + Document doc = new Document(); + + Assert.assertFalse(doc.getTrackRevisions()); + + // Insert an inline shape without tracking revisions, which will make this shape not a revision of any kind. + Shape shape = new Shape(doc, ShapeType.CUBE); + shape.setWrapType(WrapType.INLINE); + shape.setWidth(100.0); + shape.setHeight(100.0); + doc.getFirstSection().getBody().getFirstParagraph().appendChild(shape); + + // Start tracking revisions and then insert another shape, which will be a revision. + doc.startTrackRevisions("John Doe"); + + shape = new Shape(doc, ShapeType.SUN); + shape.setWrapType(WrapType.INLINE); + shape.setWidth(100.0); + shape.setHeight(100.0); + doc.getFirstSection().getBody().getFirstParagraph().appendChild(shape); + + Shape[] shapes = doc.getChildNodes(NodeType.SHAPE, true).OfType().ToArray(); + + Assert.assertEquals(2, shapes.length); + + shapes[0].remove(); + + // Since we removed that shape while we were tracking changes, + // the shape persists in the document and counts as a delete revision. + // Accepting this revision will remove the shape permanently, and rejecting it will keep it in the document. + Assert.assertEquals(ShapeType.CUBE, shapes[0].getShapeType()); + Assert.assertTrue(shapes[0].isDeleteRevision()); + + // And we inserted another shape while tracking changes, so that shape will count as an insert revision. + // Accepting this revision will assimilate this shape into the document as a non-revision, + // and rejecting the revision will remove this shape permanently. + Assert.assertEquals(ShapeType.SUN, shapes[1].getShapeType()); + Assert.assertTrue(shapes[1].isInsertRevision()); + //ExEnd + } + + @Test + public void moveRevisions() throws Exception + { + //ExStart + //ExFor:ShapeBase.IsMoveFromRevision + //ExFor:ShapeBase.IsMoveToRevision + //ExSummary:Shows how to identify move revision shapes. + // A move revision is when we move an element in the document body by cut-and-pasting it in Microsoft Word while + // tracking changes. If we involve an inline shape in such a text movement, that shape will also be a revision. + // Copying-and-pasting or moving floating shapes do not create move revisions. + Document doc = new Document(getMyDir() + "Revision shape.docx"); + + // Move revisions consist of pairs of "Move from", and "Move to" revisions. We moved in this document in one shape, + // but until we accept or reject the move revision, there will be two instances of that shape. + Shape[] shapes = doc.getChildNodes(NodeType.SHAPE, true).OfType().ToArray(); + + Assert.assertEquals(2, shapes.length); + + // This is the "Move to" revision, which is the shape at its arrival destination. + // If we accept the revision, this "Move to" revision shape will disappear, + // and the "Move from" revision shape will remain. + Assert.assertFalse(shapes[0].isMoveFromRevision()); + Assert.assertTrue(shapes[0].isMoveToRevision()); + + // This is the "Move from" revision, which is the shape at its original location. + // If we accept the revision, this "Move from" revision shape will disappear, + // and the "Move to" revision shape will remain. + Assert.assertTrue(shapes[1].isMoveFromRevision()); + Assert.assertFalse(shapes[1].isMoveToRevision()); + //ExEnd + } + + @Test + public void adjustWithEffects() throws Exception + { + //ExStart + //ExFor:ShapeBase.AdjustWithEffects(RectangleF) + //ExFor:ShapeBase.BoundsWithEffects + //ExSummary:Shows how to check how a shape's bounds are affected by shape effects. + Document doc = new Document(getMyDir() + "Shape shadow effect.docx"); + + Shape[] shapes = doc.getChildNodes(NodeType.SHAPE, true).OfType().ToArray(); + + Assert.assertEquals(2, shapes.length); + + // The two shapes are identical in terms of dimensions and shape type. + Assert.assertEquals(shapes[0].getWidth(), shapes[1].getWidth()); + Assert.assertEquals(shapes[0].getHeight(), shapes[1].getHeight()); + Assert.assertEquals(shapes[0].getShapeType(), shapes[1].getShapeType()); + + // The first shape has no effects, and the second one has a shadow and thick outline. + // These effects make the size of the second shape's silhouette bigger than that of the first. + // Even though the rectangle's size shows up when we click on these shapes in Microsoft Word, + // the visible outer bounds of the second shape are affected by the shadow and outline and thus are bigger. + // We can use the "AdjustWithEffects" method to see the true size of the shape. + Assert.assertEquals(0.0, shapes[0].getStrokeWeight()); + Assert.assertEquals(20.0, shapes[1].getStrokeWeight()); + Assert.assertFalse(shapes[0].getShadowEnabled()); + Assert.assertTrue(shapes[1].getShadowEnabled()); + + Shape shape = shapes[0]; + + // Create a RectangleF object, representing a rectangle, + // which we could potentially use as the coordinates and bounds for a shape. + RectangleF rectangleF = new RectangleF(200f, 200f, 1000f, 1000f); + + // Run this method to get the size of the rectangle adjusted for all our shape effects. + RectangleF rectangleFOut = shape.adjustWithEffectsInternal(rectangleF); + + // Since the shape has no border-changing effects, its boundary dimensions are unaffected. + Assert.assertEquals(200, rectangleFOut.getX()); + Assert.assertEquals(200, rectangleFOut.getY()); + Assert.assertEquals(1000, rectangleFOut.getWidth()); + Assert.assertEquals(1000, rectangleFOut.getHeight()); + + // Verify the final extent of the first shape, in points. + Assert.assertEquals(0, shape.getBoundsWithEffectsInternal().getX()); + Assert.assertEquals(0, shape.getBoundsWithEffectsInternal().getY()); + Assert.assertEquals(147, shape.getBoundsWithEffectsInternal().getWidth()); + Assert.assertEquals(147, shape.getBoundsWithEffectsInternal().getHeight()); + + shape = shapes[1]; + rectangleF = new RectangleF(200f, 200f, 1000f, 1000f); + rectangleFOut = shape.adjustWithEffectsInternal(rectangleF); + + // The shape effects have moved the apparent top left corner of the shape slightly. + Assert.assertEquals(171.5, rectangleFOut.getX()); + Assert.assertEquals(167, rectangleFOut.getY()); + + // The effects have also affected the visible dimensions of the shape. + Assert.assertEquals(1045, rectangleFOut.getWidth()); + Assert.assertEquals(1133.5, rectangleFOut.getHeight()); + + // The effects have also affected the visible bounds of the shape. + Assert.assertEquals(-28.5, shape.getBoundsWithEffectsInternal().getX()); + Assert.assertEquals(-33, shape.getBoundsWithEffectsInternal().getY()); + Assert.assertEquals(192, shape.getBoundsWithEffectsInternal().getWidth()); + Assert.assertEquals(280.5, shape.getBoundsWithEffectsInternal().getHeight()); + //ExEnd + } + + @Test + public void renderAllShapes() throws Exception + { + //ExStart + //ExFor:ShapeBase.GetShapeRenderer + //ExFor:NodeRendererBase.Save(Stream, ImageSaveOptions) + //ExSummary:Shows how to use a shape renderer to export shapes to files in the local file system. + Document doc = new Document(getMyDir() + "Various shapes.docx"); + Shape[] shapes = doc.getChildNodes(NodeType.SHAPE, true).OfType().ToArray(); + + Assert.assertEquals(7, shapes.length); + + // There are 7 shapes in the document, including one group shape with 2 child shapes. + // We will render every shape to an image file in the local file system + // while ignoring the group shapes since they have no appearance. + // This will produce 6 image files. + for (Shape shape : doc.getChildNodes(NodeType.SHAPE, true).OfType() !!Autoporter error: Undefined expression type ) + { + ShapeRenderer renderer = shape.getShapeRenderer(); + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.PNG); + renderer.save(getArtifactsDir() + $"Shape.RenderAllShapes.{shape.Name}.png", options); + } + //ExEnd + } + + @Test + public void documentHasSmartArtObject() throws Exception + { + //ExStart + //ExFor:Shape.HasSmartArt + //ExSummary:Shows how to count the number of shapes in a document with SmartArt objects. + Document doc = new Document(getMyDir() + "SmartArt.docx"); + + int numberOfSmartArtShapes = doc.getChildNodes(NodeType.SHAPE, true).Cast().Count(shape => shape.HasSmartArt); + + Assert.assertEquals(2, numberOfSmartArtShapes); + //ExEnd + + } + + @Test (groups = "SkipMono") + public void officeMathRenderer() throws Exception + { + //ExStart + //ExFor:NodeRendererBase + //ExFor:NodeRendererBase.BoundsInPoints + //ExFor:NodeRendererBase.GetBoundsInPixels(Single, Single) + //ExFor:NodeRendererBase.GetBoundsInPixels(Single, Single, Single) + //ExFor:NodeRendererBase.GetOpaqueBoundsInPixels(Single, Single) + //ExFor:NodeRendererBase.GetOpaqueBoundsInPixels(Single, Single, Single) + //ExFor:NodeRendererBase.GetSizeInPixels(Single, Single) + //ExFor:NodeRendererBase.GetSizeInPixels(Single, Single, Single) + //ExFor:NodeRendererBase.OpaqueBoundsInPoints + //ExFor:NodeRendererBase.SizeInPoints + //ExFor:OfficeMathRenderer + //ExFor:OfficeMathRenderer.#ctor(OfficeMath) + //ExSummary:Shows how to measure and scale shapes. + Document doc = new Document(getMyDir() + "Office math.docx"); + + OfficeMath officeMath = (OfficeMath)doc.getChild(NodeType.OFFICE_MATH, 0, true); + OfficeMathRenderer renderer = new OfficeMathRenderer(officeMath); + + // Verify the size of the image that the OfficeMath object will create when we render it. + Assert.assertEquals(122.0f, 0.25f, msSizeF.getWidth(renderer.getSizeInPointsInternal())); + Assert.assertEquals(13.0f, 0.15f, msSizeF.getHeight(renderer.getSizeInPointsInternal())); + + Assert.assertEquals(122.0f, 0.25f, renderer.getBoundsInPointsInternal().getWidth()); + Assert.assertEquals(13.0f, 0.15f, renderer.getBoundsInPointsInternal().getHeight()); + + // Shapes with transparent parts may contain different values in the "OpaqueBoundsInPoints" properties. + Assert.assertEquals(122.0f, 0.25f, renderer.getOpaqueBoundsInPointsInternal().getWidth()); + Assert.assertEquals(14.2f, 0.1f, renderer.getOpaqueBoundsInPointsInternal().getHeight()); + + // Get the shape size in pixels, with linear scaling to a specific DPI. + Rectangle bounds = renderer.getBoundsInPixelsInternal(1.0f, 96.0f); + + Assert.assertEquals(163, bounds.getWidth()); + Assert.assertEquals(18, bounds.getHeight()); + + // Get the shape size in pixels, but with a different DPI for the horizontal and vertical dimensions. + bounds = renderer.getBoundsInPixelsInternal(1.0f, 96.0f, 150.0f); + Assert.assertEquals(163, bounds.getWidth()); + Assert.assertEquals(27, bounds.getHeight()); + + // The opaque bounds may vary here also. + bounds = renderer.getOpaqueBoundsInPixelsInternal(1.0f, 96.0f); + + Assert.assertEquals(163, bounds.getWidth()); + Assert.assertEquals(19, bounds.getHeight()); + + bounds = renderer.getOpaqueBoundsInPixelsInternal(1.0f, 96.0f, 150.0f); + + Assert.assertEquals(163, bounds.getWidth()); + Assert.assertEquals(29, bounds.getHeight()); + //ExEnd + } + + @Test + public void shapeTypes() throws Exception + { + //ExStart + //ExFor:ShapeType + //ExSummary:Shows how Aspose.Words identify shapes. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertShape(ShapeType.HEPTAGON, RelativeHorizontalPosition.PAGE, 0.0, + RelativeVerticalPosition.PAGE, 0.0, 0.0, 0.0, WrapType.NONE); + + builder.insertShape(ShapeType.CLOUD, RelativeHorizontalPosition.RIGHT_MARGIN, 0.0, + RelativeVerticalPosition.PAGE, 0.0, 0.0, 0.0, WrapType.NONE); + + builder.insertShape(ShapeType.MATH_PLUS, RelativeHorizontalPosition.RIGHT_MARGIN, 0.0, + RelativeVerticalPosition.PAGE, 0.0, 0.0, 0.0, WrapType.NONE); + + // To correct identify shape types you need to work with shapes as DML. + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(SaveFormat.DOCX); + { + // "Strict" or "Transitional" compliance allows to save shape as DML. + saveOptions.setCompliance(OoxmlCompliance.ISO_29500_2008_TRANSITIONAL); + } + + doc.save(getArtifactsDir() + "Shape.ShapeTypes.docx", saveOptions); + doc = new Document(getArtifactsDir() + "Shape.ShapeTypes.docx"); + + Shape[] shapes = doc.getChildNodes(NodeType.SHAPE, true).OfType().ToArray(); + + for (Shape shape : shapes) + { + System.out.println(shape.getShapeType()); + } + //ExEnd + } + + @Test + public void isDecorative() throws Exception + { + //ExStart + //ExFor:ShapeBase.IsDecorative + //ExSummary:Shows how to set that the shape is decorative. + Document doc = new Document(getMyDir() + "Decorative shapes.docx"); + + Shape shape = (Shape)doc.getChildNodes(NodeType.SHAPE, true).get(0); + Assert.assertTrue(shape.isDecorative()); + + // If "AlternativeText" is not empty, the shape cannot be decorative. + // That's why our value has changed to 'false'. + shape.setAlternativeText("Alternative text."); + Assert.assertFalse(shape.isDecorative()); + + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.moveToDocumentEnd(); + // Create a new shape as decorative. + shape = builder.insertShape(ShapeType.RECTANGLE, 100.0, 100.0); + shape.isDecorative(true); + + doc.save(getArtifactsDir() + "Shape.IsDecorative.docx"); + //ExEnd + } + + @Test + public void fillImage() throws Exception + { + //ExStart + //ExFor:Fill.SetImage(String) + //ExFor:Fill.SetImage(Byte[]) + //ExFor:Fill.SetImage(Stream) + //ExSummary:Shows how to set shape fill type as image. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // There are several ways of setting image. + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 80.0, 80.0); + // 1 - Using a local system filename: + shape.getFill().setImage(getImageDir() + "Logo.jpg"); + doc.save(getArtifactsDir() + "Shape.FillImage.FileName.docx"); + + // 2 - Load a file into a byte array: + shape.getFill().setImage(File.readAllBytes(getImageDir() + "Logo.jpg")); + doc.save(getArtifactsDir() + "Shape.FillImage.ByteArray.docx"); + + // 3 - From a stream: + FileStream stream = new FileStream(getImageDir() + "Logo.jpg", FileMode.OPEN); + try /*JAVA: was using*/ + { + shape.getFill().setImageInternal(stream); + } + finally { if (stream != null) stream.close(); } + doc.save(getArtifactsDir() + "Shape.FillImage.Stream.docx"); + //ExEnd + } + + @Test + public void shadowFormat() throws Exception + { + //ExStart + //ExFor:ShadowFormat.Visible + //ExFor:ShadowFormat.Clear() + //ExFor:ShadowType + //ExSummary:Shows how to work with a shadow formatting for the shape. + Document doc = new Document(getMyDir() + "Shape stroke pattern border.docx"); + Shape shape = (Shape)doc.getChildNodes(NodeType.SHAPE, true).get(0); + + if (shape.getShadowFormat().getVisible() && shape.getShadowFormat().getType() == ShadowType.SHADOW_2) + shape.getShadowFormat().setType(ShadowType.SHADOW_7); + + if (shape.getShadowFormat().getType() == ShadowType.SHADOW_MIXED) + shape.getShadowFormat().clear(); + //ExEnd + } + + @Test + public void noTextRotation() throws Exception + { + //ExStart + //ExFor:TextBox.NoTextRotation + //ExSummary:Shows how to disable text rotation when the shape is rotate. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertShape(ShapeType.ELLIPSE, 20.0, 20.0); + shape.getTextBox().setNoTextRotation(true); + + doc.save(getArtifactsDir() + "Shape.NoTextRotation.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "Shape.NoTextRotation.docx"); + shape = (Shape)doc.getChildNodes(NodeType.SHAPE, true).get(0); + + Assert.assertEquals(true, shape.getTextBox().getNoTextRotation()); + } + + @Test + public void relativeSizeAndPosition() throws Exception + { + //ExStart + //ExFor:ShapeBase.RelativeHorizontalSize + //ExFor:ShapeBase.RelativeVerticalSize + //ExFor:ShapeBase.WidthRelative + //ExFor:ShapeBase.HeightRelative + //ExFor:ShapeBase.TopRelative + //ExFor:ShapeBase.LeftRelative + //ExFor:RelativeHorizontalSize + //ExFor:RelativeVerticalSize + //ExSummary:Shows how to set relative size and position. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Adding a simple shape with absolute size and position. + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 100.0, 40.0); + // Set WrapType to WrapType.None since Inline shapes are automatically converted to absolute units. + shape.setWrapType(WrapType.NONE); + + // Checking and setting the relative horizontal size. + if (shape.getRelativeHorizontalSize() == RelativeHorizontalSize.DEFAULT) + { + // Setting the horizontal size binding to Margin. + shape.setRelativeHorizontalSize(RelativeHorizontalSize.MARGIN); + // Setting the width to 50% of Margin width. + shape.setWidthRelative(50f); + } + + // Checking and setting the relative vertical size. + if (shape.getRelativeVerticalSize() == RelativeVerticalSize.DEFAULT) + { + // Setting the vertical size binding to Margin. + shape.setRelativeVerticalSize(RelativeVerticalSize.MARGIN); + // Setting the heigh to 30% of Margin height. + shape.setHeightRelative(30f); + } + + // Checking and setting the relative vertical position. + if (shape.getRelativeVerticalPosition() == RelativeVerticalPosition.PARAGRAPH) + { + // etting the position binding to TopMargin. + shape.setRelativeVerticalPosition(RelativeVerticalPosition.TOP_MARGIN); + // Setting relative Top to 30% of TopMargin position. + shape.setTopRelative(30f); + } + + // Checking and setting the relative horizontal position. + if (shape.getRelativeHorizontalPosition() == RelativeHorizontalPosition.DEFAULT) + { + // Setting the position binding to RightMargin. + shape.setRelativeHorizontalPosition(RelativeHorizontalPosition.RIGHT_MARGIN); + // The position relative value can be negative. + shape.setLeftRelative(-260); + } + + doc.save(getArtifactsDir() + "Shape.RelativeSizeAndPosition.docx"); + //ExEnd + } + + @Test + public void fillBaseColor() throws Exception + { + //ExStart:FillBaseColor + //GistId:3428e84add5beb0d46a8face6e5fc858 + //ExFor:Fill.BaseForeColor + //ExFor:Stroke.BaseForeColor + //ExSummary:Shows how to get foreground color without modifiers. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(); + + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 100.0, 40.0); + shape.getFill().setForeColor(Color.RED); + shape.getFill().setForeTintAndShade(0.5); + shape.getStroke().getFill().setForeColor(msColor.getGreen()); + shape.getStroke().getFill().setTransparency(0.5); + + Assert.assertEquals(new Color((255), (188), (188), (255)).getRGB(), shape.getFill().getForeColor().getRGB()); + Assert.assertEquals(Color.RED.getRGB(), shape.getFill().getBaseForeColor().getRGB()); + + Assert.assertEquals(new Color((0), (128), (0), (128)).getRGB(), shape.getStroke().getForeColor().getRGB()); + Assert.assertEquals(msColor.getGreen().getRGB(), shape.getStroke().getBaseForeColor().getRGB()); + + Assert.assertEquals(msColor.getGreen().getRGB(), shape.getStroke().getFill().getForeColor().getRGB()); + Assert.assertEquals(msColor.getGreen().getRGB(), shape.getStroke().getFill().getBaseForeColor().getRGB()); + //ExEnd:FillBaseColor + } + + @Test + public void fitImageToShape() throws Exception + { + //ExStart:FitImageToShape + //GistId:3428e84add5beb0d46a8face6e5fc858 + //ExFor:ImageData.FitImageToShape + //ExSummary:Shows hot to fit the image data to Shape frame. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert an image shape and leave its orientation in its default state. + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 300.0, 450.0); + shape.getImageData().setImage(getImageDir() + "Barcode.png"); + shape.getImageData().fitImageToShape(); + + doc.save(getArtifactsDir() + "Shape.FitImageToShape.docx"); + //ExEnd:FitImageToShape + } + + @Test + public void strokeForeThemeColors() throws Exception + { + //ExStart:StrokeForeThemeColors + //GistId:eeeec1fbf118e95e7df3f346c91ed726 + //ExFor:Stroke.ForeThemeColor + //ExFor:Stroke.ForeTintAndShade + //ExSummary:Shows how to set fore theme color and tint and shade. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertShape(ShapeType.TEXT_BOX, 100.0, 40.0); + Stroke stroke = shape.getStroke(); + stroke.setForeThemeColor(ThemeColor.DARK_1); + stroke.setForeTintAndShade(0.5); + + doc.save(getArtifactsDir() + "Shape.StrokeForeThemeColors.docx"); + //ExEnd:StrokeForeThemeColors + + doc = new Document(getArtifactsDir() + "Shape.StrokeForeThemeColors.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(ThemeColor.DARK_1, shape.getStroke().getForeThemeColor()); + Assert.assertEquals(0.5, shape.getStroke().getForeTintAndShade()); + } + + @Test + public void strokeBackThemeColors() throws Exception + { + //ExStart:StrokeBackThemeColors + //GistId:eeeec1fbf118e95e7df3f346c91ed726 + //ExFor:Stroke.BackThemeColor + //ExFor:Stroke.BackTintAndShade + //ExSummary:Shows how to set back theme color and tint and shade. + Document doc = new Document(getMyDir() + "Stroke gradient outline.docx"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + Stroke stroke = shape.getStroke(); + stroke.setBackThemeColor(ThemeColor.DARK_2); + stroke.setBackTintAndShade(0.2d); + + doc.save(getArtifactsDir() + "Shape.StrokeBackThemeColors.docx"); + //ExEnd:StrokeBackThemeColors + + doc = new Document(getArtifactsDir() + "Shape.StrokeBackThemeColors.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(ThemeColor.DARK_2, shape.getStroke().getBackThemeColor()); + double precision = 1e-6; + Assert.assertEquals(0.2d, precision, shape.getStroke().getBackTintAndShade()); + } + + @Test + public void textBoxOleControl() throws Exception + { + //ExStart:TextBoxOleControl + //GistId:eeeec1fbf118e95e7df3f346c91ed726 + //ExFor:TextBoxControl + //ExFor:TextBoxControl.Text + //ExFor:TextBoxControl.Type + //ExSummary:Shows how to change text of the TextBox OLE control. + Document doc = new Document(getMyDir() + "Textbox control.docm"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + TextBoxControl textBoxControl = (TextBoxControl)shape.getOleFormat().getOleControl(); + Assert.assertEquals("Aspose.Words test", textBoxControl.getText()); + + textBoxControl.setText("Updated text"); + Assert.assertEquals("Updated text", textBoxControl.getText()); + Assert.assertEquals(Forms2OleControlType.TEXTBOX, textBoxControl.getType()); + //ExEnd:TextBoxOleControl + } + + @Test + public void glow() throws Exception + { + //ExStart:Glow + //GistId:5f20ac02cb42c6b08481aa1c5b0cd3db + //ExFor:ShapeBase.Glow + //ExFor:GlowFormat + //ExFor:GlowFormat.Color + //ExFor:GlowFormat.Radius + //ExFor:GlowFormat.Transparency + //ExFor:GlowFormat.Remove() + //ExSummary:Shows how to interact with glow shape effect. + Document doc = new Document(getMyDir() + "Various shapes.docx"); + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + shape.getGlow().setColor(msColor.getSalmon()); + shape.getGlow().setRadius(30.0); + shape.getGlow().setTransparency(0.15); + + doc.save(getArtifactsDir() + "Shape.Glow.docx"); + + doc = new Document(getArtifactsDir() + "Shape.Glow.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + Assert.assertEquals(new Color((250), (128), (114), (217)).getRGB(), shape.getGlow().getColor().getRGB()); + Assert.assertEquals(30, shape.getGlow().getRadius()); + Assert.assertEquals(0.15d, 0.01d, shape.getGlow().getTransparency()); + + shape.getGlow().remove(); + + Assert.assertEquals(Color.BLACK.getRGB(), shape.getGlow().getColor().getRGB()); + Assert.assertEquals(0, shape.getGlow().getRadius()); + Assert.assertEquals(0, shape.getGlow().getTransparency()); + //ExEnd:Glow + } + + @Test + public void reflection() throws Exception + { + //ExStart:Reflection + //GistId:5f20ac02cb42c6b08481aa1c5b0cd3db + //ExFor:ShapeBase.Reflection + //ExFor:ReflectionFormat + //ExFor:ReflectionFormat.Size + //ExFor:ReflectionFormat.Blur + //ExFor:ReflectionFormat.Transparency + //ExFor:ReflectionFormat.Distance + //ExFor:ReflectionFormat.Remove() + //ExSummary:Shows how to interact with reflection shape effect. + Document doc = new Document(getMyDir() + "Various shapes.docx"); + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + shape.getReflection().setTransparency(0.37); + shape.getReflection().setSize(0.48); + shape.getReflection().setBlur(17.5); + shape.getReflection().setDistance(9.2); + + doc.save(getArtifactsDir() + "Shape.Reflection.docx"); + + doc = new Document(getArtifactsDir() + "Shape.Reflection.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + ReflectionFormat reflectionFormat = shape.getReflection(); + + Assert.assertEquals(0.37d, 0.01d, reflectionFormat.getTransparency()); + Assert.assertEquals(0.48d, 0.01d, reflectionFormat.getSize()); + Assert.assertEquals(17.5d, 0.01d, reflectionFormat.getBlur()); + Assert.assertEquals(9.2d, 0.01d, reflectionFormat.getDistance()); + + reflectionFormat.remove(); + + Assert.assertEquals(0, reflectionFormat.getTransparency()); + Assert.assertEquals(0, reflectionFormat.getSize()); + Assert.assertEquals(0, reflectionFormat.getBlur()); + Assert.assertEquals(0, reflectionFormat.getDistance()); + //ExEnd:Reflection + } + + @Test + public void softEdge() throws Exception + { + //ExStart:SoftEdge + //GistId:6e4482e7434754c31c6f2f6e4bf48bb1 + //ExFor:ShapeBase.SoftEdge + //ExFor:SoftEdgeFormat + //ExFor:SoftEdgeFormat.Radius + //ExFor:SoftEdgeFormat.Remove + //ExSummary:Shows how to work with soft edge formatting. + DocumentBuilder builder = new DocumentBuilder(); + Shape shape = builder.insertShape(ShapeType.RECTANGLE, 200.0, 200.0); + + // Apply soft edge to the shape. + shape.getSoftEdge().setRadius(30.0); + + builder.getDocument().save(getArtifactsDir() + "Shape.SoftEdge.docx"); + + // Load document with rectangle shape with soft edge. + Document doc = new Document(getArtifactsDir() + "Shape.SoftEdge.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + SoftEdgeFormat softEdgeFormat = shape.getSoftEdge(); + + // Check soft edge radius. + Assert.assertEquals(30, softEdgeFormat.getRadius()); + + // Remove soft edge from the shape. + softEdgeFormat.remove(); + + // Check radius of the removed soft edge. + Assert.assertEquals(0, softEdgeFormat.getRadius()); + //ExEnd:SoftEdge + } + + @Test + public void adjustments() throws Exception + { + //ExStart:Adjustments + //GistId:6e4482e7434754c31c6f2f6e4bf48bb1 + //ExFor:Shape.Adjustments + //ExFor:AdjustmentCollection + //ExFor:AdjustmentCollection.Count + //ExFor:AdjustmentCollection.Item(Int32) + //ExFor:Adjustment + //ExFor:Adjustment.Name + //ExFor:Adjustment.Value + //ExSummary:Shows how to work with adjustment raw values. + Document doc = new Document(getMyDir() + "Rounded rectangle shape.docx"); + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + AdjustmentCollection adjustments = shape.getAdjustments(); + Assert.assertEquals(1, adjustments.getCount()); + + Adjustment adjustment = adjustments.get(0); + Assert.assertEquals("adj", adjustment.getName()); + Assert.assertEquals(16667, adjustment.getValue()); + + adjustment.setValue(30000); + + doc.save(getArtifactsDir() + "Shape.Adjustments.docx"); + //ExEnd:Adjustments + + doc = new Document(getArtifactsDir() + "Shape.Adjustments.docx"); + shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + adjustments = shape.getAdjustments(); + Assert.assertEquals(1, adjustments.getCount()); + + adjustment = adjustments.get(0); + Assert.assertEquals("adj", adjustment.getName()); + Assert.assertEquals(30000, adjustment.getValue()); + } + + @Test + public void shadowFormatColor() throws Exception + { + //ExStart:ShadowFormatColor + //GistId:65919861586e42e24f61a3ccb65f8f4e + //ExFor:ShapeBase.ShadowFormat + //ExFor:ShadowFormat + //ExFor:ShadowFormat.Color + //ExFor:ShadowFormat.Type + //ExSummary:Shows how to get shadow color. + Document doc = new Document(getMyDir() + "Shadow color.docx"); + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + ShadowFormat shadowFormat = shape.getShadowFormat(); + + Assert.assertEquals(Color.RED.getRGB(), shadowFormat.getColor().getRGB()); + Assert.assertEquals(ShadowType.SHADOW_MIXED, shadowFormat.getType()); + //ExEnd:ShadowFormatColor + } + + @Test + public void setActiveXProperties() throws Exception + { + //ExStart:SetActiveXProperties + //GistId:ac8ba4eb35f3fbb8066b48c999da63b0 + //ExFor:Forms2OleControl.ForeColor + //ExFor:Forms2OleControl.BackColor + //ExFor:Forms2OleControl.Height + //ExFor:Forms2OleControl.Width + //ExSummary:Shows how to set properties for ActiveX control. + Document doc = new Document(getMyDir() + "ActiveX controls.docx"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + Forms2OleControl oleControl = (Forms2OleControl)shape.getOleFormat().getOleControl(); + oleControl.setForeColor(new Color((0x17), (0xE1), (0x35))); + oleControl.setBackColor(new Color((0x33), (0x97), (0xF4))); + oleControl.setHeight(100.54); + oleControl.setWidth(201.06); + //ExEnd:SetActiveXProperties + + Assert.assertEquals(new Color((0x17), (0xE1), (0x35)).getRGB(), oleControl.getForeColor().getRGB()); + Assert.assertEquals(new Color((0x33), (0x97), (0xF4)).getRGB(), oleControl.getBackColor().getRGB()); + Assert.assertEquals(100.54, oleControl.getHeight()); + Assert.assertEquals(201.06, oleControl.getWidth()); + } + + @Test + public void selectRadioControl() throws Exception + { + //ExStart:SelectRadioControl + //GistId:ac8ba4eb35f3fbb8066b48c999da63b0 + //ExFor:OptionButtonControl + //ExFor:OptionButtonControl.Selected + //ExFor:OptionButtonControl.Type + //ExSummary:Shows how to select radio button. + Document doc = new Document(getMyDir() + "Radio buttons.docx"); + + Shape shape1 = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + OptionButtonControl optionButton1 = (OptionButtonControl)shape1.getOleFormat().getOleControl(); + // Deselect selected first item. + optionButton1.setSelected(false); + + Shape shape2 = (Shape)doc.getChild(NodeType.SHAPE, 1, true); + OptionButtonControl optionButton2 = (OptionButtonControl)shape2.getOleFormat().getOleControl(); + // Select second option button. + optionButton2.setSelected(true); + + Assert.assertEquals(Forms2OleControlType.OPTION_BUTTON, optionButton1.getType()); + Assert.assertEquals(Forms2OleControlType.OPTION_BUTTON, optionButton2.getType()); + + doc.save(getArtifactsDir() + "Shape.SelectRadioControl.docx"); + //ExEnd:SelectRadioControl + } + + @Test + public void checkedCheckBox() throws Exception + { + //ExStart:CheckedCheckBox + //GistId:ac8ba4eb35f3fbb8066b48c999da63b0 + //ExFor:CheckBoxControl + //ExFor:CheckBoxControl.Checked + //ExFor:CheckBoxControl.Type + //ExFor:Forms2OleControlType + //ExSummary:Shows how to change state of the CheckBox control. + Document doc = new Document(getMyDir() + "ActiveX controls.docx"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + CheckBoxControl checkBoxControl = (CheckBoxControl)shape.getOleFormat().getOleControl(); + checkBoxControl.setChecked(true); + + Assert.assertEquals(true, checkBoxControl.getChecked()); + Assert.assertEquals(Forms2OleControlType.CHECK_BOX, checkBoxControl.getType()); + //ExEnd:CheckedCheckBox + } + + @Test + public void insertGroupShape() throws Exception + { + //ExStart:InsertGroupShape + //GistId:e06aa7a168b57907a5598e823a22bf0a + //ExFor:DocumentBuilder.InsertGroupShape(double, double, double, double, ShapeBase[]) + //ExFor:DocumentBuilder.InsertGroupShape(ShapeBase[]) + //ExSummary:Shows how to insert DML group shape. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape1 = builder.insertShape(ShapeType.RECTANGLE, 200.0, 250.0); + shape1.setLeft(20.0); + shape1.setTop(20.0); + shape1.getStroke().setColor(Color.RED); + + Shape shape2 = builder.insertShape(ShapeType.ELLIPSE, 150.0, 200.0); + shape2.setLeft(40.0); + shape2.setTop(50.0); + shape2.getStroke().setColor(msColor.getGreen()); + + // Dimensions for the new GroupShape node. + double left = 10.0; + double top = 10.0; + double width = 200.0; + double height = 300.0; + // Insert GroupShape node for the specified size which is inserted into the specified position. + GroupShape groupShape1 = builder.insertGroupShape(left, top, width, height, new Shape[] { shape1, shape2 }); + + // Insert GroupShape node which position and dimension will be calculated automatically. + Shape shape3 = (Shape)shape1.deepClone(true); + GroupShape groupShape2 = builder.insertGroupShape(shape3); + + doc.save(getArtifactsDir() + "Shape.InsertGroupShape.docx"); + //ExEnd:InsertGroupShape + } + + @Test + public void combineGroupShape() throws Exception + { + //ExStart:CombineGroupShape + //GistId:bb594993b5fe48692541e16f4d354ac2 + //ExFor:DocumentBuilder.InsertGroupShape(ShapeBase[]) + //ExSummary:Shows how to combine group shape with the shape. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape1 = builder.insertShape(ShapeType.RECTANGLE, 200.0, 250.0); + shape1.setLeft(20.0); + shape1.setTop(20.0); + shape1.getStroke().setColor(Color.RED); + + Shape shape2 = builder.insertShape(ShapeType.ELLIPSE, 150.0, 200.0); + shape2.setLeft(40.0); + shape2.setTop(50.0); + shape2.getStroke().setColor(msColor.getGreen()); + + // Combine shapes into a GroupShape node which is inserted into the specified position. + GroupShape groupShape1 = builder.insertGroupShape(shape1, shape2); + + // Combine Shape and GroupShape nodes. + Shape shape3 = (Shape)shape1.deepClone(true); + GroupShape groupShape2 = builder.insertGroupShape(groupShape1, shape3); + + doc.save(getArtifactsDir() + "Shape.CombineGroupShape.docx"); + //ExEnd:CombineGroupShape + + doc = new Document(getArtifactsDir() + "Shape.CombineGroupShape.docx"); + + NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); + for (Shape shape : (Iterable) shapes) + { + Assert.Is.Not.EqualTo(0)shape.getWidth()); + Assert.Is.Not.EqualTo(0)shape.getHeight()); + } + } + + @Test + public void insertCommandButton() throws Exception + { + //ExStart:InsertCommandButton + //GistId:bb594993b5fe48692541e16f4d354ac2 + //ExFor:CommandButtonControl + //ExFor:CommandButtonControl.#ctor + //ExFor:CommandButtonControl.Type + //ExFor:DocumentBuilder.InsertForms2OleControl(Forms2OleControl) + //ExSummary:Shows how to insert ActiveX control. + DocumentBuilder builder = new DocumentBuilder(); + + CommandButtonControl button1 = new CommandButtonControl(); + Shape shape = builder.insertForms2OleControl(button1); + Assert.assertEquals(Forms2OleControlType.COMMAND_BUTTON, button1.getType()); + //ExEnd:InsertCommandButton + } + + @Test + public void hidden() throws Exception + { + //ExStart:Hidden + //GistId:bb594993b5fe48692541e16f4d354ac2 + //ExFor:ShapeBase.Hidden + //ExSummary:Shows how to hide the shape. + Document doc = new Document(getMyDir() + "Shadow color.docx"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + if (!shape.getHidden()) + shape.setHidden(true); + + doc.save(getArtifactsDir() + "Shape.Hidden.docx"); + //ExEnd:Hidden + } + + @Test + public void commandButtonCaption() throws Exception + { + //ExStart:CommandButtonCaption + //GistId:366eb64fd56dec3c2eaa40410e594182 + //ExFor:Forms2OleControl.Caption + //ExSummary:Shows how to set caption for ActiveX control. + DocumentBuilder builder = new DocumentBuilder(); + + CommandButtonControl button1 = new CommandButtonControl(); { button1.setCaption("Button caption"); } + Shape shape = builder.insertForms2OleControl(button1); + Assert.assertEquals("Button caption", button1.getCaption()); + //ExEnd:CommandButtonCaption + } + + @Test + public void shadowFormatTransparency() throws Exception + { + //ExStart:ShadowFormatTransparency + //GistId:045648ef22da6b384ebcf0344717bfb5 + //ExFor:ShadowFormat.Color + //ExFor:ShadowFormat.Transparency + //ExSummary:Shows how to set a color with transparency. + Document doc = new Document(getMyDir() + "Shadow color.docx"); + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + ShadowFormat shadowFormat = shape.getShadowFormat(); + shadowFormat.setType(ShadowType.SHADOW_21); + shadowFormat.setColor(Color.RED); + shadowFormat.setTransparency(0.8); + + doc.save(getArtifactsDir() + "Shape.ShadowFormatTransparency.docx"); + //ExEnd:ShadowFormatTransparency + } +} + diff --git a/Examples/ApiExamples/JavaPorting/ExSignDocumentCustom.java b/Examples/ApiExamples/JavaPorting/ExSignDocumentCustom.java new file mode 100644 index 00000000..8de4d603 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExSignDocumentCustom.java @@ -0,0 +1,128 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.ms.System.msString; +import org.testng.Assert; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.SignatureLineOptions; +import com.aspose.words.SignatureLine; +import com.aspose.words.CertificateHolder; +import com.aspose.words.SignOptions; +import com.aspose.words.DigitalSignatureUtil; +import com.aspose.ms.System.Guid; +import java.util.ArrayList; + + +@Test +public class ExSignDocumentCustom extends ApiExampleBase +{ + //ExStart + //ExFor:CertificateHolder + //ExFor:SignatureLineOptions.Signer + //ExFor:SignatureLineOptions.SignerTitle + //ExFor:SignatureLine.Id + //ExFor:SignOptions.SignatureLineId + //ExFor:SignOptions.SignatureLineImage + //ExFor:DigitalSignatureUtil.Sign(String, String, CertificateHolder, SignOptions) + //ExSummary:Shows how to add a signature line to a document, and then sign it using a digital certificate. + @Test (description = "WORDSNET-16868") //ExSkip + public static void sign() throws Exception + { + String signeeName = "Ron Williams"; + String srcDocumentPath = getMyDir() + "Document.docx"; + String dstDocumentPath = getArtifactsDir() + "SignDocumentCustom.Sign.docx"; + String certificatePath = getMyDir() + "morzal.pfx"; + String certificatePassword = "aw"; + + createSignees(); + + Signee signeeInfo = mSignees.Find(c => msString.equals(c.getName(), signeeName)); + + if (signeeInfo != null) + signDocument(srcDocumentPath, dstDocumentPath, signeeInfo, certificatePath, certificatePassword); + else + Assert.fail("Signee does not exist."); + } + + /// + /// Creates a copy of a source document signed using provided signee information and X509 certificate. + /// + private static void signDocument(String srcDocumentPath, String dstDocumentPath, + Signee signeeInfo, String certificatePath, String certificatePassword) throws Exception + { + Document document = new Document(srcDocumentPath); + DocumentBuilder builder = new DocumentBuilder(document); + + // Configure and insert a signature line, an object in the document that will display a signature that we sign it with. + SignatureLineOptions signatureLineOptions = new SignatureLineOptions(); + { + signatureLineOptions.setSigner(signeeInfo.getName()); + signatureLineOptions.setSignerTitle(signeeInfo.getPosition()); + } + + SignatureLine signatureLine = builder.insertSignatureLine(signatureLineOptions).getSignatureLine(); + signatureLine.setIdInternal(signeeInfo.getPersonId()); + + // First, we will save an unsigned version of our document. + builder.getDocument().save(dstDocumentPath); + + CertificateHolder certificateHolder = CertificateHolder.create(certificatePath, certificatePassword); + + SignOptions signOptions = new SignOptions(); + { + signOptions.setSignatureLineId(signeeInfo.getPersonId()); + signOptions.setSignatureLineImage(signeeInfo.getImage()); + } + + // Overwrite the unsigned document we saved above with a version signed using the certificate. + DigitalSignatureUtil.sign(dstDocumentPath, dstDocumentPath, certificateHolder, signOptions); + } + + public static class Signee + { + public Guid getPersonId() { return mPersonId; }; public void setPersonId(Guid value) { mPersonId = value; }; + + private Guid mPersonId; + public String getName() { return mName; }; public void setName(String value) { mName = value; }; + + private String mName; + public String getPosition() { return mPosition; }; public void setPosition(String value) { mPosition = value; }; + + private String mPosition; + public byte[] getImage() { return mImage; }; public void setImage(byte[] value) { mImage = value; }; + + private byte[] mImage; + + public Signee(Guid guid, String name, String position, byte[] image) + { + setPersonId(guid); + setName(name); + setPosition(position); + setImage(image); + } + } + + private static void createSignees() throws Exception + { + String signImagePath = getImageDir() + "Logo.jpg"; + + mSignees = new ArrayList(); + { + mSignees.add(new Signee(Guid.newGuid(), "Ron Williams", "Chief Executive Officer", TestUtil.imageToByteArray(signImagePath))); + mSignees.add(new Signee(Guid.newGuid(), "Stephen Morse", "Head of Compliance", TestUtil.imageToByteArray(signImagePath))); + } + } + + private static ArrayList mSignees; + //ExEnd +} diff --git a/Examples/ApiExamples/JavaPorting/ExSmartTag.java b/Examples/ApiExamples/JavaPorting/ExSmartTag.java new file mode 100644 index 00000000..7aeef03e --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExSmartTag.java @@ -0,0 +1,237 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.SmartTag; +import com.aspose.words.Run; +import com.aspose.words.CustomXmlProperty; +import org.testng.Assert; +import com.aspose.words.NodeType; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.DocumentVisitor; +import com.aspose.words.VisitorAction; +import com.aspose.ms.System.msConsole; +import com.aspose.ms.System.msString; +import com.aspose.words.CustomXmlPropertyCollection; +import java.util.Iterator; + + +@Test +class ExSmartTag !Test class should be public in Java to run, please fix .Net source! extends ApiExampleBase +{ + //ExStart + //ExFor:CompositeNode.RemoveSmartTags + //ExFor:CustomXmlProperty + //ExFor:CustomXmlProperty.#ctor(String,String,String) + //ExFor:CustomXmlProperty.Name + //ExFor:CustomXmlProperty.Value + //ExFor:SmartTag + //ExFor:SmartTag.#ctor(DocumentBase) + //ExFor:SmartTag.Accept(DocumentVisitor) + //ExFor:SmartTag.AcceptStart(DocumentVisitor) + //ExFor:SmartTag.AcceptEnd(DocumentVisitor) + //ExFor:SmartTag.Element + //ExFor:SmartTag.Properties + //ExFor:SmartTag.Uri + //ExSummary:Shows how to create smart tags. + @Test //ExSkip + public void create() throws Exception + { + Document doc = new Document(); + + // A smart tag appears in a document with Microsoft Word recognizes a part of its text as some form of data, + // such as a name, date, or address, and converts it to a hyperlink that displays a purple dotted underline. + SmartTag smartTag = new SmartTag(doc); + + // Smart tags are composite nodes that contain their recognized text in its entirety. + // Add contents to this smart tag manually. + smartTag.appendChild(new Run(doc, "May 29, 2019")); + + // Microsoft Word may recognize the above contents as being a date. + // Smart tags use the "Element" property to reflect the type of data they contain. + smartTag.setElement("date"); + + // Some smart tag types process their contents further into custom XML properties. + smartTag.getProperties().add(new CustomXmlProperty("Day", "", "29")); + smartTag.getProperties().add(new CustomXmlProperty("Month", "", "5")); + smartTag.getProperties().add(new CustomXmlProperty("Year", "", "2019")); + + // Set the smart tag's URI to the default value. + smartTag.setUri("urn:schemas-microsoft-com:office:smarttags"); + + doc.getFirstSection().getBody().getFirstParagraph().appendChild(smartTag); + doc.getFirstSection().getBody().getFirstParagraph().appendChild(new Run(doc, " is a date. ")); + + // Create another smart tag for a stock ticker. + smartTag = new SmartTag(doc); + smartTag.setElement("stockticker"); + smartTag.setUri("urn:schemas-microsoft-com:office:smarttags"); + + smartTag.appendChild(new Run(doc, "MSFT")); + + doc.getFirstSection().getBody().getFirstParagraph().appendChild(smartTag); + doc.getFirstSection().getBody().getFirstParagraph().appendChild(new Run(doc, " is a stock ticker.")); + + // Print all the smart tags in our document using a document visitor. + doc.accept(new SmartTagPrinter()); + + // Older versions of Microsoft Word support smart tags. + doc.save(getArtifactsDir() + "SmartTag.Create.doc"); + + // Use the "RemoveSmartTags" method to remove all smart tags from a document. + Assert.assertEquals(2, doc.getChildNodes(NodeType.SMART_TAG, true).getCount()); + + doc.removeSmartTags(); + + Assert.assertEquals(0, doc.getChildNodes(NodeType.SMART_TAG, true).getCount()); + testCreate(new Document(getArtifactsDir() + "SmartTag.Create.doc")); //ExSkip + } + + /// + /// Prints visited smart tags and their contents. + /// + private static class SmartTagPrinter extends DocumentVisitor + { + /// + /// Called when a SmartTag node is encountered in the document. + /// + public /*override*/ /*VisitorAction*/int visitSmartTagStart(SmartTag smartTag) + { + System.out.println("Smart tag type: {smartTag.Element}"); + return VisitorAction.CONTINUE; + } + + /// + /// Called when the visiting of a SmartTag node is ended. + /// + public /*override*/ /*VisitorAction*/int visitSmartTagEnd(SmartTag smartTag) + { + System.out.println("\tContents: \"{smartTag.ToString(SaveFormat.Text)}\""); + + if (smartTag.getProperties().getCount() == 0) + { + System.out.println("\tContains no properties"); + } + else + { + msConsole.write("\tProperties: "); + String[] properties = new String[smartTag.getProperties().getCount()]; + int index = 0; + + for (CustomXmlProperty cxp : smartTag.getProperties()) + properties[index++] = $"\"{cxp.Name}\" = \"{cxp.Value}\""; + + System.out.println(msString.join(", ", properties)); + } + + return VisitorAction.CONTINUE; + } + } + //ExEnd + + @Test (enabled = false) + public void testCreate(Document doc) + { + SmartTag smartTag = (SmartTag)doc.getChild(NodeType.SMART_TAG, 0, true); + + Assert.assertEquals("date", smartTag.getElement()); + Assert.assertEquals("May 29, 2019", smartTag.getText()); + Assert.assertEquals("urn:schemas-microsoft-com:office:smarttags", smartTag.getUri()); + + Assert.assertEquals("Day", smartTag.getProperties().get(0).getName()); + Assert.assertEquals("", smartTag.getProperties().get(0).getUri()); + Assert.assertEquals("29", smartTag.getProperties().get(0).getValue()); + Assert.assertEquals("Month", smartTag.getProperties().get(1).getName()); + Assert.assertEquals("", smartTag.getProperties().get(1).getUri()); + Assert.assertEquals("5", smartTag.getProperties().get(1).getValue()); + Assert.assertEquals("Year", smartTag.getProperties().get(2).getName()); + Assert.assertEquals("", smartTag.getProperties().get(2).getUri()); + Assert.assertEquals("2019", smartTag.getProperties().get(2).getValue()); + + smartTag = (SmartTag)doc.getChild(NodeType.SMART_TAG, 1, true); + + Assert.assertEquals("stockticker", smartTag.getElement()); + Assert.assertEquals("MSFT", smartTag.getText()); + Assert.assertEquals("urn:schemas-microsoft-com:office:smarttags", smartTag.getUri()); + Assert.assertEquals(0, smartTag.getProperties().getCount()); + } + + @Test + public void properties() throws Exception + { + //ExStart + //ExFor:CustomXmlProperty.Uri + //ExFor:CustomXmlPropertyCollection + //ExFor:CustomXmlPropertyCollection.Add(CustomXmlProperty) + //ExFor:CustomXmlPropertyCollection.Clear + //ExFor:CustomXmlPropertyCollection.Contains(String) + //ExFor:CustomXmlPropertyCollection.Count + //ExFor:CustomXmlPropertyCollection.GetEnumerator + //ExFor:CustomXmlPropertyCollection.IndexOfKey(String) + //ExFor:CustomXmlPropertyCollection.Item(Int32) + //ExFor:CustomXmlPropertyCollection.Item(String) + //ExFor:CustomXmlPropertyCollection.Remove(String) + //ExFor:CustomXmlPropertyCollection.RemoveAt(Int32) + //ExSummary:Shows how to work with smart tag properties to get in depth information about smart tags. + Document doc = new Document(getMyDir() + "Smart tags.doc"); + + // A smart tag appears in a document with Microsoft Word recognizes a part of its text as some form of data, + // such as a name, date, or address, and converts it to a hyperlink that displays a purple dotted underline. + // In Word 2003, we can enable smart tags via "Tools" -> "AutoCorrect options..." -> "SmartTags". + // In our input document, there are three objects that Microsoft Word registered as smart tags. + // Smart tags may be nested, so this collection contains more. + SmartTag[] smartTags = doc.getChildNodes(NodeType.SMART_TAG, true).OfType().ToArray(); + + Assert.assertEquals(8, smartTags.length); + + // The "Properties" member of a smart tag contains its metadata, which will be different for each type of smart tag. + // The properties of a "date"-type smart tag contain its year, month, and day. + CustomXmlPropertyCollection properties = smartTags[7].getProperties(); + + Assert.assertEquals(4, properties.getCount()); + + Iterator enumerator = properties.iterator(); + try /*JAVA: was using*/ + { + while (enumerator.hasNext()) + { + System.out.println("Property name: {enumerator.Current.Name}, value: {enumerator.Current.Value}"); + Assert.assertEquals("", enumerator.next().getUri()); + } + } + finally { if (enumerator != null) enumerator.close(); } + + // We can also access the properties in various ways, such as a key-value pair. + Assert.assertTrue(properties.contains("Day")); + Assert.assertEquals("22", properties.get("Day").getValue()); + Assert.assertEquals("2003", properties.get(2).getValue()); + Assert.assertEquals(1, properties.indexOfKey("Month")); + + // Below are three ways of removing elements from the properties collection. + // 1 - Remove by index: + properties.removeAt(3); + + Assert.assertEquals(3, properties.getCount()); + + // 2 - Remove by name: + properties.remove("Year"); + + Assert.assertEquals(2, properties.getCount()); + + // 3 - Clear the entire collection at once: + properties.clear(); + + Assert.assertEquals(0, properties.getCount()); + //ExEnd + } +} + diff --git a/Examples/ApiExamples/JavaPorting/ExStructuredDocumentTag.java b/Examples/ApiExamples/JavaPorting/ExStructuredDocumentTag.java new file mode 100644 index 00000000..6eef92c9 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExStructuredDocumentTag.java @@ -0,0 +1,1441 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import com.aspose.ms.System.ms; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import java.util.ArrayList; +import com.aspose.words.StructuredDocumentTag; +import com.aspose.words.NodeType; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.SdtType; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.Style; +import com.aspose.words.StyleIdentifier; +import com.aspose.words.MarkupLevel; +import com.aspose.words.NodeCollection; +import com.aspose.words.Node; +import com.aspose.ms.System.msConsole; +import com.aspose.ms.System.Globalization.msCultureInfo; +import com.aspose.words.SdtDateStorageFormat; +import com.aspose.words.SdtCalendarType; +import com.aspose.ms.System.DateTime; +import java.awt.Color; +import com.aspose.words.SdtAppearance; +import com.aspose.words.GlossaryDocument; +import com.aspose.words.BuildingBlock; +import com.aspose.words.Section; +import com.aspose.words.Body; +import com.aspose.words.SdtListItemCollection; +import com.aspose.words.SdtListItem; +import java.util.Iterator; +import com.aspose.ms.System.Guid; +import com.aspose.words.CustomXmlPart; +import com.aspose.ms.System.Text.Encoding; +import com.aspose.words.CustomXmlPartCollection; +import com.aspose.words.StructuredDocumentTagRangeStart; +import com.aspose.words.CustomXmlSchemaCollection; +import com.aspose.words.Run; +import com.aspose.words.Table; +import com.aspose.words.Row; +import com.aspose.words.StructuredDocumentTagRangeEnd; +import com.aspose.words.StructuredDocumentTagCollection; +import com.aspose.words.IStructuredDocumentTag; +import com.aspose.words.Cell; +import com.aspose.words.Paragraph; +import com.aspose.words.SaveFormat; +import com.aspose.words.FindReplaceOptions; +import org.testng.annotations.DataProvider; + + +@Test +class ExStructuredDocumentTag !Test class should be public in Java to run, please fix .Net source! extends ApiExampleBase +{ + @Test + public void repeatingSection() throws Exception + { + //ExStart + //ExFor:StructuredDocumentTag.SdtType + //ExFor:IStructuredDocumentTag.SdtType + //ExSummary:Shows how to get the type of a structured document tag. + Document doc = new Document(getMyDir() + "Structured document tags.docx"); + + ArrayList tags = doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG, true) + .OfType().ToList(); + + Assert.assertEquals(SdtType.REPEATING_SECTION, tags.get(0).getSdtType()); + Assert.assertEquals(SdtType.REPEATING_SECTION_ITEM, tags.get(1).getSdtType()); + Assert.assertEquals(SdtType.RICH_TEXT, tags.get(2).getSdtType()); + //ExEnd + } + + @Test + public void flatOpcContent() throws Exception + { + //ExStart + //ExFor:StructuredDocumentTag.WordOpenXML + //ExFor:IStructuredDocumentTag.WordOpenXML + //ExSummary:Shows how to get XML contained within the node in the FlatOpc format. + Document doc = new Document(getMyDir() + "Structured document tags.docx"); + + ArrayList tags = doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG, true) + .OfType().ToList(); + + Assert.assertTrue(tags.get(0).getWordOpenXML() + .contains( + "")); + //ExEnd + } + + @Test + public void applyStyle() throws Exception + { + //ExStart + //ExFor:StructuredDocumentTag + //ExFor:StructuredDocumentTag.NodeType + //ExFor:StructuredDocumentTag.Style + //ExFor:StructuredDocumentTag.StyleName + //ExFor:StructuredDocumentTag.WordOpenXMLMinimal + //ExFor:MarkupLevel + //ExFor:SdtType + //ExSummary:Shows how to work with styles for content control elements. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Below are two ways to apply a style from the document to a structured document tag. + // 1 - Apply a style object from the document's style collection: + Style quoteStyle = doc.getStyles().getByStyleIdentifier(StyleIdentifier.QUOTE); + StructuredDocumentTag sdtPlainText = + new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.INLINE); { sdtPlainText.setStyle(quoteStyle); } + + // 2 - Reference a style in the document by name: + StructuredDocumentTag sdtRichText = + new StructuredDocumentTag(doc, SdtType.RICH_TEXT, MarkupLevel.INLINE); { sdtRichText.setStyleName("Quote"); } + + builder.insertNode(sdtPlainText); + builder.insertNode(sdtRichText); + + Assert.assertEquals(NodeType.STRUCTURED_DOCUMENT_TAG, sdtPlainText.getNodeType()); + + NodeCollection tags = doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG, true); + + for (Node node : (Iterable) tags) + { + StructuredDocumentTag sdt = (StructuredDocumentTag)node; + + System.out.println(sdt.getWordOpenXMLMinimal()); + + Assert.assertEquals(StyleIdentifier.QUOTE, sdt.getStyle().getStyleIdentifier()); + Assert.assertEquals("Quote", sdt.getStyleName()); + } + //ExEnd + } + + @Test + public void checkBox() throws Exception + { + //ExStart + //ExFor:StructuredDocumentTag.#ctor(DocumentBase, SdtType, MarkupLevel) + //ExFor:StructuredDocumentTag.Checked + //ExFor:StructuredDocumentTag.SetCheckedSymbol(Int32, String) + //ExFor:StructuredDocumentTag.SetUncheckedSymbol(Int32, String) + //ExSummary:Show how to create a structured document tag in the form of a check box. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + StructuredDocumentTag sdtCheckBox = + new StructuredDocumentTag(doc, SdtType.CHECKBOX, MarkupLevel.INLINE); { sdtCheckBox.setChecked(true); } + + // We can set the symbols used to represent the checked/unchecked state of a checkbox content control. + sdtCheckBox.setCheckedSymbol(0x00A9, "Times New Roman"); + sdtCheckBox.setUncheckedSymbol(0x00AE, "Times New Roman"); + + builder.insertNode(sdtCheckBox); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.CheckBox.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "StructuredDocumentTag.CheckBox.docx"); + + StructuredDocumentTag[] tags = doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG, true) + .OfType().ToArray(); + + Assert.assertEquals(true, tags[0].getChecked()); + Assert.assertEquals("", tags[0].getXmlMapping().getStoreItemId()); + } + + @Test (groups = "SkipMono") + public void date() throws Exception + { + //ExStart + //ExFor:StructuredDocumentTag.CalendarType + //ExFor:StructuredDocumentTag.DateDisplayFormat + //ExFor:StructuredDocumentTag.DateDisplayLocale + //ExFor:StructuredDocumentTag.DateStorageFormat + //ExFor:StructuredDocumentTag.FullDate + //ExFor:SdtCalendarType + //ExFor:SdtDateStorageFormat + //ExSummary:Shows how to prompt the user to enter a date with a structured document tag. + Document doc = new Document(); + + // Insert a structured document tag that prompts the user to enter a date. + // In Microsoft Word, this element is known as a "Date picker content control". + // When we click on the arrow on the right end of this tag in Microsoft Word, + // we will see a pop up in the form of a clickable calendar. + // We can use that popup to select a date that the tag will display. + StructuredDocumentTag sdtDate = new StructuredDocumentTag(doc, SdtType.DATE, MarkupLevel.INLINE); + + // Display the date, according to the Saudi Arabian Arabic locale. + sdtDate.setDateDisplayLocale(msCultureInfo.getCultureInfo("ar-SA").getLCID()); + + // Set the format with which to display the date. + sdtDate.setDateDisplayFormat("dd MMMM, yyyy"); + sdtDate.setDateStorageFormat(SdtDateStorageFormat.DATE_TIME); + + // Display the date according to the Hijri calendar. + sdtDate.setCalendarType(SdtCalendarType.HIJRI); + + // Before the user chooses a date in Microsoft Word, the tag will display the text "Click here to enter a date.". + // According to the tag's calendar, set the "FullDate" property to get the tag to display a default date. + sdtDate.setFullDateInternal(new DateTime(1440, 10, 20)); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertNode(sdtDate); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.Date.docx"); + //ExEnd + } + + @Test + public void plainText() throws Exception + { + //ExStart + //ExFor:StructuredDocumentTag.Color + //ExFor:StructuredDocumentTag.ContentsFont + //ExFor:StructuredDocumentTag.EndCharacterFont + //ExFor:StructuredDocumentTag.Id + //ExFor:StructuredDocumentTag.Level + //ExFor:StructuredDocumentTag.Multiline + //ExFor:IStructuredDocumentTag.Tag + //ExFor:StructuredDocumentTag.Tag + //ExFor:StructuredDocumentTag.Title + //ExFor:StructuredDocumentTag.RemoveSelfOnly + //ExFor:StructuredDocumentTag.Appearance + //ExSummary:Shows how to create a structured document tag in a plain text box and modify its appearance. + Document doc = new Document(); + + // Create a structured document tag that will contain plain text. + StructuredDocumentTag tag = new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.INLINE); + + // Set the title and color of the frame that appears when you mouse over the structured document tag in Microsoft Word. + tag.setTitle("My plain text"); + tag.setColor(Color.MAGENTA); + + // Set a tag for this structured document tag, which is obtainable + // as an XML element named "tag", with the string below in its "@val" attribute. + tag.setTag("MyPlainTextSDT"); + + // Every structured document tag has a random unique ID. + Assert.assertTrue(tag.getId() > 0); + + // Set the font for the text inside the structured document tag. + tag.getContentsFont().setName("Arial"); + + // Set the font for the text at the end of the structured document tag. + // Any text that we type in the document body after moving out of the tag with arrow keys will use this font. + tag.getEndCharacterFont().setName("Arial Black"); + + // By default, this is false and pressing enter while inside a structured document tag does nothing. + // When set to true, our structured document tag can have multiple lines. + + // Set the "Multiline" property to "false" to only allow the contents + // of this structured document tag to span a single line. + // Set the "Multiline" property to "true" to allow the tag to contain multiple lines of content. + tag.setMultiline(true); + + // Set the "Appearance" property to "SdtAppearance.Tags" to show tags around content. + // By default structured document tag shows as BoundingBox. + tag.setAppearance(SdtAppearance.TAGS); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertNode(tag); + + // Insert a clone of our structured document tag in a new paragraph. + StructuredDocumentTag tagClone = (StructuredDocumentTag)tag.deepClone(true); + builder.insertParagraph(); + builder.insertNode(tagClone); + + // Use the "RemoveSelfOnly" method to remove a structured document tag, while keeping its contents in the document. + tagClone.removeSelfOnly(); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.PlainText.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "StructuredDocumentTag.PlainText.docx"); + tag = (StructuredDocumentTag)doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + + Assert.assertEquals("My plain text", tag.getTitle()); + Assert.assertEquals(Color.MAGENTA.getRGB(), tag.getColor().getRGB()); + Assert.assertEquals("MyPlainTextSDT", tag.getTag()); + Assert.assertTrue(tag.getId() > 0); + Assert.assertEquals("Arial", tag.getContentsFont().getName()); + Assert.assertEquals("Arial Black", tag.getEndCharacterFont().getName()); + Assert.assertTrue(tag.getMultiline()); + Assert.assertEquals(SdtAppearance.TAGS, tag.getAppearance()); + } + + @Test (dataProvider = "isTemporaryDataProvider") + public void isTemporary(boolean isTemporary) throws Exception + { + //ExStart + //ExFor:StructuredDocumentTag.IsTemporary + //ExSummary:Shows how to make single-use controls. + Document doc = new Document(); + + // Insert a plain text structured document tag, + // which will act as a plain text form that the user may enter text into. + StructuredDocumentTag tag = new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.INLINE); + + // Set the "IsTemporary" property to "true" to make the structured document tag disappear and + // assimilate its contents into the document after the user edits it once in Microsoft Word. + // Set the "IsTemporary" property to "false" to allow the user to edit the contents + // of the structured document tag any number of times. + tag.isTemporary(isTemporary); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.write("Please enter text: "); + builder.insertNode(tag); + + // Insert another structured document tag in the form of a check box and set its default state to "checked". + tag = new StructuredDocumentTag(doc, SdtType.CHECKBOX, MarkupLevel.INLINE); + tag.setChecked(true); + + // Set the "IsTemporary" property to "true" to make the check box become a symbol + // once the user clicks on it in Microsoft Word. + // Set the "IsTemporary" property to "false" to allow the user to click on the check box any number of times. + tag.isTemporary(isTemporary); + + builder.write("\nPlease click the check box: "); + builder.insertNode(tag); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.IsTemporary.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "StructuredDocumentTag.IsTemporary.docx"); + + Assert.That(doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG, true).Count(sdt => ((StructuredDocumentTag)sdt).IsTemporary == isTemporary), assertEquals(2, ); + } + + //JAVA-added data provider for test method + @DataProvider(name = "isTemporaryDataProvider") + public static Object[][] isTemporaryDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test (dataProvider = "placeholderBuildingBlockDataProvider") + public void placeholderBuildingBlock(boolean isShowingPlaceholderText) throws Exception + { + //ExStart + //ExFor:StructuredDocumentTag.IsShowingPlaceholderText + //ExFor:IStructuredDocumentTag.IsShowingPlaceholderText + //ExFor:StructuredDocumentTag.Placeholder + //ExFor:StructuredDocumentTag.PlaceholderName + //ExFor:IStructuredDocumentTag.Placeholder + //ExFor:IStructuredDocumentTag.PlaceholderName + //ExSummary:Shows how to use a building block's contents as a custom placeholder text for a structured document tag. + Document doc = new Document(); + + // Insert a plain text structured document tag of the "PlainText" type, which will function as a text box. + // The contents that it will display by default are a "Click here to enter text." prompt. + StructuredDocumentTag tag = new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.INLINE); + + // We can get the tag to display the contents of a building block instead of the default text. + // First, add a building block with contents to the glossary document. + GlossaryDocument glossaryDoc = doc.getGlossaryDocument(); + + BuildingBlock substituteBlock = new BuildingBlock(glossaryDoc); + substituteBlock.setName("Custom Placeholder"); + substituteBlock.appendChild(new Section(glossaryDoc)); + substituteBlock.getFirstSection().appendChild(new Body(glossaryDoc)); + substituteBlock.getFirstSection().getBody().appendParagraph("Custom placeholder text."); + + glossaryDoc.appendChild(substituteBlock); + + // Then, use the structured document tag's "PlaceholderName" property to reference that building block by name. + tag.setPlaceholderName("Custom Placeholder"); + + // If "PlaceholderName" refers to an existing block in the parent document's glossary document, + // we will be able to verify the building block via the "Placeholder" property. + Assert.assertEquals(substituteBlock, tag.getPlaceholder()); + + // Set the "IsShowingPlaceholderText" property to "true" to treat the + // structured document tag's current contents as placeholder text. + // This means that clicking on the text box in Microsoft Word will immediately highlight all the tag's contents. + // Set the "IsShowingPlaceholderText" property to "false" to get the + // structured document tag to treat its contents as text that a user has already entered. + // Clicking on this text in Microsoft Word will place the blinking cursor at the clicked location. + tag.isShowingPlaceholderText(isShowingPlaceholderText); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertNode(tag); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.PlaceholderBuildingBlock.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "StructuredDocumentTag.PlaceholderBuildingBlock.docx"); + tag = (StructuredDocumentTag)doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + substituteBlock = (BuildingBlock)doc.getGlossaryDocument().getChild(NodeType.BUILDING_BLOCK, 0, true); + + Assert.assertEquals("Custom Placeholder", substituteBlock.getName()); + Assert.assertEquals(isShowingPlaceholderText, tag.isShowingPlaceholderText()); + Assert.assertEquals(substituteBlock, tag.getPlaceholder()); + Assert.assertEquals(substituteBlock.getName(), tag.getPlaceholderName()); + } + + //JAVA-added data provider for test method + @DataProvider(name = "placeholderBuildingBlockDataProvider") + public static Object[][] placeholderBuildingBlockDataProvider() throws Exception + { + return new Object[][] + { + {false}, + {true}, + }; + } + + @Test + public void lock() throws Exception + { + //ExStart + //ExFor:StructuredDocumentTag.LockContentControl + //ExFor:StructuredDocumentTag.LockContents + //ExFor:IStructuredDocumentTag.LockContentControl + //ExFor:IStructuredDocumentTag.LockContents + //ExSummary:Shows how to apply editing restrictions to structured document tags. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a plain text structured document tag, which acts as a text box that prompts the user to fill it in. + StructuredDocumentTag tag = new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.INLINE); + + // Set the "LockContents" property to "true" to prohibit the user from editing this text box's contents. + tag.setLockContents(true); + builder.write("The contents of this structured document tag cannot be edited: "); + builder.insertNode(tag); + + tag = new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.INLINE); + + // Set the "LockContentControl" property to "true" to prohibit the user from + // deleting this structured document tag manually in Microsoft Word. + tag.setLockContentControl(true); + + builder.insertParagraph(); + builder.write("This structured document tag cannot be deleted but its contents can be edited: "); + builder.insertNode(tag); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.Lock.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "StructuredDocumentTag.Lock.docx"); + tag = (StructuredDocumentTag)doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + + Assert.assertTrue(tag.getLockContents()); + Assert.assertFalse(tag.getLockContentControl()); + + tag = (StructuredDocumentTag)doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 1, true); + + Assert.assertFalse(tag.getLockContents()); + Assert.assertTrue(tag.getLockContentControl()); + } + + @Test + public void listItemCollection() throws Exception + { + //ExStart + //ExFor:SdtListItem + //ExFor:SdtListItem.#ctor(String) + //ExFor:SdtListItem.#ctor(String,String) + //ExFor:SdtListItem.DisplayText + //ExFor:SdtListItem.Value + //ExFor:SdtListItemCollection + //ExFor:SdtListItemCollection.Add(SdtListItem) + //ExFor:SdtListItemCollection.Clear + //ExFor:SdtListItemCollection.Count + //ExFor:SdtListItemCollection.GetEnumerator + //ExFor:SdtListItemCollection.Item(Int32) + //ExFor:SdtListItemCollection.RemoveAt(Int32) + //ExFor:SdtListItemCollection.SelectedValue + //ExFor:StructuredDocumentTag.ListItems + //ExSummary:Shows how to work with drop down-list structured document tags. + Document doc = new Document(); + StructuredDocumentTag tag = new StructuredDocumentTag(doc, SdtType.DROP_DOWN_LIST, MarkupLevel.BLOCK); + doc.getFirstSection().getBody().appendChild(tag); + + // A drop-down list structured document tag is a form that allows the user to + // select an option from a list by left-clicking and opening the form in Microsoft Word. + // The "ListItems" property contains all list items, and each list item is an "SdtListItem". + SdtListItemCollection listItems = tag.getListItems(); + listItems.add(new SdtListItem("Value 1")); + + Assert.assertEquals(listItems.get(0).getDisplayText(), listItems.get(0).getValue()); + + // Add 3 more list items. Initialize these items using a different constructor to the first item + // to display strings that are different from their values. + listItems.add(new SdtListItem("Item 2", "Value 2")); + listItems.add(new SdtListItem("Item 3", "Value 3")); + listItems.add(new SdtListItem("Item 4", "Value 4")); + + Assert.assertEquals(4, listItems.getCount()); + + // The drop-down list is displaying the first item. Assign a different list item to the "SelectedValue" to display it. + listItems.setSelectedValue(listItems.get(3)); + + Assert.assertEquals("Value 4", listItems.getSelectedValue().getValue()); + + // Enumerate over the collection and print each element. + Iterator enumerator = listItems.iterator(); + try /*JAVA: was using*/ + { + while (enumerator.hasNext()) + if (enumerator.next() != null) + System.out.println("List item: {enumerator.Current.DisplayText}, value: {enumerator.Current.Value}"); + } + finally { if (enumerator != null) enumerator.close(); } + + // Remove the last list item. + listItems.removeAt(3); + + Assert.assertEquals(3, listItems.getCount()); + + // Since our drop-down control is set to display the removed item by default, give it an item to display which exists. + listItems.setSelectedValue(listItems.get(1)); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.ListItemCollection.docx"); + + // Use the "Clear" method to empty the entire drop-down item collection at once. + listItems.clear(); + + Assert.assertEquals(0, listItems.getCount()); + //ExEnd + } + + @Test + public void creatingCustomXml() throws Exception + { + //ExStart + //ExFor:CustomXmlPart + //ExFor:CustomXmlPart.Clone + //ExFor:CustomXmlPart.Data + //ExFor:CustomXmlPart.Id + //ExFor:CustomXmlPart.Schemas + //ExFor:CustomXmlPartCollection + //ExFor:CustomXmlPartCollection.Add(CustomXmlPart) + //ExFor:CustomXmlPartCollection.Add(String, String) + //ExFor:CustomXmlPartCollection.Clear + //ExFor:CustomXmlPartCollection.Clone + //ExFor:CustomXmlPartCollection.Count + //ExFor:CustomXmlPartCollection.GetById(String) + //ExFor:CustomXmlPartCollection.GetEnumerator + //ExFor:CustomXmlPartCollection.Item(Int32) + //ExFor:CustomXmlPartCollection.RemoveAt(Int32) + //ExFor:Document.CustomXmlParts + //ExFor:StructuredDocumentTag.XmlMapping + //ExFor:IStructuredDocumentTag.XmlMapping + //ExFor:XmlMapping.SetMapping(CustomXmlPart, String, String) + //ExSummary:Shows how to create a structured document tag with custom XML data. + Document doc = new Document(); + + // Construct an XML part that contains data and add it to the document's collection. + // If we enable the "Developer" tab in Microsoft Word, + // we can find elements from this collection in the "XML Mapping Pane", along with a few default elements. + String xmlPartId = Guid.newGuid().toString("B"); + String xmlPartContent = "Hello world!"; + CustomXmlPart xmlPart = doc.getCustomXmlParts().add(xmlPartId, xmlPartContent); + + Assert.assertEquals(Encoding.getASCII().getBytes(xmlPartContent), xmlPart.getData()); + Assert.assertEquals(xmlPartId, xmlPart.getId()); + + // Below are two ways to refer to XML parts. + // 1 - By an index in the custom XML part collection: + Assert.assertEquals(xmlPart, doc.getCustomXmlParts().get(0)); + + // 2 - By GUID: + Assert.assertEquals(xmlPart, doc.getCustomXmlParts().getById(xmlPartId)); + + // Add an XML schema association. + xmlPart.getSchemas().add("http://www.w3.org/2001/XMLSchema"); + + // Clone a part, and then insert it into the collection. + CustomXmlPart xmlPartClone = xmlPart.deepClone(); + xmlPartClone.setId(Guid.newGuid().toString("B")); + doc.getCustomXmlParts().add(xmlPartClone); + + Assert.assertEquals(2, doc.getCustomXmlParts().getCount()); + + // Iterate through the collection and print the contents of each part. + Iterator enumerator = doc.getCustomXmlParts().iterator(); + try /*JAVA: was using*/ + { + int index = 0; + while (enumerator.hasNext()) + { + System.out.println("XML part index {index}, ID: {enumerator.Current.Id}"); + System.out.println("\tContent: {Encoding.UTF8.GetString(enumerator.Current.Data)}"); + index++; + } + } + finally { if (enumerator != null) enumerator.close(); } + + // Use the "RemoveAt" method to remove the cloned part by index. + doc.getCustomXmlParts().removeAt(1); + + Assert.assertEquals(1, doc.getCustomXmlParts().getCount()); + + // Clone the XML parts collection, and then use the "Clear" method to remove all its elements at once. + CustomXmlPartCollection customXmlParts = doc.getCustomXmlParts().deepClone(); + customXmlParts.clear(); + + // Create a structured document tag that will display our part's contents and insert it into the document body. + StructuredDocumentTag tag = new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.BLOCK); + tag.getXmlMapping().setMapping(xmlPart, "/root[1]/text[1]", ""); + + doc.getFirstSection().getBody().appendChild(tag); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.CustomXml.docx"); + //ExEnd + + Assert.assertTrue(DocumentHelper.compareDocs(getArtifactsDir() + "StructuredDocumentTag.CustomXml.docx", getGoldsDir() + "StructuredDocumentTag.CustomXml Gold.docx")); + + doc = new Document(getArtifactsDir() + "StructuredDocumentTag.CustomXml.docx"); + xmlPart = doc.getCustomXmlParts().get(0); + + Assert.DoesNotThrow(() => Guid.parse(xmlPart.getId())); + Assert.assertEquals("Hello world!", Encoding.getUTF8().getString(xmlPart.getData())); + Assert.assertEquals("http://www.w3.org/2001/XMLSchema", xmlPart.getSchemas().get(0)); + + tag = (StructuredDocumentTag)doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + Assert.assertEquals("Hello world!", tag.getText().trim()); + Assert.assertEquals("/root[1]/text[1]", tag.getXmlMapping().getXPath()); + Assert.assertEquals("", tag.getXmlMapping().getPrefixMappings()); + Assert.assertEquals(xmlPart.getDataChecksum(), tag.getXmlMapping().getCustomXmlPart().getDataChecksum()); + } + + @Test + public void dataChecksum() throws Exception + { + //ExStart + //ExFor:CustomXmlPart.DataChecksum + //ExSummary:Shows how the checksum is calculated in a runtime. + Document doc = new Document(); + + StructuredDocumentTag richText = new StructuredDocumentTag(doc, SdtType.RICH_TEXT, MarkupLevel.BLOCK); + doc.getFirstSection().getBody().appendChild(richText); + + // The checksum is read-only and computed using the data of the corresponding custom XML data part. + richText.getXmlMapping().setMapping(doc.getCustomXmlParts().add(Guid.newGuid().toString(), + "ContentControl"), "/root/text", ""); + + long checksum = richText.getXmlMapping().getCustomXmlPart().getDataChecksum(); + msConsole.writeLine(checksum); + + richText.getXmlMapping().setMapping(doc.getCustomXmlParts().add(Guid.newGuid().toString(), + "Updated ContentControl"), "/root/text", ""); + + long updatedChecksum = richText.getXmlMapping().getCustomXmlPart().getDataChecksum(); + msConsole.writeLine(updatedChecksum); + + // We changed the XmlPart of the tag, and the checksum was updated at runtime. + Assert.Is.Not.EqualTo(checksum)updatedChecksum); + //ExEnd + } + + @Test + public void xmlMapping() throws Exception + { + //ExStart + //ExFor:XmlMapping + //ExFor:XmlMapping.CustomXmlPart + //ExFor:XmlMapping.Delete + //ExFor:XmlMapping.IsMapped + //ExFor:XmlMapping.PrefixMappings + //ExFor:XmlMapping.XPath + //ExSummary:Shows how to set XML mappings for custom XML parts. + Document doc = new Document(); + + // Construct an XML part that contains text and add it to the document's CustomXmlPart collection. + String xmlPartId = Guid.newGuid().toString("B"); + String xmlPartContent = "Text element #1Text element #2"; + CustomXmlPart xmlPart = doc.getCustomXmlParts().add(xmlPartId, xmlPartContent); + + Assert.assertEquals("Text element #1Text element #2", Encoding.getUTF8().getString(xmlPart.getData())); + + // Create a structured document tag that will display the contents of our CustomXmlPart. + StructuredDocumentTag tag = new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.BLOCK); + + // Set a mapping for our structured document tag. This mapping will instruct + // our structured document tag to display a portion of the XML part's text contents that the XPath points to. + // In this case, it will be contents of the the second "" element of the first "" element: "Text element #2". + tag.getXmlMapping().setMapping(xmlPart, "/root[1]/text[2]", "xmlns:ns='http://www.w3.org/2001/XMLSchema'"); + + Assert.assertTrue(tag.getXmlMapping().isMapped()); + Assert.assertEquals(xmlPart, tag.getXmlMapping().getCustomXmlPart()); + Assert.assertEquals("/root[1]/text[2]", tag.getXmlMapping().getXPath()); + Assert.assertEquals("xmlns:ns='http://www.w3.org/2001/XMLSchema'", tag.getXmlMapping().getPrefixMappings()); + + // Add the structured document tag to the document to display the content from our custom part. + doc.getFirstSection().getBody().appendChild(tag); + doc.save(getArtifactsDir() + "StructuredDocumentTag.XmlMapping.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "StructuredDocumentTag.XmlMapping.docx"); + xmlPart = doc.getCustomXmlParts().get(0); + + Assert.DoesNotThrow(() => Guid.parse(xmlPart.getId())); + Assert.assertEquals("Text element #1Text element #2", Encoding.getUTF8().getString(xmlPart.getData())); + + tag = (StructuredDocumentTag)doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + Assert.assertEquals("Text element #2", tag.getText().trim()); + Assert.assertEquals("/root[1]/text[2]", tag.getXmlMapping().getXPath()); + Assert.assertEquals("xmlns:ns='http://www.w3.org/2001/XMLSchema'", tag.getXmlMapping().getPrefixMappings()); + } + + @Test + public void structuredDocumentTagRangeStartXmlMapping() throws Exception + { + //ExStart + //ExFor:StructuredDocumentTagRangeStart.XmlMapping + //ExSummary:Shows how to set XML mappings for the range start of a structured document tag. + Document doc = new Document(getMyDir() + "Multi-section structured document tags.docx"); + + // Construct an XML part that contains text and add it to the document's CustomXmlPart collection. + String xmlPartId = Guid.newGuid().toString("B"); + String xmlPartContent = "Text element #1Text element #2"; + CustomXmlPart xmlPart = doc.getCustomXmlParts().add(xmlPartId, xmlPartContent); + + Assert.assertEquals("Text element #1Text element #2", Encoding.getUTF8().getString(xmlPart.getData())); + + // Create a structured document tag that will display the contents of our CustomXmlPart in the document. + StructuredDocumentTagRangeStart sdtRangeStart = (StructuredDocumentTagRangeStart)doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_START, 0, true); + + // If we set a mapping for our structured document tag, + // it will only display a portion of the CustomXmlPart that the XPath points to. + // This XPath will point to the contents second "" element of the first "" element of our CustomXmlPart. + sdtRangeStart.getXmlMapping().setMapping(xmlPart, "/root[1]/text[2]", null); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.StructuredDocumentTagRangeStartXmlMapping.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "StructuredDocumentTag.StructuredDocumentTagRangeStartXmlMapping.docx"); + xmlPart = doc.getCustomXmlParts().get(0); + + Assert.DoesNotThrow(() => Guid.parse(xmlPart.getId())); + Assert.assertEquals("Text element #1Text element #2", Encoding.getUTF8().getString(xmlPart.getData())); + + sdtRangeStart = (StructuredDocumentTagRangeStart)doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_START, 0, true); + Assert.assertEquals("/root[1]/text[2]", sdtRangeStart.getXmlMapping().getXPath()); + } + + @Test + public void customXmlSchemaCollection() throws Exception + { + //ExStart + //ExFor:CustomXmlSchemaCollection + //ExFor:CustomXmlSchemaCollection.Add(String) + //ExFor:CustomXmlSchemaCollection.Clear + //ExFor:CustomXmlSchemaCollection.Clone + //ExFor:CustomXmlSchemaCollection.Count + //ExFor:CustomXmlSchemaCollection.GetEnumerator + //ExFor:CustomXmlSchemaCollection.IndexOf(String) + //ExFor:CustomXmlSchemaCollection.Item(Int32) + //ExFor:CustomXmlSchemaCollection.Remove(String) + //ExFor:CustomXmlSchemaCollection.RemoveAt(Int32) + //ExSummary:Shows how to work with an XML schema collection. + Document doc = new Document(); + + String xmlPartId = Guid.newGuid().toString("B"); + String xmlPartContent = "Hello, World!"; + CustomXmlPart xmlPart = doc.getCustomXmlParts().add(xmlPartId, xmlPartContent); + + // Add an XML schema association. + xmlPart.getSchemas().add("http://www.w3.org/2001/XMLSchema"); + + // Clone the custom XML part's XML schema association collection, + // and then add a couple of new schemas to the clone. + CustomXmlSchemaCollection schemas = xmlPart.getSchemas().deepClone(); + schemas.add("http://www.w3.org/2001/XMLSchema-instance"); + schemas.add("http://schemas.microsoft.com/office/2006/metadata/contentType"); + + Assert.assertEquals(3, schemas.getCount()); + Assert.assertEquals(2, schemas.indexOf("http://schemas.microsoft.com/office/2006/metadata/contentType")); + + // Enumerate the schemas and print each element. + Iterator enumerator = schemas.iterator(); + try /*JAVA: was using*/ + { + while (enumerator.hasNext()) + System.out.println(enumerator.next()); + } + finally { if (enumerator != null) enumerator.close(); } + + // Below are three ways of removing schemas from the collection. + // 1 - Remove a schema by index: + schemas.removeAt(2); + + // 2 - Remove a schema by value: + schemas.remove("http://www.w3.org/2001/XMLSchema"); + + // 3 - Use the "Clear" method to empty the collection at once. + schemas.clear(); + + Assert.assertEquals(0, schemas.getCount()); + //ExEnd + } + + @Test + public void customXmlPartStoreItemIdReadOnly() throws Exception + { + //ExStart + //ExFor:XmlMapping.StoreItemId + //ExSummary:Shows how to get the custom XML data identifier of an XML part. + Document doc = new Document(getMyDir() + "Custom XML part in structured document tag.docx"); + + // Structured document tags have IDs in the form of GUIDs. + StructuredDocumentTag tag = (StructuredDocumentTag)doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + + Assert.assertEquals("{F3029283-4FF8-4DD2-9F31-395F19ACEE85}", tag.getXmlMapping().getStoreItemId()); + //ExEnd + } + + @Test + public void customXmlPartStoreItemIdReadOnlyNull() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + StructuredDocumentTag sdtCheckBox = + new StructuredDocumentTag(doc, SdtType.CHECKBOX, MarkupLevel.INLINE); { sdtCheckBox.setChecked(true); } + + builder.insertNode(sdtCheckBox); + + doc = DocumentHelper.saveOpen(doc); + + StructuredDocumentTag sdt = (StructuredDocumentTag)doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + System.out.println("The Id of your custom xml part is: " + sdt.getXmlMapping().getStoreItemId()); + } + + @Test + public void clearTextFromStructuredDocumentTags() throws Exception + { + //ExStart + //ExFor:StructuredDocumentTag.Clear + //ExSummary:Shows how to delete contents of structured document tag elements. + Document doc = new Document(); + + // Create a plain text structured document tag, and then append it to the document. + StructuredDocumentTag tag = new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.BLOCK); + doc.getFirstSection().getBody().appendChild(tag); + + // This structured document tag, which is in the form of a text box, already displays placeholder text. + Assert.assertEquals("Click here to enter text.", tag.getText().trim()); + Assert.assertTrue(tag.isShowingPlaceholderText()); + + // Create a building block with text contents. + GlossaryDocument glossaryDoc = doc.getGlossaryDocument(); + BuildingBlock substituteBlock = new BuildingBlock(glossaryDoc); + substituteBlock.setName("My placeholder"); + substituteBlock.appendChild(new Section(glossaryDoc)); + substituteBlock.getFirstSection().ensureMinimum(); + substituteBlock.getFirstSection().getBody().getFirstParagraph().appendChild(new Run(glossaryDoc, "Custom placeholder text.")); + glossaryDoc.appendChild(substituteBlock); + + // Set the structured document tag's "PlaceholderName" property to our building block's name to get + // the structured document tag to display the contents of the building block in place of the original default text. + tag.setPlaceholderName("My placeholder"); + + Assert.assertEquals("Custom placeholder text.", tag.getText().trim()); + Assert.assertTrue(tag.isShowingPlaceholderText()); + + // Edit the text of the structured document tag and hide the placeholder text. + Run run = (Run)tag.getChild(NodeType.RUN, 0, true); + run.setText("New text."); + tag.isShowingPlaceholderText(false); + + Assert.assertEquals("New text.", tag.getText().trim()); + + // Use the "Clear" method to clear this structured document tag's contents and display the placeholder again. + tag.clear(); + + Assert.assertTrue(tag.isShowingPlaceholderText()); + Assert.assertEquals("Custom placeholder text.", tag.getText().trim()); + //ExEnd + } + + @Test + public void accessToBuildingBlockPropertiesFromDocPartObjSdt() throws Exception + { + Document doc = new Document(getMyDir() + "Structured document tags with building blocks.docx"); + + StructuredDocumentTag docPartObjSdt = + (StructuredDocumentTag)doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + + Assert.assertEquals(SdtType.DOC_PART_OBJ, docPartObjSdt.getSdtType()); + Assert.assertEquals("Table of Contents", docPartObjSdt.getBuildingBlockGallery()); + } + + @Test + public void accessToBuildingBlockPropertiesFromPlainTextSdt() throws Exception + { + Document doc = new Document(getMyDir() + "Structured document tags with building blocks.docx"); + + StructuredDocumentTag plainTextSdt = + (StructuredDocumentTag)doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 1, true); + + Assert.assertEquals(SdtType.PLAIN_TEXT, plainTextSdt.getSdtType()); + Assert.Throws(() => { String _ =plainTextSdt.getBuildingBlockGallery(); }, + "BuildingBlockType is only accessible for BuildingBlockGallery SDT type."); + } + + @Test + public void buildingBlockCategories() throws Exception + { + //ExStart + //ExFor:StructuredDocumentTag.BuildingBlockCategory + //ExFor:StructuredDocumentTag.BuildingBlockGallery + //ExSummary:Shows how to insert a structured document tag as a building block, and set its category and gallery. + Document doc = new Document(); + + StructuredDocumentTag buildingBlockSdt = + new StructuredDocumentTag(doc, SdtType.BUILDING_BLOCK_GALLERY, MarkupLevel.BLOCK); + { + buildingBlockSdt.setBuildingBlockCategory("Built-in"); + buildingBlockSdt.setBuildingBlockGallery("Table of Contents"); + } + + doc.getFirstSection().getBody().appendChild(buildingBlockSdt); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.BuildingBlockCategories.docx"); + //ExEnd + + buildingBlockSdt = + (StructuredDocumentTag)doc.getFirstSection().getBody().getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + + Assert.assertEquals(SdtType.BUILDING_BLOCK_GALLERY, buildingBlockSdt.getSdtType()); + Assert.assertEquals("Table of Contents", buildingBlockSdt.getBuildingBlockGallery()); + Assert.assertEquals("Built-in", buildingBlockSdt.getBuildingBlockCategory()); + } + + @Test + public void updateSdtContent() throws Exception + { + Document doc = new Document(); + + // Insert a drop-down list structured document tag. + StructuredDocumentTag tag = new StructuredDocumentTag(doc, SdtType.DROP_DOWN_LIST, MarkupLevel.BLOCK); + tag.getListItems().add(new SdtListItem("Value 1")); + tag.getListItems().add(new SdtListItem("Value 2")); + tag.getListItems().add(new SdtListItem("Value 3")); + + // The drop-down list currently displays "Choose an item" as the default text. + // Set the "SelectedValue" property to one of the list items to get the tag to + // display that list item's value instead of the default text. + tag.getListItems().setSelectedValue(tag.getListItems().get(1)); + + doc.getFirstSection().getBody().appendChild(tag); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.UpdateSdtContent.pdf"); + } + + @Test + public void usePdfDocumentForUpdateSdtContent() throws Exception + { + updateSdtContent(); + + Aspose.Pdf.Document pdfDoc = new Aspose.Pdf.Document(getArtifactsDir() + "StructuredDocumentTag.UpdateSdtContent.pdf"); + TextAbsorber textAbsorber = new TextAbsorber(); + textAbsorber.Visit(pdfDoc); + + Assert.That(textAbsorber.Text, assertEquals("Value 2", ); + } + + @Test + public void fillTableUsingRepeatingSectionItem() throws Exception + { + //ExStart + //ExFor:SdtType + //ExSummary:Shows how to fill a table with data from in an XML part. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + CustomXmlPart xmlPart = doc.getCustomXmlParts().add("Books", + "" + + "" + + "Everyday Italian" + + "Giada De Laurentiis" + + "" + + "" + + "The C Programming Language" + + "Brian W. Kernighan, Dennis M. Ritchie" + + "" + + "" + + "Learning XML" + + "Erik T. Ray" + + "" + + ""); + + // Create headers for data from the XML content. + Table table = builder.startTable(); + builder.insertCell(); + builder.write("Title"); + builder.insertCell(); + builder.write("Author"); + builder.endRow(); + builder.endTable(); + + // Create a table with a repeating section inside. + StructuredDocumentTag repeatingSectionSdt = + new StructuredDocumentTag(doc, SdtType.REPEATING_SECTION, MarkupLevel.ROW); + repeatingSectionSdt.getXmlMapping().setMapping(xmlPart, "/books[1]/book", ""); + table.appendChild(repeatingSectionSdt); + + // Add repeating section item inside the repeating section and mark it as a row. + // This table will have a row for each element that we can find in the XML document + // using the "/books[1]/book" XPath, of which there are three. + StructuredDocumentTag repeatingSectionItemSdt = + new StructuredDocumentTag(doc, SdtType.REPEATING_SECTION_ITEM, MarkupLevel.ROW); + repeatingSectionSdt.appendChild(repeatingSectionItemSdt); + + Row row = new Row(doc); + repeatingSectionItemSdt.appendChild(row); + + // Map XML data with created table cells for the title and author of each book. + StructuredDocumentTag titleSdt = + new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.CELL); + titleSdt.getXmlMapping().setMapping(xmlPart, "/books[1]/book[1]/title[1]", ""); + row.appendChild(titleSdt); + + StructuredDocumentTag authorSdt = + new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.CELL); + authorSdt.getXmlMapping().setMapping(xmlPart, "/books[1]/book[1]/author[1]", ""); + row.appendChild(authorSdt); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.RepeatingSectionItem.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "StructuredDocumentTag.RepeatingSectionItem.docx"); + ArrayList tags = doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG, true).OfType().ToList(); + + Assert.assertEquals("/books[1]/book", tags.get(0).getXmlMapping().getXPath()); + Assert.assertEquals("", tags.get(0).getXmlMapping().getPrefixMappings()); + + Assert.assertEquals("", tags.get(1).getXmlMapping().getXPath()); + Assert.assertEquals("", tags.get(1).getXmlMapping().getPrefixMappings()); + + Assert.assertEquals("/books[1]/book[1]/title[1]", tags.get(2).getXmlMapping().getXPath()); + Assert.assertEquals("", tags.get(2).getXmlMapping().getPrefixMappings()); + + Assert.assertEquals("/books[1]/book[1]/author[1]", tags.get(3).getXmlMapping().getXPath()); + Assert.assertEquals("", tags.get(3).getXmlMapping().getPrefixMappings()); + + Assert.assertEquals("Title\u0007Author\u0007\u0007" + + "Everyday Italian\u0007Giada De Laurentiis\u0007\u0007" + + "The C Programming Language\u0007Brian W. Kernighan, Dennis M. Ritchie\u0007\u0007" + + "Learning XML\u0007Erik T. Ray\u0007\u0007", doc.getFirstSection().getBody().getTables().get(0).getText().trim()); + } + + @Test + public void customXmlPart() throws Exception + { + String xmlString = + "" + + "" + + "" + + "John" + + "Doe" + + "" + + "" + + "Jane" + + "Doe" + + "" + + ""; + + Document doc = new Document(); + + // Insert the full XML document as a custom document part. + // We can find the mapping for this part in Microsoft Word via "Developer" -> "XML Mapping Pane", if it is enabled. + CustomXmlPart xmlPart = doc.getCustomXmlParts().add(Guid.newGuid().toString("B"), xmlString); + + // Create a structured document tag, which will use an XPath to refer to a single element from the XML. + StructuredDocumentTag sdt = new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.BLOCK); + sdt.getXmlMapping().setMapping(xmlPart, "Company//Employee[@id='2']/FirstName", ""); + + // Add the StructuredDocumentTag to the document to display the element in the text. + doc.getFirstSection().getBody().appendChild(sdt); + } + + @Test + public void multiSectionTags() throws Exception + { + //ExStart + //ExFor:StructuredDocumentTagRangeStart + //ExFor:IStructuredDocumentTag.Id + //ExFor:StructuredDocumentTagRangeStart.Id + //ExFor:StructuredDocumentTagRangeStart.Title + //ExFor:StructuredDocumentTagRangeStart.PlaceholderName + //ExFor:StructuredDocumentTagRangeStart.IsShowingPlaceholderText + //ExFor:StructuredDocumentTagRangeStart.LockContentControl + //ExFor:StructuredDocumentTagRangeStart.LockContents + //ExFor:IStructuredDocumentTag.Level + //ExFor:StructuredDocumentTagRangeStart.Level + //ExFor:StructuredDocumentTagRangeStart.RangeEnd + //ExFor:IStructuredDocumentTag.Color + //ExFor:StructuredDocumentTagRangeStart.Color + //ExFor:StructuredDocumentTagRangeStart.SdtType + //ExFor:StructuredDocumentTagRangeStart.WordOpenXML + //ExFor:StructuredDocumentTagRangeStart.Tag + //ExFor:StructuredDocumentTagRangeEnd + //ExFor:StructuredDocumentTagRangeEnd.Id + //ExSummary:Shows how to get the properties of multi-section structured document tags. + Document doc = new Document(getMyDir() + "Multi-section structured document tags.docx"); + + StructuredDocumentTagRangeStart rangeStartTag = + ms.as(doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_START, true).get(0), StructuredDocumentTagRangeStart.class); + StructuredDocumentTagRangeEnd rangeEndTag = + ms.as(doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_END, true).get(0), StructuredDocumentTagRangeEnd.class); + + Assert.assertEquals(rangeStartTag.getId(), rangeEndTag.getId()); //ExSkip + Assert.assertEquals(NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_START, rangeStartTag.getNodeType()); //ExSkip + Assert.assertEquals(NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_END, rangeEndTag.getNodeType()); //ExSkip + + System.out.println("StructuredDocumentTagRangeStart values:"); + System.out.println("\t|Id: {rangeStartTag.Id}"); + System.out.println("\t|Title: {rangeStartTag.Title}"); + System.out.println("\t|PlaceholderName: {rangeStartTag.PlaceholderName}"); + System.out.println("\t|IsShowingPlaceholderText: {rangeStartTag.IsShowingPlaceholderText}"); + System.out.println("\t|LockContentControl: {rangeStartTag.LockContentControl}"); + System.out.println("\t|LockContents: {rangeStartTag.LockContents}"); + System.out.println("\t|Level: {rangeStartTag.Level}"); + System.out.println("\t|NodeType: {rangeStartTag.NodeType}"); + System.out.println("\t|RangeEnd: {rangeStartTag.RangeEnd}"); + System.out.println("\t|Color: {rangeStartTag.Color.ToArgb()}"); + System.out.println("\t|SdtType: {rangeStartTag.SdtType}"); + System.out.println("\t|FlatOpcContent: {rangeStartTag.WordOpenXML}"); + System.out.println("\t|Tag: {rangeStartTag.Tag}\n"); + + System.out.println("StructuredDocumentTagRangeEnd values:"); + System.out.println("\t|Id: {rangeEndTag.Id}"); + System.out.println("\t|NodeType: {rangeEndTag.NodeType}"); + //ExEnd + } + + @Test + public void sdtChildNodes() throws Exception + { + //ExStart + //ExFor:StructuredDocumentTagRangeStart.GetChildNodes(NodeType, bool) + //ExSummary:Shows how to get child nodes of StructuredDocumentTagRangeStart. + Document doc = new Document(getMyDir() + "Multi-section structured document tags.docx"); + StructuredDocumentTagRangeStart tag = + ms.as(doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_START, true).get(0), StructuredDocumentTagRangeStart.class); + + System.out.println("StructuredDocumentTagRangeStart values:"); + System.out.println("\t|Child nodes count: {tag.GetChildNodes(NodeType.Any, false).Count}\n"); + + for (Node node : (Iterable) tag.getChildNodes(NodeType.ANY, false)) + System.out.println("\t|Child node type: {node.NodeType}"); + + for (Node node : (Iterable) tag.getChildNodes(NodeType.RUN, true)) + System.out.println("\t|Child node text: {node.GetText()}"); + //ExEnd + } + + //ExStart + //ExFor:StructuredDocumentTagRangeStart.#ctor(DocumentBase, SdtType) + //ExFor:StructuredDocumentTagRangeEnd.#ctor(DocumentBase, int) + //ExFor:StructuredDocumentTagRangeStart.RemoveSelfOnly + //ExFor:StructuredDocumentTagRangeStart.RemoveAllChildren + //ExSummary:Shows how to create/remove structured document tag and its content. + @Test //ExSkip + public void sdtRangeExtendedMethods() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("StructuredDocumentTag element"); + + StructuredDocumentTagRangeStart rangeStart = insertStructuredDocumentTagRanges(doc); + + // Removes ranged structured document tag, but keeps content inside. + rangeStart.removeSelfOnly(); + + rangeStart = (StructuredDocumentTagRangeStart)doc.getChild( + NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_START, 0, false); + Assert.assertEquals(null, rangeStart); + + StructuredDocumentTagRangeEnd rangeEnd = (StructuredDocumentTagRangeEnd)doc.getChild( + NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_END, 0, false); + + Assert.assertEquals(null, rangeEnd); + Assert.assertEquals("StructuredDocumentTag element", doc.getText().trim()); + + rangeStart = insertStructuredDocumentTagRanges(doc); + + Node paragraphNode = rangeStart.LastOrDefault(); + Assert.That(paragraphNode?.GetText().Trim(), assertEquals("StructuredDocumentTag element", ); + + // Removes ranged structured document tag and content inside. + rangeStart.removeAllChildren(); + + paragraphNode = rangeStart.LastOrDefault(); + Assert.That(paragraphNode?.GetText(), assertEquals(null, ); + } + + @Test (enabled = false) + public StructuredDocumentTagRangeStart insertStructuredDocumentTagRanges(Document doc) + { + StructuredDocumentTagRangeStart rangeStart = new StructuredDocumentTagRangeStart(doc, SdtType.PLAIN_TEXT); + StructuredDocumentTagRangeEnd rangeEnd = new StructuredDocumentTagRangeEnd(doc, rangeStart.getId()); + + doc.getFirstSection().getBody().insertBefore(rangeStart, doc.getFirstSection().getBody().getFirstParagraph()); + doc.getLastSection().getBody().insertAfter(rangeEnd, doc.getFirstSection().getBody().getFirstParagraph()); + + return rangeStart; + } + //ExEnd + + @Test + public void getSdt() throws Exception + { + //ExStart + //ExFor:Range.StructuredDocumentTags + //ExFor:StructuredDocumentTagCollection.Remove(int) + //ExFor:StructuredDocumentTagCollection.RemoveAt(int) + //ExSummary:Shows how to remove structured document tag. + Document doc = new Document(getMyDir() + "Structured document tags.docx"); + + StructuredDocumentTagCollection structuredDocumentTags = doc.getRange().getStructuredDocumentTags(); + IStructuredDocumentTag sdt; + for (int i = 0; i < structuredDocumentTags.getCount(); i++) + { + sdt = structuredDocumentTags.get(i); + System.out.println(sdt.getTitle()); + } + + sdt = structuredDocumentTags.getById(1691867797); + Assert.assertEquals(1691867797, sdt.getId()); + + Assert.assertEquals(5, structuredDocumentTags.getCount()); + // Remove the structured document tag by Id. + structuredDocumentTags.remove(1691867797); + // Remove the structured document tag at position 0. + structuredDocumentTags.removeAt(0); + Assert.assertEquals(3, structuredDocumentTags.getCount()); + //ExEnd + } + + @Test + public void rangeSdt() throws Exception + { + //ExStart + //ExFor:StructuredDocumentTagCollection + //ExFor:StructuredDocumentTagCollection.GetById(int) + //ExFor:StructuredDocumentTagCollection.GetByTitle(String) + //ExFor:IStructuredDocumentTag.IsMultiSection + //ExFor:IStructuredDocumentTag.Title + //ExSummary:Shows how to get structured document tag. + Document doc = new Document(getMyDir() + "Structured document tags by id.docx"); + + // Get the structured document tag by Id. + IStructuredDocumentTag sdt = doc.getRange().getStructuredDocumentTags().getById(1160505028); + msConsole.writeLine(sdt.isMultiSection()); + System.out.println(sdt.getTitle()); + + // Get the structured document tag or ranged tag by Title. + sdt = doc.getRange().getStructuredDocumentTags().getByTitle("Alias4"); + msConsole.writeLine(sdt.getId()); + //ExEnd + } + + @Test + public void sdtAtRowLevel() throws Exception + { + //ExStart + //ExFor:SdtType + //ExSummary:Shows how to create group structured document tag at the Row level. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + + // Create a Group structured document tag at the Row level. + StructuredDocumentTag groupSdt = new StructuredDocumentTag(doc, SdtType.GROUP, MarkupLevel.ROW); + table.appendChild(groupSdt); + groupSdt.isShowingPlaceholderText(false); + groupSdt.removeAllChildren(); + + // Create a child row of the structured document tag. + Row row = new Row(doc); + groupSdt.appendChild(row); + + Cell cell = new Cell(doc); + row.appendChild(cell); + + builder.endTable(); + + // Insert cell contents. + cell.ensureMinimum(); + builder.moveTo(cell.getLastParagraph()); + builder.write("Lorem ipsum dolor."); + + // Insert text after the table. + builder.moveTo(table.getNextSibling()); + builder.write("Nulla blandit nisi."); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.SdtAtRowLevel.docx"); + //ExEnd + } + + @Test + public void ignoreStructuredDocumentTags() throws Exception + { + //ExStart + //ExFor:FindReplaceOptions.IgnoreStructuredDocumentTags + //ExSummary:Shows how to ignore content of tags from replacement. + Document doc = new Document(getMyDir() + "Structured document tags.docx"); + + // This paragraph contains SDT. + Paragraph p = (Paragraph)doc.getFirstSection().getBody().getChild(NodeType.PARAGRAPH, 2, true); + String textToSearch = p.toString(SaveFormat.TEXT).trim(); + + FindReplaceOptions options = new FindReplaceOptions(); { options.setIgnoreStructuredDocumentTags(true); } + doc.getRange().replace(textToSearch, "replacement", options); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.IgnoreStructuredDocumentTags.docx"); + //ExEnd + + doc = new Document(getArtifactsDir() + "StructuredDocumentTag.IgnoreStructuredDocumentTags.docx"); + Assert.assertEquals("This document contains Structured Document Tags with text inside them\r\rRepeatingSection\rRichText\rreplacement", doc.getText().trim()); + } + + @Test + public void citation() throws Exception + { + //ExStart + //ExFor:SdtType + //ExSummary:Shows how to create a structured document tag of the Citation type. + Document doc = new Document(); + + StructuredDocumentTag sdt = new StructuredDocumentTag(doc, SdtType.CITATION, MarkupLevel.INLINE); + Paragraph paragraph = doc.getFirstSection().getBody().getFirstParagraph(); + paragraph.appendChild(sdt); + + // Create a Citation field. + DocumentBuilder builder = new DocumentBuilder(doc); + builder.moveToParagraph(0, -1); + builder.insertField("CITATION Ath22 \\l 1033 ", "(John Lennon, 2022)"); + + // Move the field to the structured document tag. + while (sdt.getNextSibling() != null) + sdt.appendChild(sdt.getNextSibling()); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.Citation.docx"); + //ExEnd + } + + @Test + public void rangeStartWordOpenXmlMinimal() throws Exception + { + //ExStart:RangeStartWordOpenXmlMinimal + //GistId:470c0da51e4317baae82ad9495747fed + //ExFor:StructuredDocumentTagRangeStart.WordOpenXMLMinimal + //ExSummary:Shows how to get minimal XML contained within the node in the FlatOpc format. + Document doc = new Document(getMyDir() + "Multi-section structured document tags.docx"); + StructuredDocumentTagRangeStart tag = + ms.as(doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_START, 0, true), StructuredDocumentTagRangeStart.class); + + Assert.assertTrue(tag.getWordOpenXMLMinimal() + .contains( + "")); + Assert.assertFalse(tag.getWordOpenXMLMinimal().contains("xmlns:w16cid=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\"")); + //ExEnd:RangeStartWordOpenXmlMinimal + } + + @Test + public void removeSelfOnly() throws Exception + { + //ExStart:RemoveSelfOnly + //GistId:e386727403c2341ce4018bca370a5b41 + //ExFor:IStructuredDocumentTag + //ExFor:IStructuredDocumentTag.GetChildNodes(NodeType, bool) + //ExFor:IStructuredDocumentTag.RemoveSelfOnly + //ExSummary:Shows how to remove structured document tag, but keeps content inside. + Document doc = new Document(getMyDir() + "Structured document tags.docx"); + + // This collection provides a unified interface for accessing ranged and non-ranged structured tags. + Iterable sdts = doc.getRange().getStructuredDocumentTags().ToList(); + Assert.That(sdts.Count(), assertEquals(5, ); + + // Here we can get child nodes from the common interface of ranged and non-ranged structured tags. + for (IStructuredDocumentTag sdt : sdts) + if (sdt.getChildNodes(NodeType.ANY, false).getCount() > 0) + sdt.removeSelfOnly(); + + sdts = doc.getRange().getStructuredDocumentTags().ToList(); + Assert.That(sdts.Count(), assertEquals(0, ); + //ExEnd:RemoveSelfOnly + } + + @Test + public void appearance() throws Exception + { + //ExStart:Appearance + //GistId:a775441ecb396eea917a2717cb9e8f8f + //ExFor:SdtAppearance + //ExFor:StructuredDocumentTagRangeStart.Appearance + //ExFor:IStructuredDocumentTag.Appearance + //ExSummary:Shows how to show tag around content. + Document doc = new Document(getMyDir() + "Multi-section structured document tags.docx"); + StructuredDocumentTagRangeStart tag = + ms.as(doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_START, 0, true), StructuredDocumentTagRangeStart.class); + + if (tag.getAppearance() == SdtAppearance.HIDDEN) + tag.setAppearance(SdtAppearance.TAGS); + //ExEnd:Appearance + } + + @Test + public void insertStructuredDocumentTag() throws Exception + { + //ExStart:InsertStructuredDocumentTag + //GistId:e06aa7a168b57907a5598e823a22bf0a + //ExFor:DocumentBuilder.InsertStructuredDocumentTag(SdtType) + //ExSummary:Shows how to simply insert structured document tag. + Document doc = new Document(getMyDir() + "Rendering.docx"); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.moveTo(doc.getFirstSection().getBody().getParagraphs().get(3)); + // Note, that only following StructuredDocumentTag types are allowed for insertion: + // SdtType.PlainText, SdtType.RichText, SdtType.Checkbox, SdtType.DropDownList, + // SdtType.ComboBox, SdtType.Picture, SdtType.Date. + // Markup level of inserted StructuredDocumentTag will be detected automatically and depends on position being inserted at. + // Added StructuredDocumentTag will inherit paragraph and font formatting from cursor position. + StructuredDocumentTag sdtPlain = builder.insertStructuredDocumentTag(SdtType.PLAIN_TEXT); + + doc.save(getArtifactsDir() + "StructuredDocumentTag.InsertStructuredDocumentTag.docx"); + //ExEnd:InsertStructuredDocumentTag + } +} + diff --git a/Examples/ApiExamples/JavaPorting/ExStyles.java b/Examples/ApiExamples/JavaPorting/ExStyles.java new file mode 100644 index 00000000..44ae4c09 --- /dev/null +++ b/Examples/ApiExamples/JavaPorting/ExStyles.java @@ -0,0 +1,443 @@ +// Copyright (c) 2001-2025 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package ApiExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import java.util.Iterator; +import com.aspose.words.Style; +import com.aspose.ms.System.msConsole; +import com.aspose.words.StyleType; +import java.awt.Color; +import com.aspose.words.DocumentBuilder; +import com.aspose.ms.System.Drawing.msColor; +import com.aspose.words.StyleCollection; +import com.aspose.words.Paragraph; +import com.aspose.words.NodeType; +import com.aspose.words.StyleIdentifier; +import com.aspose.words.TabStop; +import com.aspose.words.TabAlignment; +import com.aspose.words.TabLeader; +import com.aspose.words.ParagraphAlignment; +import com.aspose.words.ListTemplate; +import com.aspose.words.LineStyle; + + +@Test +public class ExStyles extends ApiExampleBase +{ + @Test + public void styles() throws Exception + { + //ExStart + //ExFor:DocumentBase.Styles + //ExFor:Style.Document + //ExFor:Style.Name + //ExFor:Style.IsHeading + //ExFor:Style.IsQuickStyle + //ExFor:Style.NextParagraphStyleName + //ExFor:Style.Styles + //ExFor:Style.Type + //ExFor:StyleCollection.Document + //ExFor:StyleCollection.GetEnumerator + //ExSummary:Shows how to access a document's style collection. + Document doc = new Document(); + + Assert.assertEquals(4, doc.getStyles().getCount()); + + // Enumerate and list all the styles that a document created using Aspose.Words contains by default. + Iterator + + + This is Squarish Sans CT Regular. + + \ No newline at end of file diff --git a/Examples/Data/Hyperlinks.docx b/Examples/Data/Hyperlinks.docx new file mode 100644 index 00000000..b25d0e4c Binary files /dev/null and b/Examples/Data/Hyperlinks.docx differ diff --git a/Examples/Data/Id prefix.docx b/Examples/Data/Id prefix.docx new file mode 100644 index 00000000..17606f00 Binary files /dev/null and b/Examples/Data/Id prefix.docx differ diff --git a/Examples/Data/Iframe.htm b/Examples/Data/Iframe.htm new file mode 100644 index 00000000..b81a8313 --- /dev/null +++ b/Examples/Data/Iframe.htm @@ -0,0 +1,7 @@ + + +

          Heading of frame

          +
          +

          End of frame.

          + + \ No newline at end of file diff --git a/Examples/Data/Iframes.html b/Examples/Data/Iframes.html new file mode 100644 index 00000000..9487411b --- /dev/null +++ b/Examples/Data/Iframes.html @@ -0,0 +1,5 @@ + + + + + diff --git a/Examples/Data/Image bullet points.docx b/Examples/Data/Image bullet points.docx new file mode 100644 index 00000000..b0487f5f Binary files /dev/null and b/Examples/Data/Image bullet points.docx differ diff --git a/Examples/Data/Images.docx b/Examples/Data/Images.docx new file mode 100644 index 00000000..b17ac7d7 Binary files /dev/null and b/Examples/Data/Images.docx differ diff --git a/Examples/Data/Images.html b/Examples/Data/Images.html new file mode 100644 index 00000000..4644490c --- /dev/null +++ b/Examples/Data/Images.html @@ -0,0 +1,14 @@ + + + + + + + +

          My heading

          +

          This is my paragraph. Images:

          +My image +My image + + + \ No newline at end of file diff --git a/Examples/Data/Images.pdf b/Examples/Data/Images.pdf new file mode 100644 index 00000000..cf5b28ba Binary files /dev/null and b/Examples/Data/Images.pdf differ diff --git a/Examples/Data/Images/Barcode.png b/Examples/Data/Images/Barcode.png new file mode 100644 index 00000000..057ce1d1 Binary files /dev/null and b/Examples/Data/Images/Barcode.png differ diff --git a/Examples/Data/Images/Enhanced Windows MetaFile.emf b/Examples/Data/Images/Enhanced Windows MetaFile.emf new file mode 100644 index 00000000..b52b35c0 Binary files /dev/null and b/Examples/Data/Images/Enhanced Windows MetaFile.emf differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ImageToPdf/Test.gif b/Examples/Data/Images/Graphics Interchange Format.gif similarity index 100% rename from Examples/src/main/resources/com/aspose/words/examples/loading_saving/ImageToPdf/Test.gif rename to Examples/Data/Images/Graphics Interchange Format.gif diff --git a/Examples/Data/Images/Logo icon.ico b/Examples/Data/Images/Logo icon.ico new file mode 100644 index 00000000..4e5629c5 Binary files /dev/null and b/Examples/Data/Images/Logo icon.ico differ diff --git a/Examples/Data/Images/Logo.jpg b/Examples/Data/Images/Logo.jpg new file mode 100644 index 00000000..5a6c2894 Binary files /dev/null and b/Examples/Data/Images/Logo.jpg differ diff --git a/Examples/Data/Images/Microsoft Visio drawing.vsd b/Examples/Data/Images/Microsoft Visio drawing.vsd new file mode 100644 index 00000000..2ffa7948 Binary files /dev/null and b/Examples/Data/Images/Microsoft Visio drawing.vsd differ diff --git a/Examples/Data/Images/RightF.jpg b/Examples/Data/Images/RightF.jpg new file mode 100644 index 00000000..b548779d Binary files /dev/null and b/Examples/Data/Images/RightF.jpg differ diff --git a/Examples/Data/Images/Scalable Vector Graphics.svg b/Examples/Data/Images/Scalable Vector Graphics.svg new file mode 100644 index 00000000..3ee4576c --- /dev/null +++ b/Examples/Data/Images/Scalable Vector Graphics.svg @@ -0,0 +1,871 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Examples/Data/Images/Tagged Image File Format.tiff b/Examples/Data/Images/Tagged Image File Format.tiff new file mode 100644 index 00000000..7707ecf6 Binary files /dev/null and b/Examples/Data/Images/Tagged Image File Format.tiff differ diff --git a/Examples/Data/Images/Transparent background logo.png b/Examples/Data/Images/Transparent background logo.png new file mode 100644 index 00000000..43f228e6 Binary files /dev/null and b/Examples/Data/Images/Transparent background logo.png differ diff --git a/Examples/Data/Images/WebP image.webp b/Examples/Data/Images/WebP image.webp new file mode 100644 index 00000000..9f7dba6f Binary files /dev/null and b/Examples/Data/Images/WebP image.webp differ diff --git a/Examples/Data/Images/Windows MetaFile.wmf b/Examples/Data/Images/Windows MetaFile.wmf new file mode 100644 index 00000000..d2adc0f4 Binary files /dev/null and b/Examples/Data/Images/Windows MetaFile.wmf differ diff --git a/Examples/Data/Images/WrongF.jpg b/Examples/Data/Images/WrongF.jpg new file mode 100644 index 00000000..ce3b8803 Binary files /dev/null and b/Examples/Data/Images/WrongF.jpg differ diff --git a/Examples/Data/Ink object.docx b/Examples/Data/Ink object.docx new file mode 100644 index 00000000..263d6d1a Binary files /dev/null and b/Examples/Data/Ink object.docx differ diff --git a/Examples/Data/JavaScript in HREF.docx b/Examples/Data/JavaScript in HREF.docx new file mode 100644 index 00000000..6e654161 Binary files /dev/null and b/Examples/Data/JavaScript in HREF.docx differ diff --git a/Examples/Data/Korean backslash symbol.docx b/Examples/Data/Korean backslash symbol.docx new file mode 100644 index 00000000..2c5f3aa0 Binary files /dev/null and b/Examples/Data/Korean backslash symbol.docx differ diff --git a/Examples/Data/Layout entities.docx b/Examples/Data/Layout entities.docx new file mode 100644 index 00000000..b403a627 Binary files /dev/null and b/Examples/Data/Layout entities.docx differ diff --git a/Examples/Data/Legacy control character.doc b/Examples/Data/Legacy control character.doc new file mode 100644 index 00000000..b7252375 Binary files /dev/null and b/Examples/Data/Legacy control character.doc differ diff --git a/Examples/Data/Legacy drop-down.docx b/Examples/Data/Legacy drop-down.docx new file mode 100644 index 00000000..4832b805 Binary files /dev/null and b/Examples/Data/Legacy drop-down.docx differ diff --git a/Examples/Data/Legacy fields.doc b/Examples/Data/Legacy fields.doc new file mode 100644 index 00000000..ef4951c7 Binary files /dev/null and b/Examples/Data/Legacy fields.doc differ diff --git a/Examples/Data/Linked fields.docx b/Examples/Data/Linked fields.docx new file mode 100644 index 00000000..069168fd Binary files /dev/null and b/Examples/Data/Linked fields.docx differ diff --git a/Examples/Data/Linked image.docx b/Examples/Data/Linked image.docx new file mode 100644 index 00000000..fb713936 Binary files /dev/null and b/Examples/Data/Linked image.docx differ diff --git a/Examples/Data/List destination.docx b/Examples/Data/List destination.docx new file mode 100644 index 00000000..b1af52a4 Binary files /dev/null and b/Examples/Data/List destination.docx differ diff --git a/Examples/Data/List item.docx b/Examples/Data/List item.docx new file mode 100644 index 00000000..8a7c2a2d Binary files /dev/null and b/Examples/Data/List item.docx differ diff --git a/Examples/Data/List of people.csv b/Examples/Data/List of people.csv new file mode 100644 index 00000000..8f9d4b99 --- /dev/null +++ b/Examples/Data/List of people.csv @@ -0,0 +1,5 @@ +Name;Age;Money;GotKids;Birth +John Doe;30;1160.90;true;1989-04-01 4:00:00 pm +Jane Doe;27;3010.15;false;1992-01-31 07:00:00 am +John Smith;51;60.70;true;1968-03-08 1:00:00 pm +$John Smith;51;60.70;true;1968-03-08 1:00:00 pm diff --git a/Examples/Data/List of people.json b/Examples/Data/List of people.json new file mode 100644 index 00000000..f40ac9bf --- /dev/null +++ b/Examples/Data/List of people.json @@ -0,0 +1,25 @@ +[ + { + "Name": "John Doe", + "Age": "30", + "Money": 1160.90, + "Birth": "03.2.15", + "GotKids": true, + "Child": [ "1.Ann Doe", "2.Charles Doe" ] + }, + { + "Name": "Jane Doe", + "Age": "27", + "Money": 3010.15, + "Birth": "08/03/2018", + "GotKids": false + }, + { + "Name": "John Smith", + "Age": 51, + "Money": 60.70, + "Birth": "03 2 15", + "GotKids": true, + "Child": [ "1.Danny Smith", "2.Bob Smith" ] + } +] \ No newline at end of file diff --git a/Examples/Data/List of people.xml b/Examples/Data/List of people.xml new file mode 100644 index 00000000..baade4a0 --- /dev/null +++ b/Examples/Data/List of people.xml @@ -0,0 +1,28 @@ + + + + John Doe + 30 + 1160.90 + true + Ann Doe + Charles Doe + 1989-04-01 4:00:00 pm + + + Jane Doe + 27 + 3010.15 + false + 1992-01-31 07:00:00 am + + + John Smith + 51 + 60.70 + true + Danny Smith + Bob Smith + 1968-03-08 1:00:00 pm + + diff --git a/Examples/Data/List source.docx b/Examples/Data/List source.docx new file mode 100644 index 00000000..320dccb3 Binary files /dev/null and b/Examples/Data/List source.docx differ diff --git a/Examples/Data/List with leading zero.docx b/Examples/Data/List with leading zero.docx new file mode 100644 index 00000000..be7671f0 Binary files /dev/null and b/Examples/Data/List with leading zero.docx differ diff --git a/Examples/Data/List with the same definition identifier - destination.docx b/Examples/Data/List with the same definition identifier - destination.docx new file mode 100644 index 00000000..024a2dde Binary files /dev/null and b/Examples/Data/List with the same definition identifier - destination.docx differ diff --git a/Examples/Data/List with the same definition identifier - source.docx b/Examples/Data/List with the same definition identifier - source.docx new file mode 100644 index 00000000..28461ffe Binary files /dev/null and b/Examples/Data/List with the same definition identifier - source.docx differ diff --git a/Examples/Data/Macro.docm b/Examples/Data/Macro.docm new file mode 100644 index 00000000..989db041 Binary files /dev/null and b/Examples/Data/Macro.docm differ diff --git a/Examples/Data/Mail merge data - Customers.xml b/Examples/Data/Mail merge data - Customers.xml new file mode 100644 index 00000000..e46ecfdb --- /dev/null +++ b/Examples/Data/Mail merge data - Customers.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Examples/Data/Mail merge data - Orders.xml b/Examples/Data/Mail merge data - Orders.xml new file mode 100644 index 00000000..7bd50ad5 --- /dev/null +++ b/Examples/Data/Mail merge data - Orders.xml @@ -0,0 +1,45 @@ + + + + 23 +
          Nelson Street
          + Howick + Auckland + 543 1234 + 03/01/2010 + 14.00 + + BBQ Chicken Pizza + 6.00 + 1 + 6.00 + + + 1.5 Litre Coke + 4.00 + 2 + 8.00 + +
          + + 10 +
          Parkville Avenue
          + Pakuranga + Auckland + 548 7342 + 05/03/2010 + 6.00 + + Hawaiian Pizza + 4.00 + 1 + 4.00 + + + Fries + 1.00 + 2 + 2.00 + +
          +
          \ No newline at end of file diff --git a/Examples/Data/Mail merge data - Purchase order.xml b/Examples/Data/Mail merge data - Purchase order.xml new file mode 100644 index 00000000..ae45c51b --- /dev/null +++ b/Examples/Data/Mail merge data - Purchase order.xml @@ -0,0 +1,34 @@ + + +
          + Ellen Adams + 123 Maple Street + Mill Valley + CA + 10999 + USA +
          +
          + Tai Yee + 8 Oak Avenue + Old Town + PA + 95819 + USA +
          + Please leave packages in shed by driveway. + + + Lawnmower + 1 + 148.95 + Confirm this is electric + + + Baby Monitor + 2 + 39.98 + 1999-05-21 + + +
          \ No newline at end of file diff --git a/Examples/src/main/resources/MailMerge/Vendors.xml b/Examples/Data/Mail merge data - Vendors.xml similarity index 100% rename from Examples/src/main/resources/MailMerge/Vendors.xml rename to Examples/Data/Mail merge data - Vendors.xml diff --git a/Examples/Data/Mail merge destination - Northwind employees.docx b/Examples/Data/Mail merge destination - Northwind employees.docx new file mode 100644 index 00000000..a5f54cfc Binary files /dev/null and b/Examples/Data/Mail merge destination - Northwind employees.docx differ diff --git a/Examples/Data/Mail merge destination - Northwind suppliers.docx b/Examples/Data/Mail merge destination - Northwind suppliers.docx new file mode 100644 index 00000000..aa6f4452 Binary files /dev/null and b/Examples/Data/Mail merge destination - Northwind suppliers.docx differ diff --git a/Examples/Data/Mail merge destination - Suppliers.docx b/Examples/Data/Mail merge destination - Suppliers.docx new file mode 100644 index 00000000..976fab91 Binary files /dev/null and b/Examples/Data/Mail merge destination - Suppliers.docx differ diff --git a/Examples/Data/Mail merge destinations - Complex template.docx b/Examples/Data/Mail merge destinations - Complex template.docx new file mode 100644 index 00000000..1e0e7fc4 Binary files /dev/null and b/Examples/Data/Mail merge destinations - Complex template.docx differ diff --git a/Examples/Data/Mail merge destinations - Fax.docx b/Examples/Data/Mail merge destinations - Fax.docx new file mode 100644 index 00000000..f5b403b4 Binary files /dev/null and b/Examples/Data/Mail merge destinations - Fax.docx differ diff --git a/Examples/Data/Mail merge destinations - Invoice.docx b/Examples/Data/Mail merge destinations - Invoice.docx new file mode 100644 index 00000000..a7eb019d Binary files /dev/null and b/Examples/Data/Mail merge destinations - Invoice.docx differ diff --git a/Examples/Data/Mail merge destinations - LINQ.docx b/Examples/Data/Mail merge destinations - LINQ.docx new file mode 100644 index 00000000..1d3fcb44 Binary files /dev/null and b/Examples/Data/Mail merge destinations - LINQ.docx differ diff --git a/Examples/Data/Mail merge destinations - Mustache syntax.docx b/Examples/Data/Mail merge destinations - Mustache syntax.docx new file mode 100644 index 00000000..c7fa7420 Binary files /dev/null and b/Examples/Data/Mail merge destinations - Mustache syntax.docx differ diff --git a/Examples/Data/Mail merge destinations - Orders.docx b/Examples/Data/Mail merge destinations - Orders.docx new file mode 100644 index 00000000..a2cd5170 Binary files /dev/null and b/Examples/Data/Mail merge destinations - Orders.docx differ diff --git a/Examples/Data/Mail merge destinations - Registration complete.docx b/Examples/Data/Mail merge destinations - Registration complete.docx new file mode 100644 index 00000000..0b680e57 Binary files /dev/null and b/Examples/Data/Mail merge destinations - Registration complete.docx differ diff --git a/Examples/Data/Mail merge destinations - Vendor.docx b/Examples/Data/Mail merge destinations - Vendor.docx new file mode 100644 index 00000000..b60a3875 Binary files /dev/null and b/Examples/Data/Mail merge destinations - Vendor.docx differ diff --git a/Examples/Data/Mail merge mustache tags.docx b/Examples/Data/Mail merge mustache tags.docx new file mode 100644 index 00000000..19dfdee9 Binary files /dev/null and b/Examples/Data/Mail merge mustache tags.docx differ diff --git a/Examples/Data/Mail merge regions.docx b/Examples/Data/Mail merge regions.docx new file mode 100644 index 00000000..78d26542 Binary files /dev/null and b/Examples/Data/Mail merge regions.docx differ diff --git a/Examples/Data/Mail merge tables.docx b/Examples/Data/Mail merge tables.docx new file mode 100644 index 00000000..3625c964 Binary files /dev/null and b/Examples/Data/Mail merge tables.docx differ diff --git a/Examples/Data/Mail merge template.docx b/Examples/Data/Mail merge template.docx new file mode 100644 index 00000000..150eb724 Binary files /dev/null and b/Examples/Data/Mail merge template.docx differ diff --git a/Examples/Data/Mail merge with regions data set.docx b/Examples/Data/Mail merge with regions data set.docx new file mode 100644 index 00000000..f56f02bc Binary files /dev/null and b/Examples/Data/Mail merge with regions data set.docx differ diff --git a/Examples/Data/Mail merge with regions.docx b/Examples/Data/Mail merge with regions.docx new file mode 100644 index 00000000..e205a037 Binary files /dev/null and b/Examples/Data/Mail merge with regions.docx differ diff --git a/Examples/Data/Mail merge.doc b/Examples/Data/Mail merge.doc new file mode 100644 index 00000000..853e2bdd Binary files /dev/null and b/Examples/Data/Mail merge.doc differ diff --git a/Examples/Data/Master document.docx b/Examples/Data/Master document.docx new file mode 100644 index 00000000..88addd85 Binary files /dev/null and b/Examples/Data/Master document.docx differ diff --git a/Examples/Data/Math shapes.docx b/Examples/Data/Math shapes.docx new file mode 100644 index 00000000..c8d4362e Binary files /dev/null and b/Examples/Data/Math shapes.docx differ diff --git a/Examples/Data/Merged table.docx b/Examples/Data/Merged table.docx new file mode 100644 index 00000000..13892469 Binary files /dev/null and b/Examples/Data/Merged table.docx differ diff --git a/Examples/Data/Microsoft equation object.docx b/Examples/Data/Microsoft equation object.docx new file mode 100644 index 00000000..35e8900e Binary files /dev/null and b/Examples/Data/Microsoft equation object.docx differ diff --git a/Examples/Data/Missing font.docx b/Examples/Data/Missing font.docx new file mode 100644 index 00000000..f43f6476 Binary files /dev/null and b/Examples/Data/Missing font.docx differ diff --git a/Examples/Data/Missing font.html b/Examples/Data/Missing font.html new file mode 100644 index 00000000..6b206ab0 --- /dev/null +++ b/Examples/Data/Missing font.html @@ -0,0 +1,6 @@ + + +

          Hello world!

          +

          + + diff --git a/Examples/Data/Missing image.html b/Examples/Data/Missing image.html new file mode 100644 index 00000000..5af6bf73 --- /dev/null +++ b/Examples/Data/Missing image.html @@ -0,0 +1,7 @@ + + +

          Simple file.

          +

          +

          + + diff --git a/Examples/Data/Multi-section structured document tags.docx b/Examples/Data/Multi-section structured document tags.docx new file mode 100644 index 00000000..db1244d4 Binary files /dev/null and b/Examples/Data/Multi-section structured document tags.docx differ diff --git a/Examples/Data/MyFonts/AllegroOpen.otf b/Examples/Data/MyFonts/AllegroOpen.otf new file mode 100644 index 00000000..a01196bf Binary files /dev/null and b/Examples/Data/MyFonts/AllegroOpen.otf differ diff --git a/Examples/Data/MyFonts/Amethysta/Amethysta-Regular.ttf b/Examples/Data/MyFonts/Amethysta/Amethysta-Regular.ttf new file mode 100644 index 00000000..ab9eff55 Binary files /dev/null and b/Examples/Data/MyFonts/Amethysta/Amethysta-Regular.ttf differ diff --git a/Examples/Data/MyFonts/Arvo-Bold.ttf b/Examples/Data/MyFonts/Arvo-Bold.ttf new file mode 100644 index 00000000..97b203e3 Binary files /dev/null and b/Examples/Data/MyFonts/Arvo-Bold.ttf differ diff --git a/Examples/Data/MyFonts/Arvo-BoldItalic.ttf b/Examples/Data/MyFonts/Arvo-BoldItalic.ttf new file mode 100644 index 00000000..73a38a04 Binary files /dev/null and b/Examples/Data/MyFonts/Arvo-BoldItalic.ttf differ diff --git a/Examples/Data/MyFonts/Arvo-Italic.ttf b/Examples/Data/MyFonts/Arvo-Italic.ttf new file mode 100644 index 00000000..405d8bbd Binary files /dev/null and b/Examples/Data/MyFonts/Arvo-Italic.ttf differ diff --git a/Examples/Data/MyFonts/Arvo-Regular.ttf b/Examples/Data/MyFonts/Arvo-Regular.ttf new file mode 100644 index 00000000..0f09ea5f Binary files /dev/null and b/Examples/Data/MyFonts/Arvo-Regular.ttf differ diff --git a/Examples/Data/MyFonts/Junction/static/Junction-Bold.ttf b/Examples/Data/MyFonts/Junction/static/Junction-Bold.ttf new file mode 100644 index 00000000..7ce2fd64 Binary files /dev/null and b/Examples/Data/MyFonts/Junction/static/Junction-Bold.ttf differ diff --git a/Examples/Data/MyFonts/Junction/static/Junction-Light.ttf b/Examples/Data/MyFonts/Junction/static/Junction-Light.ttf new file mode 100644 index 00000000..9420d0b5 Binary files /dev/null and b/Examples/Data/MyFonts/Junction/static/Junction-Light.ttf differ diff --git a/Examples/Data/MyFonts/Junction/static/Junction-Medium.ttf b/Examples/Data/MyFonts/Junction/static/Junction-Medium.ttf new file mode 100644 index 00000000..02d7c99d Binary files /dev/null and b/Examples/Data/MyFonts/Junction/static/Junction-Medium.ttf differ diff --git a/Examples/Data/MyFonts/Junction/static/Junction-Regular.ttf b/Examples/Data/MyFonts/Junction/static/Junction-Regular.ttf new file mode 100644 index 00000000..f71eea11 Binary files /dev/null and b/Examples/Data/MyFonts/Junction/static/Junction-Regular.ttf differ diff --git a/Examples/Data/MyFonts/Junction/static/Junction-SemiBold.ttf b/Examples/Data/MyFonts/Junction/static/Junction-SemiBold.ttf new file mode 100644 index 00000000..5b5e27a1 Binary files /dev/null and b/Examples/Data/MyFonts/Junction/static/Junction-SemiBold.ttf differ diff --git a/Examples/Data/MyFonts/Junction/variable/JunctionVariableGX.ttf b/Examples/Data/MyFonts/Junction/variable/JunctionVariableGX.ttf new file mode 100644 index 00000000..0f60851b Binary files /dev/null and b/Examples/Data/MyFonts/Junction/variable/JunctionVariableGX.ttf differ diff --git a/Examples/Data/MyFonts/Kreon-Bold.ttf b/Examples/Data/MyFonts/Kreon-Bold.ttf new file mode 100644 index 00000000..977a6a67 Binary files /dev/null and b/Examples/Data/MyFonts/Kreon-Bold.ttf differ diff --git a/Examples/Data/MyFonts/Kreon-Light.ttf b/Examples/Data/MyFonts/Kreon-Light.ttf new file mode 100644 index 00000000..6cf10167 Binary files /dev/null and b/Examples/Data/MyFonts/Kreon-Light.ttf differ diff --git a/Examples/Data/MyFonts/Kreon-Regular.ttf b/Examples/Data/MyFonts/Kreon-Regular.ttf new file mode 100644 index 00000000..b506338d Binary files /dev/null and b/Examples/Data/MyFonts/Kreon-Regular.ttf differ diff --git a/Examples/Data/MyFonts/NoticiaText-Bold.ttf b/Examples/Data/MyFonts/NoticiaText-Bold.ttf new file mode 100644 index 00000000..77687788 Binary files /dev/null and b/Examples/Data/MyFonts/NoticiaText-Bold.ttf differ diff --git a/Examples/Data/MyFonts/NoticiaText-BoldItalic.ttf b/Examples/Data/MyFonts/NoticiaText-BoldItalic.ttf new file mode 100644 index 00000000..29f18694 Binary files /dev/null and b/Examples/Data/MyFonts/NoticiaText-BoldItalic.ttf differ diff --git a/Examples/Data/MyFonts/NoticiaText-Italic.ttf b/Examples/Data/MyFonts/NoticiaText-Italic.ttf new file mode 100644 index 00000000..69598e39 Binary files /dev/null and b/Examples/Data/MyFonts/NoticiaText-Italic.ttf differ diff --git a/Examples/Data/MyFonts/NoticiaText-Regular.ttf b/Examples/Data/MyFonts/NoticiaText-Regular.ttf new file mode 100644 index 00000000..a37288f9 Binary files /dev/null and b/Examples/Data/MyFonts/NoticiaText-Regular.ttf differ diff --git a/Examples/Data/MyFonts/Slabo13px-Regular.ttf b/Examples/Data/MyFonts/Slabo13px-Regular.ttf new file mode 100644 index 00000000..6e1fae90 Binary files /dev/null and b/Examples/Data/MyFonts/Slabo13px-Regular.ttf differ diff --git a/Examples/Data/MyFonts/Slabo27px-Regular.ttf b/Examples/Data/MyFonts/Slabo27px-Regular.ttf new file mode 100644 index 00000000..4d73e098 Binary files /dev/null and b/Examples/Data/MyFonts/Slabo27px-Regular.ttf differ diff --git a/Examples/Data/MyFonts/Squarish Sans CT Regular.ttf b/Examples/Data/MyFonts/Squarish Sans CT Regular.ttf new file mode 100644 index 00000000..596ff878 Binary files /dev/null and b/Examples/Data/MyFonts/Squarish Sans CT Regular.ttf differ diff --git a/Examples/Data/MyFonts/dinot.otf b/Examples/Data/MyFonts/dinot.otf new file mode 100644 index 00000000..4a5e1312 Binary files /dev/null and b/Examples/Data/MyFonts/dinot.otf differ diff --git a/Examples/Data/MyFonts/dinot.ttf b/Examples/Data/MyFonts/dinot.ttf new file mode 100644 index 00000000..4bdbb4c8 Binary files /dev/null and b/Examples/Data/MyFonts/dinot.ttf differ diff --git a/Examples/Data/MyFonts/mplus-2m-regular.ttf b/Examples/Data/MyFonts/mplus-2m-regular.ttf new file mode 100644 index 00000000..bdbde005 Binary files /dev/null and b/Examples/Data/MyFonts/mplus-2m-regular.ttf differ diff --git a/Examples/Data/Nested elements.json b/Examples/Data/Nested elements.json new file mode 100644 index 00000000..b8391da9 --- /dev/null +++ b/Examples/Data/Nested elements.json @@ -0,0 +1,82 @@ +[ + { + Contract: + [ + { + Client: + { + Name: "A Company" + }, + Price: 1200000 + }, + { + Client: + { + Name: "B Ltd." + }, + Price: 750000 + }, + { + Client: + { + Name: "C & D" + }, + Price: 350000 + } + ] + }, + { + Name: "Tony Anderson", + Contract: + [ + { + Client: + { + Name: "E Corp." + }, + Price: 650000 + }, + { + Client: + { + Name: "F & Partners" + }, + Price: 550000 + } + ] + }, + { + Name: "July James", + Contract: + [ + { + Client: + { + Name: "G & Co." + }, + Price: 350000 + }, + { + Client: + { + Name: "H Group" + }, + Price: 250000 + }, + { + Client: + { + Name: "I & Sons" + }, + Price: 100000 + }, + { + Client: + { + Name: "J Ent." + }, + Price: 100000 + } + ] + } +] \ No newline at end of file diff --git a/Examples/Data/Nested elements.xml b/Examples/Data/Nested elements.xml new file mode 100644 index 00000000..c7bc97db --- /dev/null +++ b/Examples/Data/Nested elements.xml @@ -0,0 +1,65 @@ + + + + + + A Company + + 1200000 + + + + B Ltd. + + 750000 + + + + C & D + + 350000 + + + + Tony Anderson + + + E Corp. + + 650000 + + + + F & Partners + + 550000 + + + + July James + + + G & Co. + + 350000 + + + + H Group + + 250000 + + + + I & Sons + + 100000 + + + + J Ent. + + 100000 + + + diff --git a/Examples/Data/Nested fields.docx b/Examples/Data/Nested fields.docx new file mode 100644 index 00000000..a6faa1fc Binary files /dev/null and b/Examples/Data/Nested fields.docx differ diff --git a/Examples/Data/Nested tables.docx b/Examples/Data/Nested tables.docx new file mode 100644 index 00000000..f3d2f93e Binary files /dev/null and b/Examples/Data/Nested tables.docx differ diff --git a/Examples/Data/No default editing language.docx b/Examples/Data/No default editing language.docx new file mode 100644 index 00000000..86c4511d Binary files /dev/null and b/Examples/Data/No default editing language.docx differ diff --git a/Examples/Data/Non compatible table.docx b/Examples/Data/Non compatible table.docx new file mode 100644 index 00000000..a98365a1 Binary files /dev/null and b/Examples/Data/Non compatible table.docx differ diff --git a/Examples/Data/Northwind traders.docx b/Examples/Data/Northwind traders.docx new file mode 100644 index 00000000..4b2b3a8d Binary files /dev/null and b/Examples/Data/Northwind traders.docx differ diff --git a/Examples/Data/Number detection.txt b/Examples/Data/Number detection.txt new file mode 100644 index 00000000..3eb70e9c --- /dev/null +++ b/Examples/Data/Number detection.txt @@ -0,0 +1,8 @@ + +1.48MM X 1,199MM X C - QTY:80MT AT USD982/MT +1.88MM X 1,300MM X C - QTY:20MT AT USD971/MT +2.10MM X 1,219MM X C - QTY:20MT AT USD965/MT +. +2)HOT ROLLED STEEL FOR GENERAL STRUCTURE +GRADE:JIS G 3101:2010 SS400 +2.70MM X 1,515MM X C - QTY:200MT AT USD964/MT \ No newline at end of file diff --git a/Examples/Data/OLE ActiveX controls.docm b/Examples/Data/OLE ActiveX controls.docm new file mode 100644 index 00000000..6d7b88eb Binary files /dev/null and b/Examples/Data/OLE ActiveX controls.docm differ diff --git a/Examples/Data/OLE objects.docx b/Examples/Data/OLE objects.docx new file mode 100644 index 00000000..addfd889 Binary files /dev/null and b/Examples/Data/OLE objects.docx differ diff --git a/Examples/Data/OLE shape.rtf b/Examples/Data/OLE shape.rtf new file mode 100644 index 00000000..f1a3ea2a --- /dev/null +++ b/Examples/Data/OLE shape.rtf @@ -0,0 +1,659 @@ +{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff1\deff1\stshfdbch0\stshfloch37\stshfhich37\stshfbi37\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;} +{\f37\fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\f39\froman\fcharset238\fprq2 Times New Roman CE;}{\f40\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f42\froman\fcharset161\fprq2 Times New Roman Greek;} +{\f43\froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f46\froman\fcharset186\fprq2 Times New Roman Baltic;} +{\f47\froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f49\fswiss\fcharset238\fprq2 Arial CE;}{\f50\fswiss\fcharset204\fprq2 Arial Cyr;}{\f52\fswiss\fcharset161\fprq2 Arial Greek;}{\f53\fswiss\fcharset162\fprq2 Arial Tur;} +{\f54\fbidi \fswiss\fcharset177\fprq2 Arial (Hebrew);}{\f55\fbidi \fswiss\fcharset178\fprq2 Arial (Arabic);}{\f56\fswiss\fcharset186\fprq2 Arial Baltic;}{\f57\fswiss\fcharset163\fprq2 Arial (Vietnamese);}{\f409\fswiss\fcharset238\fprq2 Calibri CE;} +{\f410\fswiss\fcharset204\fprq2 Calibri Cyr;}{\f412\fswiss\fcharset161\fprq2 Calibri Greek;}{\f413\fswiss\fcharset162\fprq2 Calibri Tur;}{\f414\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\f415\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);} +{\f416\fswiss\fcharset186\fprq2 Calibri Baltic;}{\f417\fswiss\fcharset163\fprq2 Calibri (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0; +\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{ +\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch \af1\afs22\alang1025 \ltrch \f1\fs22\lang1031\langfe1033\cgrid\langnp1031\langfenp1033 \snext0 \styrsid14448319 Normal;}{\*\cs10 \additive \ssemihidden \styrsid14448319 +Default Paragraph Font;}{\*\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv +\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch \af37\afs20 \ltrch \f37\fs20\lang1024\langfe1024\cgrid\langnp1024\langfenp1024 \snext11 \ssemihidden Normal Table;}{\s15\ql \li0\ri0\widctlpar +\tqc\tx4320\tqr\tx8640\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch \af1\afs22\alang1025 \ltrch \f1\fs22\lang1031\langfe1033\cgrid\langnp1031\langfenp1033 \sbasedon0 \snext15 \styrsid12323684 header;}{\s16\ql \li0\ri0\widctlpar +\tqc\tx4320\tqr\tx8640\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch \af1\afs22\alang1025 \ltrch \f1\fs22\lang1031\langfe1033\cgrid\langnp1031\langfenp1033 \sbasedon0 \snext16 \styrsid12323684 footer;}} +{\*\latentstyles\lsdstimax156\lsdlockeddef0{\lsdlockedexcept Normal;heading 1;heading 2;heading 3;heading 4;heading 5;heading 6;heading 7;heading 8;heading 9;toc 1;toc 2;toc 3;toc 4;toc 5;toc 6;toc 7;toc 8;toc 9;caption;Title;Default Paragraph Font;Subtitle;Strong;Emphasis;Table Grid;}} +{\*\rsidtbl \rsid1511220\rsid3432523\rsid12323684\rsid14448319}{\*\generator Microsoft Word 11.0.6568;}{\info{\author RPC}{\operator RPC}{\creatim\yr2020\mo1\dy26\min29}{\revtim\yr2020\mo1\dy26\min31}{\version2}{\edmins2}{\nofpages1}{\nofwords4} +{\nofchars25}{\*\company }{\nofcharsws28}{\vern24579}}\margl1417\margr1417\margt1417\margb1134\ltrsect +\deftab708\widowctrl\ftnbj\aenddoc\hyphhotz425\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\hyphcaps0\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1417\dgvorigin1417\dghshow1\dgvshow1 +\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct +\asianbrkrule\rsidroot14448319\newtblstyruls\nogrowautofit \fet0{\*\ftnsep \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch \af1\afs22\alang1025 \ltrch +\f1\fs22\lang1031\langfe1033\cgrid\langnp1031\langfenp1033 {\rtlch \af1 \ltrch \insrsid12323684 \chftnsep +\par }}{\*\ftnsepc \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch \af1\afs22\alang1025 \ltrch \f1\fs22\lang1031\langfe1033\cgrid\langnp1031\langfenp1033 {\rtlch \af1 \ltrch \insrsid12323684 +\chftnsepc +\par }}{\*\aftnsep \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch \af1\afs22\alang1025 \ltrch \f1\fs22\lang1031\langfe1033\cgrid\langnp1031\langfenp1033 {\rtlch \af1 \ltrch \insrsid12323684 +\chftnsep +\par }}{\*\aftnsepc \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch \af1\afs22\alang1025 \ltrch \f1\fs22\lang1031\langfe1033\cgrid\langnp1031\langfenp1033 {\rtlch \af1 \ltrch \insrsid12323684 +\chftnsepc +\par }}\ltrpar \sectd \ltrsect\linex0\endnhere\titlepg\sectdefaultcl\sftnbj {\header \ltrpar \pard\plain \ltrpar\s15\ql \li0\ri0\widctlpar\tqc\tx4320\tqr\tx8640\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch \af1\afs22\alang1025 \ltrch +\f1\fs22\lang1031\langfe1033\cgrid\langnp1031\langfenp1033 {\rtlch \af1 \ltrch \insrsid12323684 +\par }}{\footer \ltrpar \pard\plain \ltrpar\s16\ql \li0\ri0\widctlpar\tqc\tx4320\tqr\tx8640\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch \af1\afs22\alang1025 \ltrch \f1\fs22\lang1031\langfe1033\cgrid\langnp1031\langfenp1033 {\rtlch \af1 \ltrch +\insrsid12323684 +\par }}{\headerf \ltrpar \pard\plain \ltrpar\qr \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch \af1\afs22\alang1025 \ltrch \f1\fs22\lang1031\langfe1033\cgrid\langnp1031\langfenp1033 {\rtlch \af1 \ltrch \insrsid12323684 T +his document contains an OLE object in the form of a shape}{\rtlch \af1 \ltrch \insrsid12323684 +\par }\pard \ltrpar\qr \li0\ri0\sa480\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch \af1 \ltrch \insrsid12323684 Double clicking on the object will access its data, and it can be extracted programmatically by Aspose.Words}{\rtlch \af1 +\ltrch \insrsid12323684 +\par }}{\footerf \ltrpar \pard\plain \ltrpar\s16\ql \li0\ri0\widctlpar\tqc\tx4320\tqr\tx8640\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch \af1\afs22\alang1025 \ltrch \f1\fs22\lang1031\langfe1033\cgrid\langnp1031\langfenp1033 {\rtlch \af1 \ltrch +\insrsid12323684 +\par }}{\*\pnseclvl1\pnucrm\pnqc\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnqc\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnqc\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnqc\pnstart1\pnindent720\pnhang +{\pntxta )}}{\*\pnseclvl5\pndec\pnqc\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnqc\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnqc\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}} +{\*\pnseclvl8\pnlcltr\pnqc\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnqc\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar +\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14448319 \rtlch \af1\afs22\alang1025 \ltrch \f1\fs22\lang1031\langfe1033\cgrid\langnp1031\langfenp1033 {\pard\plain \ltrpar +\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14448319 \rtlch \af1\afs22\alang1025 \ltrch \f1\fs22\lang1031\langfe1033\cgrid\langnp1031\langfenp1033 {\object\objemb\objw1440\objh1215{\*\objclass Outlook.FileAttach} +{\*\objdata 0105000002000000130000004f75746c6f6f6b2e46696c6541747461636800000000000000000000660000 +d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff0900060000000000000000000000010000000100000000000000001000000200000001000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffdffffff04000000fefffffffefffffffeffffff060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000100000001100000012000000130000001400000015000000160000001700000018000000190000001a0000001b0000001c0000001d0000001e00 +00001f00000020000000210000002200000023000000240000002500000026000000feffffff28000000290000002a0000002b0000002c0000002d0000002e0000002f0000003000000031000000feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffff0200000031f0060000000000c000000000000046000000000000000000000000e035 +920773d3d50103000000c00100000000000001004f006c00650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000201ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 +0000000000000000000000001400000000000000010043006f006d0070004f0062006a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120002010100000004000000ffffffff0000000000000000000000000000000000000000000000000000 +0000000000000000000001000000760000000000000003004f0062006a0049006e0066006f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000201ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 +000000000000000000000000030000000600000000000000feffffff02000000fefffffffeffffff05000000fefffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff010000020800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100feff030a0000ffffffff31f0060000000000c0000000000000461800 +00004f75746c6f6f6b2046696c65204174746163686d656e7400130000004f75746c6f6f6b2e46696c6541747461636800130000004f75746c6f6f6b2e46696c6541747461636800f439b2710000000000000000000000000000000000000000000040000300000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000003020000074353562e637376074353562e637376074353562e637376042e637376fc64c41c0a87d001e0621720886cd0010100000000000000074300530056002e00630073007600074300530056002e00630073007600074300 +530056002e00630073007600042e00630073007600000000000000000000000000000000000001000000e004dc040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000041007400740061006300680044006500730063000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000160002000300000006000000ffffffff000000000000 +000000000000000000000000000000000000000000000000000000000000040000007a000000000000004100740074006100630068005000720065007300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000200ffffffffffffffffffffffff00000000 +000000000000000000000000000000000000000000000000000000000000000005000000664300000000000041007400740061006300680043006f006e00740065006e00740073000000000000000000000000000000000000000000000000000000000000000000000000001e0002010500000007000000ffffffff0000 +0000000000000000000000000000000000000000000000000000000000000000000027000000b01500000000000003004d00610069006c004100740074006100630068006d0065006e0074000000000000000000000000000000000000000000000000000000000000000000000020000200ffffffffffffffffffffffff +000000000000000000000000000000000000000000000000000000000000000000000000060000000c00000000000000000108000000ec0900005f08000054430000010009000003aa21000000006f19000000000400000003010800050000000b0200000000050000000c02510060000500000009020000000005000000 +0102ffffff00a5000000410bc6008800200020000000000020002000000020002800000020000000400000000100010000000000000100000000000000000000000000000000000000000000ffffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffc000001fc000001fc000001fc000001fc000001fc000001fc000001fc000001fc000001fc000001 +fc000001fc0000018000000180000001800000018000000180000001800000018000000180000001800000018000000180000001800000018000000180000003c0000007e000000ffc00001ffc00003fffffffff21060000410b460066002000200000000000200020000000200028000000200000002000000001001800 +00000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000b9a495917c6a78614c6a533c664e37624a32604830604830604830604830604830604830604830604830604830604830604830604830604830604830604830604830604830604830604830000000000000000000000000000000000000000000b9a495fceadfdfcdc4ddc5b7debdacdeb8a2 +e3b298e5b390e5b390e5b390e5b28ee6b08be7af88e9ad85eaac82ebaa7feca77beea577efa373f1a16ff1a06bf39e68f39d65f49b63604830000000000000000000000000000000000000000000baa596fcebe1fcebe1fcebe1fcebe0fbeadffbe9dffbe9defbe9ddfae8dcfbe7dcfae6dafae6d9fae5d7fae4d6fae3d4 +fae2d3f9e0d2f9e0cff9decef9ddccf9dccaf9dbc8f49c65604830000000000000000000000000000000000000000000bba697fceee4fbede4fcede4fbece4fbece3fcebe2fbebe2fbebe0fbeadffbe9dffbe9ddfbe8dcfae7dafae6dafae4d8fae4d6f9e2d4fae1d3a88877f9dfcff9decdf9dccaf39d67604830000000 +000000000000000000000000000000000000bba698fcefe7fcefe7fbefe6fcefe6fcefe6fcede5fcede4fcede4fcece3fcebe2fceae1fceadffbeadefbe8dcfbe7dbfae6dafae5d7fae4d59b7b69906e5cfae0d0fadfcef29e6a604830000000000000000000000000000000000000000000bca899fcf1eafcf1e9fcf1ea +fcf0e9fcf0e9fcf0e8fdefe8fcefe7fceee6fceee5f2e2d8d4beb3e8d5c9fceae0fce9defbe8ddfbe7dbfae5d9f9e4d7694431d5b9a9fae0d0f1a06d604830000000000000000000000000000000000000000000bda999fdf3edfdf3edfdf3ecfdf2ecfdf3ebfdf2ebfcf2eafdf1eafdf1e9c0aa9e67422f66412e66412e +7e5d4bfcebe1714d3b66412e775441bfa4957e5b497e5b49fae2d3f0a270604830000000000000000000000000000000000000000000bda99afdf5effdf4effdf4effdf4eefdf4eefdf4eefdf3edfdf3edfcf2eb69443166412ed4c2b7fcf0e7b79e917e5d4b6c483566412ed4bcaffbe8dcb69a8a6c4835d5baadefa373 +604830000000000000000000000000000000000000000000bfaa9bfef6f1fdf6f1fdf6f1fdf6f1fdf6f1fef5f0fdf5f0fdf5f0fdf4ef66412e714e3cfdf2ecfcf1eafcf0e9e9d8cf69443166412ed4beb2fceadffbe8ddfbe7dafae5d8eda577604830000000000000000000000000000000000000000000c0ab9dfdf8f3 +fdf7f3fef7f3fef7f3fef7f3fdf7f3fdf7f2fdf7f2fdf6f16c4836694431fdf4eefdf3edfdf3ecfcf1ea714e3b66412ed4c0b4fcebe2fbeae0fbe9ddfbe7dbeda77b604830000000000000000000000000000000000000000000c0ac9efef9f5fef9f5fef9f5fef8f5fef8f5fef8f5fef8f5fdf7f4fef7f3d5c6be67422f +7e5e4de9ddd6fdf4eefdf3ed714e3b66412ed4c1b6fceee4fbece2fbeae0fbe8ddeba97f604830000000000000000000000000000000000000000000c1ae9efefaf7fefaf7fefaf7fef9f7fef9f7fefaf7fef9f7fef9f6fef9f6fef8f5eae0da917566714e3c6c48367e5e4d69443166412ed4c1b7fcefe7fceee5fcece3 +fbeadfe9ab83604830000000000000348037347d32337a2e337729327325327020316c1c306a1730661330630f2f600b2f5d082f5c052e5a032e58002e5800fef9f6fef8f5fef8f4fef7f3e9ded76c483666412ed5c3b9fcf1e9fcefe7fcede4fcece2e8ae8760483000000000000035833affffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2e5800917668fefaf7fef9f6fef8f5fef7f369443166412ed5c4bafdf2ecfcf1e9fdefe7fcede4e6af8b60483000000000000036863effffffd3ead2cfe8cecae7c8c4e6c3bee4bbb8e3b6b2e1afade1a9a8dfa4a4dfa0a2df9fa4dfa0ffffff +2e590266412eb7a59bfefaf8f4ede97e5e4e66412e67422ffdf4effdf3edfdf2ebfdf0e8fceee6e5b18f604830000000000000368a42ffffffd3e9d273c3951ea164219b58238d3f277c22548d39eef7f16bc08742a95f5cb16df9faf8f9faf72f5b05e0d7d2714e3c66412e66412e66412e694432dfd3ccfdf6f1fdf4ef +fdf3edfcf1eafcf0e8e5b392604830000000000000378c46ffffffd3ead2cfe9cd2f9651238c3e25822d2c791b6a984990d6af41b6703faf67b9dfc4f9fbf9fcfdfc2f5d07fffdfcfefcfbeae3dfd5c9c3e0d5d0fef9f6fef8f4fdf7f3fdf6f1fdf4eefdf2edfdf1eae4b596604830000000000000378e49ffffffd4e9d3 +cfe9cfa7d1a8287a1c2a77133e7a11c9ecda43c38442bd7c80cfa1f9fdfbf1f9f2ffffff2f600afffdfdfffdfcfefcfbfefbfafefbf9fefaf7fef9f5fef8f4fef6f2fef5f0fdf4eefdf2ece2b79a60483000000000000037904cffffffd5e9d4d1e9cfcde8cb6ba153326100345c034fc99145c98d5bca94ecf8f2f9fdfb +ace1a9ffffff30610dfffefdfffdfcfffdfcfffcfbfffbfafefaf8fefaf7fef8f5fdf7f3fef6f1fdf4effdf3ede1b99c60483000000000000037934effffffd6ead5d2e9d2cee8cdcae7c84566183f9e5b47d19a46cc92b3e7cffafefccdecccb2e1afffffff316410fffefefffefdfffdfcfffcfbfffcfafefbf9fefaf8 +fef9f6fef8f4fef6f2fdf6f0fdf3eee1ba9f604830000000000000389450ffffffd7ead6d5e9d4d1e9cfcde8cc83c18e45c98e45cc924cad76fafdfcf9fbf9b7e3b4b8e3b5ffffff306715fffefefffefdfffefdfffdfcfffcfbfefbf9fefaf8fefaf7fef8f5fef7f3fdf6f1fdf5efdfbba1604830000000000000389552 +ffffffd7ead7d6ead5d3e9d2cce8cd54c38744c38444be804666339aa98ef8f9f7f5f8f4bee5bcffffff316a18fffefefffefdfffdfdfffdfcfffcfbfefcfafefbf9dbc9c0dbc2afdebba5debba5debba5dfbca3604830000000000000358d4efefefeddeeddd7ead7d5ead578c69141b67141ba7849844e4a63314b6433 +e4e7e0f8f9f7daeed9ffffff316d1dfffefefffefdfffefdfffdfcfffdfbfffcfabeac9d8c766388725e816b577a634e725b456a533c6048300000000000002e7b42eff7f1eaf4ead7ead7aed6b33da85b3ead647fca9ad7ded34b64334b6433657a50f8f9f7f8f9f7fefefe327021fffefefffefdfffdfdfffdfcfffdfc +fffcfbbfad9decd2bfeacebbe7cab5e4c4aee1bea9604830100d090000000000001f552ec0dec9f7fbf7d7ead73b9a463b9f4e40a659ecf4ecf9faf8859e774b64334b6433899a7af8f9f7fafbf9327425fffefefffefefffefdfffefdfffdfcfffcfbc1ae9fffeee4fbe8dcf4ded0eed4c3604830100d090a0805000000 +0000000f2a165e9f70edf5eff7fbf7eaf4eaddeeddd7ead7d7ead6d6ead5d5ead5d4e9d3d3e9d3d3ead2d3e9d2ffffff337729fffefefffefefffefdfefefdfffdfcfffdfbc2b0a0ffeee4fbe8dcf5ded0654e36100d090a0805000000000000000000000000112f195e9f70c0dec9eff7f1fefefeffffffffffffffffff +ffffffffffffffffffffffffffffffffffff347a2dfffefefffefefffefdfffdfdfffdfcfffdfbc4b2a3ffeee4fbe8dc6c553e100d090a08050000000000000000000000000000000000000f2a161f552e2e7b423e975638945138934f37914d378f4a378d46368a4235873e35843a358036347c31fffefefffefefffefe +fffefdfffdfdfffdfcc6b4a4ffeee4836e59100d090a0805000000000000000000000000000000000000000000000000000000000000d0beb1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefffffefffefefffefefffdfdfffdfcc8b5a59c8674100d090a0805000000000000000000 +000000000000000000000000000000000000000000000000d1bfb1d1bfb1d1bfb1d1bfb1d0beb0cfbdafcfbdafcfbcaecdbbadcdbbaccdb9acccb9abcbb8aacab7a9cab7a8c9b6a7c8b6a7c9b6a6100d090a0705000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000026060f00090049636f6e4f6e6c790000050000000102ffffff0005000000090200000000310100004009c600880000000000 +2d0060002400000028000000600000002d00000001000100000000001c0200000000000000000000000000000000000000000000ffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8106398473ffffffffffffff0922391f21ffffffffffffff3ff23f3e21ffffffffffffff3fe09f3c61ffffffffffffff3 +f849f1cccffffffffffffff3f1c9f844cffffffffffffff3f388fffffffffffffffffff8931cfffffffffffffffffffc101cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f19000040098600ee00000000002d0060002400000028000000600000002d000000 +0100180000000000a0320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000e9e9e99a9a9a0000000000008c8c8ce9e9e9000000bdbdbd686868000000686868bdbdbd000000000000e9e9e9000000e9e9e9000000000000000000686868d9d9d90000000000009a9a9a000000000000d0d0 +d00000004d4d4d0000008c8c8c0000000000000000008c8c8ca7a7a70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f0f0f04d4d4d8c8c8cf0f0f0000000f0f0f0bdbdbd000000b2b2b2f0f0f0000000d0d0d0000000d9d9d9000000a7a7a70000 +00b2b2b2000000000000000000686868d9d9d90000009a9a9a686868f0f0f0000000000000000000000000000000000000bdbdbd000000f0f0f0000000000000f0f0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009a9a9a6868680000000000000000 +00000000000000000000000000000000000000000000000000bdbdbd0000004d4d4da7a7a7686868000000000000000000000000000000000000000000bdbdbd000000000000000000000000000000a7a7a7000000e1e1e1000000a7a7a79a9a9a9a9a9abdbdbd0000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000004d4d4db2b2b20000000000000000000000000000000000000000000000000000009a9a9a4d4d4df0f0f0d9d9d9000000000000000000e9e9e90000000000000000000000000000004d4d4dbdbdbd0000000000000000000000007c7c7c7c7c7ce1e1e10000000000 +004d4d4dd0d0d0d0d0d04d4d4d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bdbdbd000000000000000000000000000000000000000000bdbdbd4d4d4d7c7c7ce9e9e9000000a7a7a79a9a9a0000009a9a9ab2b2b20000000000000000000000 +00000000a7a7a7686868f0f0f0000000000000000000000000b2b2b2000000000000d0d0d0000000000000000000000000d0d0d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000686868b2b2b2000000000000000000000000000000000000b2b2b24d4d4dd0d0 +d00000000000000000004d4d4dc7c7c7000000c7c7c7686868000000000000000000000000000000000000a7a7a7000000000000c7c7c7000000c7c7c74d4d4d4d4d4d0000007c7c7c9a9a9a0000000000009a9a9a7c7c7c0000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000bdbdbd4d4d4d000000000000000000000000000000000000000000bdbdbd000000000000000000d9d9d9000000e9e9e9000000f0f0f0000000d9d9d90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000007c7c7c7c7c7ce1e1e1000000f0f0f0bdbdbd0000006868688c8c8c000000000000c7c7c7a7a7a7686868000000000000000000686868a7a7a70000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bdbdbd686868000000686868d9d9d9000000f0f0f09a9a9a000000000000b2b2b24d4d4da7a7a70000000000 +00000000b2b2b24d4d4d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000600000026060f00010000000600000026060f00020030000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000506b3b456d706c6f7965654f66666963653b456d706c6f79656553616c65733b4b65794163636f756e744d616e616765723b506b262378443b46 +49522d313030303030303131393823637573746f6d65723b535f4d49542d534223656d706c6f7965653b535f4d49542d50484f23656d706c6f7965653b23454d5054592d4b4559233b4753502d313030303030303636343823636f6e74616374706572736f6e262378443b4649522d313030303030303936312363757374 +6f6d65723b535f4d49542d54485223656d706c6f7965653b535f4d49542d4a5423656d706c6f7965653b23454d5054592d4b4559233b4753502d31303030303535373523636f6e74616374706572736f6e262378443b4649522d3130303030303039363123637573746f6d65723b535f4d49542d54485223656d706c6f79 +65653b535f4d49542d4a5423656d706c6f7965653b23454d5054592d4b4559233b4753502d31303030303337343323636f6e74616374706572736f6e262378443b4649522d3130303030303131303523637573746f6d65723b535f4d49542d4d4f4823656d706c6f7965653b535f4d49542d4a5423656d706c6f7965653b +23454d5054592d4b4559233b4753502d3130303030303131323423636f6e74616374706572736f6e262378443b4649522d3130303030303136323623637573746f6d65723b23454d5054592d4b4559233b535f4d49542d4d495223656d706c6f7965653b23454d5054592d4b4559233b4753502d31303030303032303535 +23636f6e74616374706572736f6e262378443b4649522d3130303030303136323623637573746f6d65723b23454d5054592d4b4559233b535f4d49542d4d495223656d706c6f7965653b23454d5054592d4b4559233b33686c6f6e7063313438386d72707337436f5065262378443b4649522d3130303030303136323623 +637573746f6d65723b23454d5054592d4b4559233b535f4d49542d4d495223656d706c6f7965653b23454d5054592d4b4559233b336e33376a6d35313530616572306771436f5065262378443b4649522d3130303030303136393023637573746f6d65723b535f4d49542d54485223656d706c6f7965653b535f4d49542d +4a5423656d706c6f7965653b23454d5054592d4b4559233b4753502d31303030303630393523636f6e74616374706572736f6e262378443b4649522d3130303030303136393023637573746f6d65723b535f4d49542d54485223656d706c6f7965653b535f4d49542d4a5423656d706c6f7965653b23454d5054592d4b45 +59233b4753502d31313030303431393323636f6e74616374706572736f6e262378443b4649522d31303030303238383323637573746f6d65723b535f4d49542d534223656d706c6f7965653b535f4d49542d54485223656d706c6f7965653b23454d5054592d4b4559233b4753502d31303030303439323423636f6e7461 +6374706572736f6e262378443b4649522d31303030303332303223637573746f6d65723b535f4d49542d54485223656d706c6f7965653b535f4d49542d4a5423656d706c6f7965653b23454d5054592d4b4559233b4753502d31303030303535353523636f6e74616374706572736f6e262378443b4649522d3130303030 +3333333323637573746f6d65723b535f4d49542d4d535423656d706c6f7965653b535f4d49542d4a5423656d706c6f7965653b23454d5054592d4b4559233b4753502d31303030303539323923636f6e74616374706572736f6e262378443b4649522d31303030303333333323637573746f6d65723b535f4d49542d4d53 +5423656d706c6f7965653b535f4d49542d4a5423656d706c6f7965653b23454d5054592d4b4559233b4753502d31303030303538393023636f6e74616374706572736f6e262378443b4649522d31303030303333333323637573746f6d65723b535f4d49542d4d535423656d706c6f7965653b535f4d49542d4a5423656d +706c6f7965653b23454d5054592d4b4559233b4753502d31303030303630353823636f6e74616374706572736f6e262378443b4649522d31303030303333333323637573746f6d65723b535f4d49542d4d535423656d706c6f7965653b535f4d49542d4a5423656d706c6f7965653b23454d5054592d4b4559233b475350 +2d31303030303539333023636f6e74616374706572736f6e262378443b4649522d3130303239303923637573746f6d65723b535f4d49542d54485223656d706c6f7965653b535f4d49542d4a5423656d706c6f7965653b23454d5054592d4b4559233b4753502d3130303030303138333823636f6e74616374706572736f +6e262378443b4649522d3130303239343923637573746f6d65723b535f4d49542d4d4f4823656d706c6f7965653b535f4d49542d4a5423656d706c6f7965653b23454d5054592d4b4559233b4753502d3130303434343323636f6e74616374706572736f6e262378443b4649522d3130303332383023637573746f6d6572 +3b535f4d49542d44474523656d706c6f7965653b535f4d49542d4d5723656d706c6f7965653b23454d5054592d4b4559233b4753502d31303030303536323523636f6e74616374706572736f6e262378443b4649522d3130303339343923637573746f6d65723b535f4d49542d475623656d706c6f7965653b535f4d4954 +2d54485223656d706c6f7965653b535f4d49542d475623656d706c6f7965653b4753502d31303030303530313223636f6e74616374706572736f6e262378443b4649522d3130303430303523637573746f6d65723b535f4d49542d4d4f4823656d706c6f7965653b535f4d49542d4a5423656d706c6f7965653b23454d50 +54592d4b4559233b4753502d3130303538393323636f6e74616374706572736f6e262378443b4649522d31313030303235333023637573746f6d65723b535f4d49542d54485223656d706c6f7965653b535f4d49542d4a5423656d706c6f7965653b23454d5054592d4b4559233b4753502d31313030303431353923636f +6e74616374706572736f6e262378443b4649522d31343723637573746f6d65723b535f4d49542d4d4f4823656d706c6f7965653b535f4d49542d4a5423656d706c6f7965653b23454d5054592d4b4559233b4753502d31303030303630393723636f6e74616374706572736f6e262378443b4649522d3134372363757374 +6f6d65723b535f4d49542d4d4f4823656d706c6f7965653b535f4d49542d4a5423656d706c6f7965653b23454d5054592d4b4559233b4753502d313030303030303636353323636f6e74616374706572736f6e262378443b4649522d31343723637573746f6d65723b535f4d49542d4d4f4823656d706c6f7965653b535f +4d49542d4a5423656d706c6f7965653b23454d5054592d4b4559233b4753502d31303030303630393823636f6e74616374706572736f6e262378443b4649522d31343723637573746f6d65723b535f4d49542d4d4f4823656d706c6f7965653b535f4d49542d4a5423656d706c6f7965653b23454d5054592d4b4559233b +4753502d31303030303630393623636f6e74616374706572736f6e262378443b4649522d31353723637573746f6d65723b535f4d49542d54485223656d706c6f7965653b535f4d49542d4a5423656d706c6f7965653b23454d5054592d4b4559233b4753502d31303030303438393623636f6e74616374706572736f6e26 +2378443b4649522d31353723637573746f6d65723b535f4d49542d54485223656d706c6f7965653b535f4d49542d4a5423656d706c6f7965653b23454d5054592d4b4559233b636a6f6c32673133366673306f6e63436f5065262378443b4649522d31353723637573746f6d65723b535f4d49542d54485223656d706c6f +7965653b535f4d49542d4a5423656d706c6f7965653b23454d5054592d4b4559233b4753502d31353723636f6e74616374706572736f6e262378443b4649522d3137333623637573746f6d65723b535f4d49542d4d4f4823656d706c6f7965653b535f4d49542d4a5423656d706c6f7965653b23454d5054592d4b455923 +3b4753502d3239353623636f6e74616374706572736f6e262378443b4649522d33333723637573746f6d65723b535f4d49542d54485223656d706c6f7965653b535f4d49542d4a5423656d706c6f7965653b23454d5054592d4b4559233b4753502d31303030303332393223636f6e74616374706572736f6e262378443b +4649522d33333723637573746f6d65723b535f4d49542d54485223656d706c6f7965653b535f4d49542d4a5423656d706c6f7965653b23454d5054592d4b4559233b4753502d3130303030303132333723636f6e74616374706572736f6e262378443b4649522d35363030303030393823637573746f6d65723b535f4d49 +542d484723656d706c6f7965653b535f4d49542d4445565523656d706c6f7965653b23454d5054592d4b4559233b4753502d313030303030303237303023636f6e74616374706572736f6e262378443b4649522d36373023637573746f6d65723b535f4d49542d54485223656d706c6f7965653b535f4d49542d4a542365 +6d706c6f7965653b23454d5054592d4b4559233b4753502d31303030303630363723636f6e74616374706572736f6e262378443b4649522d36373023637573746f6d65723b535f4d49542d54485223656d706c6f7965653b535f4d49542d4a5423656d706c6f7965653b23454d5054592d4b4559233b4753502d31303030 +303334353123636f6e74616374706572736f6e262378443b4649522d36373023637573746f6d65723b535f4d49542d54485223656d706c6f7965653b535f4d49542d4a5423656d706c6f7965653b23454d5054592d4b4559233b4753502d31303030303537323023636f6e74616374706572736f6e262378443b4649522d +36373023637573746f6d65723b535f4d49542d54485223656d706c6f7965653b535f4d49542d4a5423656d706c6f7965653b23454d5054592d4b4559233b4753502d31303030303334373723636f6e74616374706572736f6e262378443b494d504f52545f484f505045205354414454414c4c454e444f52462363757374 +6f6d65723b23454d5054592d4b4559233b23454d5054592d4b4559233b23454d5054592d4b4559233b494d504f52545f486f70706520576f6c6623436f6e74616374506572736f6e262378443b31696368613269313767636a3638616d43753b23454d5054592d4b4559233b23454d5054592d4b4559233b23454d505459 +2d4b4559233b31696368613269313767636a3638616d4375233175706d61646b5065436f5065262378443b316a3635346c7131373830736665706243753b535f4d49542d544d5223656d706c6f7965653b535f4d49542d544d5223656d706c6f7965653b23454d5054592d4b4559233b316a3635346c7131373830736665 +7062437523336c696c3434355065436f5065262378443b3134673369697631336d74346b65687543753b23454d5054592d4b4559233b535f4d49542d414c4123656d706c6f7965653b23454d5054592d4b4559233b3134673369697631336d74346b6568754375233170716b757636436f5065262378443b313467336969 +7631336d74346b65687543753b23454d5054592d4b4559233b535f4d49542d414c4123656d706c6f7965653b23454d5054592d4b4559233b3233726b36687431336d74346d666c64436f5065262378443b3134673369697631336d74346b65687543753b23454d5054592d4b4559233b535f4d49542d414c4123656d706c +6f7965653b23454d5054592d4b4559233b31396e6a626b62313172386c65377238436f506523326b3973326539436f5065262378443b3134673369697631336d74346b65687543753b23454d5054592d4b4559233b535f4d49542d414c4123656d706c6f7965653b23454d5054592d4b4559233b33726c6375306a313775 +76356c64696f436f5065262378443b326f6b36723034313336757070346f3443753b23454d5054592d4b4559233b23454d5054592d4b4559233b23454d5054592d4b4559233b326f6b36723034313336757070346f34437523336a366c6c6731436f5065262378443b3235636b38763631377030356d76756643753b2345 +4d5054592d4b4559233b31766531706f3031366e723476323966436f506523336937356c6b71456d3b23454d5054592d4b4559233b32696c753162723138757135716c6436436f5065262378443b3235636b38763631377030356d76756643753b23454d5054592d4b4559233b31766531706f3031366e72347632396643 +6f506523336937356c6b71456d3b23454d5054592d4b4559233b3235636b38763631377030356d767566437523756a7173736f5065436f5065262378443b3235636b38763631377030356d76756643753b23454d5054592d4b4559233b31766531706f3031366e723476323966436f506523336937356c6b71456d3b2345 +4d5054592d4b4559233b333235707362753138757164706c726c436f5065262378443b32367230353866313631306c336d687343753b23454d5054592d4b4559233b7663763872313132306f326768736543752333696865316975456d3b23454d5054592d4b4559233b32356e36693739313631306c38663866436f5065 +262378443b32367230353866313631306c336d687343753b23454d5054592d4b4559233b7663763872313132306f326768736543752333696865316975456d3b23454d5054592d4b4559233b32367230353866313631306c336d687343752333686e307364755065436f5065262378443b32377165726266313361673439 +70623643753b23454d5054592d4b4559233b23454d5054592d4b4559233b23454d5054592d4b4559233b32377165726266313361673439706236437523326b6f35683936436f5065262378443b3362713272733137756b3737736f6d43753b23454d5054592d4b4559233b23454d5054592d4b4559233b23454d5054592d +4b4559233b32736876316b713137756b376b636869436f5065262378443b3362713272733137756b3737736f6d43753b23454d5054592d4b4559233b23454d5054592d4b4559233b23454d5054592d4b4559233b3362713272733137756b3737736f6d4375236475706f32395065436f5065262378443b336d73326c376c +31326137653275387343753b23454d5054592d4b4559233b23454d5054592d4b4559233b23454d5054592d4b4559233b336d73326c376c31326137653275387343752332356375393761436f5065262378443b336d73326c376c31326137653275387343753b23454d5054592d4b4559233b23454d5054592d4b4559233b +23454d5054592d4b4559233b3269766a6b6a323132613765366c3136436f5065262378443b336d73326c376c31326137653275387343753b23454d5054592d4b4559233b23454d5054592d4b4559233b23454d5054592d4b4559233b3334326868616e313262653372613668436f5065262378443b333771616763313133 +727331646e757643753b23454d5054592d4b4559233b23454d5054592d4b4559233b23454d5054592d4b4559233b333771616763313133727331646e757643752332763335617136436f50650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000001050000050000000d0000004d45544146494c455049435400ec090000a1f7ffff5c4300000800ec095f080000 +010009000003aa21000000006f19000000000400000003010800050000000b0200000000050000000c025100600005000000090200000000050000000102ffffff00a5000000410bc60088002000200000000000200020000000200028000000200000004000000001000100000000000001000000000000000000000000 +00000000000000000000ffffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000fffffffffc000001fc000001fc000001fc000001fc000001fc000001fc000001fc000001fc000001fc000001fc000001fc0000018000000180000001800000018000000180000001800000018000000180000001800000018000000180000001800000018000000180000003c000 +0007e000000ffc00001ffc00003fffffffff21060000410b46006600200020000000000020002000000020002800000020000000200000000100180000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b9a495917c6a78614c6a533c664e37624a32604830604830604830604830604830604830604830604830604830604830604830604830 +604830604830604830604830604830604830604830000000000000000000000000000000000000000000b9a495fceadfdfcdc4ddc5b7debdacdeb8a2e3b298e5b390e5b390e5b390e5b28ee6b08be7af88e9ad85eaac82ebaa7feca77beea577efa373f1a16ff1a06bf39e68f39d65f49b63604830000000000000000000 +000000000000000000000000baa596fcebe1fcebe1fcebe1fcebe0fbeadffbe9dffbe9defbe9ddfae8dcfbe7dcfae6dafae6d9fae5d7fae4d6fae3d4fae2d3f9e0d2f9e0cff9decef9ddccf9dccaf9dbc8f49c65604830000000000000000000000000000000000000000000bba697fceee4fbede4fcede4fbece4fbece3 +fcebe2fbebe2fbebe0fbeadffbe9dffbe9ddfbe8dcfae7dafae6dafae4d8fae4d6f9e2d4fae1d3a88877f9dfcff9decdf9dccaf39d67604830000000000000000000000000000000000000000000bba698fcefe7fcefe7fbefe6fcefe6fcefe6fcede5fcede4fcede4fcece3fcebe2fceae1fceadffbeadefbe8dcfbe7db +fae6dafae5d7fae4d59b7b69906e5cfae0d0fadfcef29e6a604830000000000000000000000000000000000000000000bca899fcf1eafcf1e9fcf1eafcf0e9fcf0e9fcf0e8fdefe8fcefe7fceee6fceee5f2e2d8d4beb3e8d5c9fceae0fce9defbe8ddfbe7dbfae5d9f9e4d7694431d5b9a9fae0d0f1a06d604830000000 +000000000000000000000000000000000000bda999fdf3edfdf3edfdf3ecfdf2ecfdf3ebfdf2ebfcf2eafdf1eafdf1e9c0aa9e67422f66412e66412e7e5d4bfcebe1714d3b66412e775441bfa4957e5b497e5b49fae2d3f0a270604830000000000000000000000000000000000000000000bda99afdf5effdf4effdf4ef +fdf4eefdf4eefdf4eefdf3edfdf3edfcf2eb69443166412ed4c2b7fcf0e7b79e917e5d4b6c483566412ed4bcaffbe8dcb69a8a6c4835d5baadefa373604830000000000000000000000000000000000000000000bfaa9bfef6f1fdf6f1fdf6f1fdf6f1fdf6f1fef5f0fdf5f0fdf5f0fdf4ef66412e714e3cfdf2ecfcf1ea +fcf0e9e9d8cf69443166412ed4beb2fceadffbe8ddfbe7dafae5d8eda577604830000000000000000000000000000000000000000000c0ab9dfdf8f3fdf7f3fef7f3fef7f3fef7f3fdf7f3fdf7f2fdf7f2fdf6f16c4836694431fdf4eefdf3edfdf3ecfcf1ea714e3b66412ed4c0b4fcebe2fbeae0fbe9ddfbe7dbeda77b +604830000000000000000000000000000000000000000000c0ac9efef9f5fef9f5fef9f5fef8f5fef8f5fef8f5fef8f5fdf7f4fef7f3d5c6be67422f7e5e4de9ddd6fdf4eefdf3ed714e3b66412ed4c1b6fceee4fbece2fbeae0fbe8ddeba97f604830000000000000000000000000000000000000000000c1ae9efefaf7 +fefaf7fefaf7fef9f7fef9f7fefaf7fef9f7fef9f6fef9f6fef8f5eae0da917566714e3c6c48367e5e4d69443166412ed4c1b7fcefe7fceee5fcece3fbeadfe9ab83604830000000000000348037347d32337a2e337729327325327020316c1c306a1730661330630f2f600b2f5d082f5c052e5a032e58002e5800fef9f6 +fef8f5fef8f4fef7f3e9ded76c483666412ed5c3b9fcf1e9fcefe7fcede4fcece2e8ae8760483000000000000035833affffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2e5800917668fefaf7fef9f6fef8f5fef7f369443166412ed5c4bafdf2ecfcf1e9fdefe7 +fcede4e6af8b60483000000000000036863effffffd3ead2cfe8cecae7c8c4e6c3bee4bbb8e3b6b2e1afade1a9a8dfa4a4dfa0a2df9fa4dfa0ffffff2e590266412eb7a59bfefaf8f4ede97e5e4e66412e67422ffdf4effdf3edfdf2ebfdf0e8fceee6e5b18f604830000000000000368a42ffffffd3e9d273c3951ea164 +219b58238d3f277c22548d39eef7f16bc08742a95f5cb16df9faf8f9faf72f5b05e0d7d2714e3c66412e66412e66412e694432dfd3ccfdf6f1fdf4effdf3edfcf1eafcf0e8e5b392604830000000000000378c46ffffffd3ead2cfe9cd2f9651238c3e25822d2c791b6a984990d6af41b6703faf67b9dfc4f9fbf9fcfdfc +2f5d07fffdfcfefcfbeae3dfd5c9c3e0d5d0fef9f6fef8f4fdf7f3fdf6f1fdf4eefdf2edfdf1eae4b596604830000000000000378e49ffffffd4e9d3cfe9cfa7d1a8287a1c2a77133e7a11c9ecda43c38442bd7c80cfa1f9fdfbf1f9f2ffffff2f600afffdfdfffdfcfefcfbfefbfafefbf9fefaf7fef9f5fef8f4fef6f2 +fef5f0fdf4eefdf2ece2b79a60483000000000000037904cffffffd5e9d4d1e9cfcde8cb6ba153326100345c034fc99145c98d5bca94ecf8f2f9fdfbace1a9ffffff30610dfffefdfffdfcfffdfcfffcfbfffbfafefaf8fefaf7fef8f5fdf7f3fef6f1fdf4effdf3ede1b99c60483000000000000037934effffffd6ead5 +d2e9d2cee8cdcae7c84566183f9e5b47d19a46cc92b3e7cffafefccdecccb2e1afffffff316410fffefefffefdfffdfcfffcfbfffcfafefbf9fefaf8fef9f6fef8f4fef6f2fdf6f0fdf3eee1ba9f604830000000000000389450ffffffd7ead6d5e9d4d1e9cfcde8cc83c18e45c98e45cc924cad76fafdfcf9fbf9b7e3b4 +b8e3b5ffffff306715fffefefffefdfffefdfffdfcfffcfbfefbf9fefaf8fefaf7fef8f5fef7f3fdf6f1fdf5efdfbba1604830000000000000389552ffffffd7ead7d6ead5d3e9d2cce8cd54c38744c38444be804666339aa98ef8f9f7f5f8f4bee5bcffffff316a18fffefefffefdfffdfdfffdfcfffcfbfefcfafefbf9 +dbc9c0dbc2afdebba5debba5debba5dfbca3604830000000000000358d4efefefeddeeddd7ead7d5ead578c69141b67141ba7849844e4a63314b6433e4e7e0f8f9f7daeed9ffffff316d1dfffefefffefdfffefdfffdfcfffdfbfffcfabeac9d8c766388725e816b577a634e725b456a533c6048300000000000002e7b42 +eff7f1eaf4ead7ead7aed6b33da85b3ead647fca9ad7ded34b64334b6433657a50f8f9f7f8f9f7fefefe327021fffefefffefdfffdfdfffdfcfffdfcfffcfbbfad9decd2bfeacebbe7cab5e4c4aee1bea9604830100d090000000000001f552ec0dec9f7fbf7d7ead73b9a463b9f4e40a659ecf4ecf9faf8859e774b6433 +4b6433899a7af8f9f7fafbf9327425fffefefffefefffefdfffefdfffdfcfffcfbc1ae9fffeee4fbe8dcf4ded0eed4c3604830100d090a08050000000000000f2a165e9f70edf5eff7fbf7eaf4eaddeeddd7ead7d7ead6d6ead5d5ead5d4e9d3d3e9d3d3ead2d3e9d2ffffff337729fffefefffefefffefdfefefdfffdfc +fffdfbc2b0a0ffeee4fbe8dcf5ded0654e36100d090a0805000000000000000000000000112f195e9f70c0dec9eff7f1fefefeffffffffffffffffffffffffffffffffffffffffffffffffffffff347a2dfffefefffefefffefdfffdfdfffdfcfffdfbc4b2a3ffeee4fbe8dc6c553e100d090a0805000000000000000000 +0000000000000000000f2a161f552e2e7b423e975638945138934f37914d378f4a378d46368a4235873e35843a358036347c31fffefefffefefffefefffefdfffdfdfffdfcc6b4a4ffeee4836e59100d090a0805000000000000000000000000000000000000000000000000000000000000d0beb1ffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffefefffffefffefefffefefffdfdfffdfcc8b5a59c8674100d090a0805000000000000000000000000000000000000000000000000000000000000000000d1bfb1d1bfb1d1bfb1d1bfb1d0beb0cfbdafcfbdafcfbcaecdbbadcdbbaccdb9acccb9abcbb8aacab7a9 +cab7a8c9b6a7c8b6a7c9b6a6100d090a0705000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000a00000026060f00090049636f6e4f6e6c790000050000000102ffffff0005000000090200000000310100004009c6008800000000002d0060002400000028000000600000002d00000001000100000000001c0200000000000000000000000000000000000000000000ffffff00ffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffff8106398473ffffffffffffff0922391f21ffffffffffffff3ff23f3e21ffffffffffffff3fe09f3c61ffffffffffffff3f849f1cccffffffffffffff3f1c9f844cffffffffffffff3f388fffffffffffffffffff8931cfffffffffffffffffffc101cffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffff6f19000040098600ee00000000002d0060002400000028000000600000002d0000000100180000000000a0320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e9e9e99a9a9a0000000000008c8c8ce9e9e9000000bdbd +bd686868000000686868bdbdbd000000000000e9e9e9000000e9e9e9000000000000000000686868d9d9d90000000000009a9a9a000000000000d0d0d00000004d4d4d0000008c8c8c0000000000000000008c8c8ca7a7a70000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000f0f0f04d4d4d8c8c8cf0f0f0000000f0f0f0bdbdbd000000b2b2b2f0f0f0000000d0d0d0000000d9d9d9000000a7a7a7000000b2b2b2000000000000000000686868d9d9d90000009a9a9a686868f0f0f0000000000000000000000000000000000000bdbdbd000000f0f0f0000000000000f0f0 +f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009a9a9a686868000000000000000000000000000000000000000000000000000000000000000000bdbdbd0000004d4d4da7a7a7686868000000000000000000000000000000000000000000bdbdbd0000 +00000000000000000000000000a7a7a7000000e1e1e1000000a7a7a79a9a9a9a9a9abdbdbd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004d4d4db2b2b20000000000000000000000000000000000000000000000000000009a9a9a4d4d4df0f0f0d9d9 +d9000000000000000000e9e9e90000000000000000000000000000004d4d4dbdbdbd0000000000000000000000007c7c7c7c7c7ce1e1e10000000000004d4d4dd0d0d0d0d0d04d4d4d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bdbdbd0000 +00000000000000000000000000000000000000bdbdbd4d4d4d7c7c7ce9e9e9000000a7a7a79a9a9a0000009a9a9ab2b2b2000000000000000000000000000000a7a7a7686868f0f0f0000000000000000000000000b2b2b2000000000000d0d0d0000000000000000000000000d0d0d00000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000686868b2b2b2000000000000000000000000000000000000b2b2b24d4d4dd0d0d00000000000000000004d4d4dc7c7c7000000c7c7c7686868000000000000000000000000000000000000a7a7a7000000000000c7c7c7000000c7c7c74d4d4d4d4d +4d0000007c7c7c9a9a9a0000000000009a9a9a7c7c7c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bdbdbd4d4d4d000000000000000000000000000000000000000000bdbdbd000000000000000000d9d9d9000000e9e9e9000000f0f0f0000000d9d9d90000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007c7c7c7c7c7ce1e1e1000000f0f0f0bdbdbd0000006868 +688c8c8c000000000000c7c7c7a7a7a7686868000000000000000000686868a7a7a70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000bdbdbd686868000000686868d9d9d9000000f0f0f09a9a9a000000000000b2b2b24d4d4da7a7a7000000000000000000b2b2b24d4d4d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000026060f00010000000600000026060f0002003000030000000000}{\result {\rtlch \af0 \ltrch \insrsid1511220 +{\pict{\*\picprop\shplid1025{\sp{\sn shapeType}{\sv 75}}{\sp{\sn fFlipH}{\sv 0}}{\sp{\sn fFlipV}{\sv 0}}{\sp{\sn fLine}{\sv 0}}{\sp{\sn fOleIcon}{\sv 1}}{\sp{\sn fLayoutInCell}{\sv 1}}{\sp{\sn fLayoutInCell}{\sv 1}}} +\picscalex100\picscaley100\piccropl0\piccropr0\piccropt0\piccropb0\picw2540\pich2143\picwgoal1440\pichgoal1215\wmetafile8\bliptag-1849847755\blipupi96{\*\blipuid 91bd9035edb6d261dfd1560171c84243} +010009000003aa21000000006f19000000000400000003010800050000000b0200000000050000000c025100600005000000090200000000050000000102ffff +ff00a5000000410bc600880020002000000000002000200000002000280000002000000040000000010001000000000000010000000000000000000000000000 +0000000000000000ffffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000fffffffffc000001fc000001fc000001fc000001fc000001fc000001fc000001fc000001fc000001fc000001fc000001fc000001 +8000000180000001800000018000000180000001800000018000000180000001800000018000000180000001800000018000000180000003c0000007e000000f +fc00001ffc00003fffffffff21060000410b46006600200020000000000020002000000020002800000020000000200000000100180000000000000c00000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +b9a495917c6a78614c6a533c664e37624a3260483060483060483060483060483060483060483060483060483060483060483060483060483060483060483060 +4830604830604830604830000000000000000000000000000000000000000000b9a495fceadfdfcdc4ddc5b7debdacdeb8a2e3b298e5b390e5b390e5b390e5b2 +8ee6b08be7af88e9ad85eaac82ebaa7feca77beea577efa373f1a16ff1a06bf39e68f39d65f49b63604830000000000000000000000000000000000000000000 +baa596fcebe1fcebe1fcebe1fcebe0fbeadffbe9dffbe9defbe9ddfae8dcfbe7dcfae6dafae6d9fae5d7fae4d6fae3d4fae2d3f9e0d2f9e0cff9decef9ddccf9 +dccaf9dbc8f49c65604830000000000000000000000000000000000000000000bba697fceee4fbede4fcede4fbece4fbece3fcebe2fbebe2fbebe0fbeadffbe9 +dffbe9ddfbe8dcfae7dafae6dafae4d8fae4d6f9e2d4fae1d3a88877f9dfcff9decdf9dccaf39d67604830000000000000000000000000000000000000000000 +bba698fcefe7fcefe7fbefe6fcefe6fcefe6fcede5fcede4fcede4fcece3fcebe2fceae1fceadffbeadefbe8dcfbe7dbfae6dafae5d7fae4d59b7b69906e5cfa +e0d0fadfcef29e6a604830000000000000000000000000000000000000000000bca899fcf1eafcf1e9fcf1eafcf0e9fcf0e9fcf0e8fdefe8fcefe7fceee6fcee +e5f2e2d8d4beb3e8d5c9fceae0fce9defbe8ddfbe7dbfae5d9f9e4d7694431d5b9a9fae0d0f1a06d604830000000000000000000000000000000000000000000 +bda999fdf3edfdf3edfdf3ecfdf2ecfdf3ebfdf2ebfcf2eafdf1eafdf1e9c0aa9e67422f66412e66412e7e5d4bfcebe1714d3b66412e775441bfa4957e5b497e +5b49fae2d3f0a270604830000000000000000000000000000000000000000000bda99afdf5effdf4effdf4effdf4eefdf4eefdf4eefdf3edfdf3edfcf2eb6944 +3166412ed4c2b7fcf0e7b79e917e5d4b6c483566412ed4bcaffbe8dcb69a8a6c4835d5baadefa373604830000000000000000000000000000000000000000000 +bfaa9bfef6f1fdf6f1fdf6f1fdf6f1fdf6f1fef5f0fdf5f0fdf5f0fdf4ef66412e714e3cfdf2ecfcf1eafcf0e9e9d8cf69443166412ed4beb2fceadffbe8ddfb +e7dafae5d8eda577604830000000000000000000000000000000000000000000c0ab9dfdf8f3fdf7f3fef7f3fef7f3fef7f3fdf7f3fdf7f2fdf7f2fdf6f16c48 +36694431fdf4eefdf3edfdf3ecfcf1ea714e3b66412ed4c0b4fcebe2fbeae0fbe9ddfbe7dbeda77b604830000000000000000000000000000000000000000000 +c0ac9efef9f5fef9f5fef9f5fef8f5fef8f5fef8f5fef8f5fdf7f4fef7f3d5c6be67422f7e5e4de9ddd6fdf4eefdf3ed714e3b66412ed4c1b6fceee4fbece2fb +eae0fbe8ddeba97f604830000000000000000000000000000000000000000000c1ae9efefaf7fefaf7fefaf7fef9f7fef9f7fefaf7fef9f7fef9f6fef9f6fef8 +f5eae0da917566714e3c6c48367e5e4d69443166412ed4c1b7fcefe7fceee5fcece3fbeadfe9ab83604830000000000000348037347d32337a2e337729327325 +327020316c1c306a1730661330630f2f600b2f5d082f5c052e5a032e58002e5800fef9f6fef8f5fef8f4fef7f3e9ded76c483666412ed5c3b9fcf1e9fcefe7fc +ede4fcece2e8ae8760483000000000000035833affffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2e58 +00917668fefaf7fef9f6fef8f5fef7f369443166412ed5c4bafdf2ecfcf1e9fdefe7fcede4e6af8b60483000000000000036863effffffd3ead2cfe8cecae7c8 +c4e6c3bee4bbb8e3b6b2e1afade1a9a8dfa4a4dfa0a2df9fa4dfa0ffffff2e590266412eb7a59bfefaf8f4ede97e5e4e66412e67422ffdf4effdf3edfdf2ebfd +f0e8fceee6e5b18f604830000000000000368a42ffffffd3e9d273c3951ea164219b58238d3f277c22548d39eef7f16bc08742a95f5cb16df9faf8f9faf72f5b +05e0d7d2714e3c66412e66412e66412e694432dfd3ccfdf6f1fdf4effdf3edfcf1eafcf0e8e5b392604830000000000000378c46ffffffd3ead2cfe9cd2f9651 +238c3e25822d2c791b6a984990d6af41b6703faf67b9dfc4f9fbf9fcfdfc2f5d07fffdfcfefcfbeae3dfd5c9c3e0d5d0fef9f6fef8f4fdf7f3fdf6f1fdf4eefd +f2edfdf1eae4b596604830000000000000378e49ffffffd4e9d3cfe9cfa7d1a8287a1c2a77133e7a11c9ecda43c38442bd7c80cfa1f9fdfbf1f9f2ffffff2f60 +0afffdfdfffdfcfefcfbfefbfafefbf9fefaf7fef9f5fef8f4fef6f2fef5f0fdf4eefdf2ece2b79a60483000000000000037904cffffffd5e9d4d1e9cfcde8cb +6ba153326100345c034fc99145c98d5bca94ecf8f2f9fdfbace1a9ffffff30610dfffefdfffdfcfffdfcfffcfbfffbfafefaf8fefaf7fef8f5fdf7f3fef6f1fd +f4effdf3ede1b99c60483000000000000037934effffffd6ead5d2e9d2cee8cdcae7c84566183f9e5b47d19a46cc92b3e7cffafefccdecccb2e1afffffff3164 +10fffefefffefdfffdfcfffcfbfffcfafefbf9fefaf8fef9f6fef8f4fef6f2fdf6f0fdf3eee1ba9f604830000000000000389450ffffffd7ead6d5e9d4d1e9cf +cde8cc83c18e45c98e45cc924cad76fafdfcf9fbf9b7e3b4b8e3b5ffffff306715fffefefffefdfffefdfffdfcfffcfbfefbf9fefaf8fefaf7fef8f5fef7f3fd +f6f1fdf5efdfbba1604830000000000000389552ffffffd7ead7d6ead5d3e9d2cce8cd54c38744c38444be804666339aa98ef8f9f7f5f8f4bee5bcffffff316a +18fffefefffefdfffdfdfffdfcfffcfbfefcfafefbf9dbc9c0dbc2afdebba5debba5debba5dfbca3604830000000000000358d4efefefeddeeddd7ead7d5ead5 +78c69141b67141ba7849844e4a63314b6433e4e7e0f8f9f7daeed9ffffff316d1dfffefefffefdfffefdfffdfcfffdfbfffcfabeac9d8c766388725e816b577a +634e725b456a533c6048300000000000002e7b42eff7f1eaf4ead7ead7aed6b33da85b3ead647fca9ad7ded34b64334b6433657a50f8f9f7f8f9f7fefefe3270 +21fffefefffefdfffdfdfffdfcfffdfcfffcfbbfad9decd2bfeacebbe7cab5e4c4aee1bea9604830100d090000000000001f552ec0dec9f7fbf7d7ead73b9a46 +3b9f4e40a659ecf4ecf9faf8859e774b64334b6433899a7af8f9f7fafbf9327425fffefefffefefffefdfffefdfffdfcfffcfbc1ae9fffeee4fbe8dcf4ded0ee +d4c3604830100d090a08050000000000000f2a165e9f70edf5eff7fbf7eaf4eaddeeddd7ead7d7ead6d6ead5d5ead5d4e9d3d3e9d3d3ead2d3e9d2ffffff3377 +29fffefefffefefffefdfefefdfffdfcfffdfbc2b0a0ffeee4fbe8dcf5ded0654e36100d090a0805000000000000000000000000112f195e9f70c0dec9eff7f1 +fefefeffffffffffffffffffffffffffffffffffffffffffffffffffffff347a2dfffefefffefefffefdfffdfdfffdfcfffdfbc4b2a3ffeee4fbe8dc6c553e10 +0d090a08050000000000000000000000000000000000000f2a161f552e2e7b423e975638945138934f37914d378f4a378d46368a4235873e35843a358036347c +31fffefefffefefffefefffefdfffdfdfffdfcc6b4a4ffeee4836e59100d090a0805000000000000000000000000000000000000000000000000000000000000 +d0beb1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefffffefffefefffefefffdfdfffdfcc8b5a59c8674100d090a080500 +0000000000000000000000000000000000000000000000000000000000000000d1bfb1d1bfb1d1bfb1d1bfb1d0beb0cfbdafcfbdafcfbcaecdbbadcdbbaccdb9 +acccb9abcbb8aacab7a9cab7a8c9b6a7c8b6a7c9b6a6100d090a0705000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000a00000026060f00090049636f6e4f6e6c790000050000000102ffffff0005000000090200000000310100004009c6008800 +000000002d0060002400000028000000600000002d00000001000100000000001c0200000000000000000000000000000000000000000000ffffff00ffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffff8106398473ffffffffffffff0922391f21ffffffffffffff3ff23f3e21ffffffffffffff3fe09f3c61ffffffffffffff3f849f1cc +cffffffffffffff3f1c9f844cffffffffffffff3f388fffffffffffffffffff8931cfffffffffffffffffffc101cffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffff6f19000040098600ee00000000002d0060002400000028000000600000002d000000010018000000 +0000a032000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000e9e9e99a9a9a0000000000008c8c8ce9e9e9000000bdbdbd686868000000686868bdbdbd000000000000e9e9e9000000e9e9e9 +000000000000000000686868d9d9d90000000000009a9a9a000000000000d0d0d00000004d4d4d0000008c8c8c0000000000000000008c8c8ca7a7a700000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000f0f0f04d4d4d8c8c8cf0f0f0000000f0f0f0bdbdbd00 +0000b2b2b2f0f0f0000000d0d0d0000000d9d9d9000000a7a7a7000000b2b2b2000000000000000000686868d9d9d90000009a9a9a686868f0f0f00000000000 +00000000000000000000000000bdbdbd000000f0f0f0000000000000f0f0f0000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000009a9a9a686868000000000000000000000000000000000000000000000000000000000000000000bdbdbd0000004d4d4da7a7a7686868 +000000000000000000000000000000000000000000bdbdbd000000000000000000000000000000a7a7a7000000e1e1e1000000a7a7a79a9a9a9a9a9abdbdbd00 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000004d4d4db2b2b200000000000000000000000000000000 +00000000000000000000009a9a9a4d4d4df0f0f0d9d9d9000000000000000000e9e9e90000000000000000000000000000004d4d4dbdbdbd0000000000000000 +000000007c7c7c7c7c7ce1e1e10000000000004d4d4dd0d0d0d0d0d04d4d4d000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000bdbdbd000000000000000000000000000000000000000000bdbdbd4d4d4d7c7c7ce9e9e9000000a7a7a79a9a9a0000009a9a9a +b2b2b2000000000000000000000000000000a7a7a7686868f0f0f0000000000000000000000000b2b2b2000000000000d0d0d0000000000000000000000000d0 +d0d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000686868b2b2b200000000000000000000000000000000 +0000b2b2b24d4d4dd0d0d00000000000000000004d4d4dc7c7c7000000c7c7c7686868000000000000000000000000000000000000a7a7a7000000000000c7c7 +c7000000c7c7c74d4d4d4d4d4d0000007c7c7c9a9a9a0000000000009a9a9a7c7c7c000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000bdbdbd4d4d4d000000000000000000000000000000000000000000bdbdbd000000000000000000d9d9d9000000e9e9e9000000f0f0f0 +000000d9d9d900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007c7c7c7c7c7ce1e1e1000000f0f0f0bdbdbd00 +00006868688c8c8c000000000000c7c7c7a7a7a7686868000000000000000000686868a7a7a70000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000bdbdbd686868000000686868d9d9d9000000f0f0f09a9a9a000000000000b2b2b24d4d4da7a7a7000000000000000000 +b2b2b24d4d4d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000026060f00010000000600000026060f0002003000030000000000}}}}}{\rtlch \af1 \ltrch \insrsid12323684 +\par }} \ No newline at end of file diff --git a/Examples/Data/OLE spreadsheet.docm b/Examples/Data/OLE spreadsheet.docm new file mode 100644 index 00000000..44c057c1 Binary files /dev/null and b/Examples/Data/OLE spreadsheet.docm differ diff --git a/Examples/Data/Odso data.docx b/Examples/Data/Odso data.docx new file mode 100644 index 00000000..b74059cb Binary files /dev/null and b/Examples/Data/Odso data.docx differ diff --git a/Examples/Data/Office math.docx b/Examples/Data/Office math.docx new file mode 100644 index 00000000..7d70f6d6 Binary files /dev/null and b/Examples/Data/Office math.docx differ diff --git a/Examples/Data/OpenType text shaping.docx b/Examples/Data/OpenType text shaping.docx new file mode 100644 index 00000000..927f2b2b Binary files /dev/null and b/Examples/Data/OpenType text shaping.docx differ diff --git a/Examples/Data/PDF artifacts.docx b/Examples/Data/PDF artifacts.docx new file mode 100644 index 00000000..72e1154e Binary files /dev/null and b/Examples/Data/PDF artifacts.docx differ diff --git a/Examples/Data/Page fields.docx b/Examples/Data/Page fields.docx new file mode 100644 index 00000000..85ea6263 Binary files /dev/null and b/Examples/Data/Page fields.docx differ diff --git a/Examples/Data/Paragraph frame.docx b/Examples/Data/Paragraph frame.docx new file mode 100644 index 00000000..69bf6520 Binary files /dev/null and b/Examples/Data/Paragraph frame.docx differ diff --git a/Examples/Data/Paragraphs.docx b/Examples/Data/Paragraphs.docx new file mode 100644 index 00000000..4c311806 Binary files /dev/null and b/Examples/Data/Paragraphs.docx differ diff --git a/Examples/Data/Pdf Document.pdf b/Examples/Data/Pdf Document.pdf new file mode 100644 index 00000000..15301cc2 Binary files /dev/null and b/Examples/Data/Pdf Document.pdf differ diff --git a/Examples/Data/Phonetic guide.docx b/Examples/Data/Phonetic guide.docx new file mode 100644 index 00000000..4cbb1bd1 Binary files /dev/null and b/Examples/Data/Phonetic guide.docx differ diff --git a/Examples/Data/Presentation.pptx b/Examples/Data/Presentation.pptx new file mode 100644 index 00000000..8c2db6e9 Binary files /dev/null and b/Examples/Data/Presentation.pptx differ diff --git a/Examples/Data/Properties.docx b/Examples/Data/Properties.docx new file mode 100644 index 00000000..34564db8 Binary files /dev/null and b/Examples/Data/Properties.docx differ diff --git a/Examples/Data/Protected pdf document.pdf b/Examples/Data/Protected pdf document.pdf new file mode 100644 index 00000000..516236ad Binary files /dev/null and b/Examples/Data/Protected pdf document.pdf differ diff --git a/Examples/Data/Quotes.md b/Examples/Data/Quotes.md new file mode 100644 index 00000000..33b1048f --- /dev/null +++ b/Examples/Data/Quotes.md @@ -0,0 +1,18 @@ +![](QuotesExample.001.png) + +**Evaluation Only. Created with Aspose.Words. Copyright 2003-2020 Aspose Pty Ltd.** + +We support blockquotes in Markdown: +> *Lorem* +> +> *ipsum* + +The quotes can be of any level and can be nested: +> Quote level 3 +> +> Nested quote level 4 +> +> *Back to first level* +> +> Headings are allowed inside Quotes +**Created with an evaluation copy of Aspose.Words. To discover the full versions of our APIs please visit: https://products.aspose.com/words/** diff --git a/Examples/Data/Radio buttons.docx b/Examples/Data/Radio buttons.docx new file mode 100644 index 00000000..363a5c5f Binary files /dev/null and b/Examples/Data/Radio buttons.docx differ diff --git a/Examples/Data/Rendering.docx b/Examples/Data/Rendering.docx new file mode 100644 index 00000000..4f0190b8 Binary files /dev/null and b/Examples/Data/Rendering.docx differ diff --git a/Examples/Data/Replace regex.docx b/Examples/Data/Replace regex.docx new file mode 100644 index 00000000..2f1f9dee Binary files /dev/null and b/Examples/Data/Replace regex.docx differ diff --git a/Examples/Data/Replace text with fields.docx b/Examples/Data/Replace text with fields.docx new file mode 100644 index 00000000..94688d12 Binary files /dev/null and b/Examples/Data/Replace text with fields.docx differ diff --git a/Examples/Data/Report building.docx b/Examples/Data/Report building.docx new file mode 100644 index 00000000..19d115e5 Binary files /dev/null and b/Examples/Data/Report building.docx differ diff --git a/Examples/Data/Reporting engine template - Background color (Java).docx b/Examples/Data/Reporting engine template - Background color (Java).docx new file mode 100644 index 00000000..3f571a3c Binary files /dev/null and b/Examples/Data/Reporting engine template - Background color (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Bubble chart (Java).docx b/Examples/Data/Reporting engine template - Bubble chart (Java).docx new file mode 100644 index 00000000..bac626a2 Binary files /dev/null and b/Examples/Data/Reporting engine template - Bubble chart (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Bulleted list (Java).docx b/Examples/Data/Reporting engine template - Bulleted list (Java).docx new file mode 100644 index 00000000..6c4d6c95 Binary files /dev/null and b/Examples/Data/Reporting engine template - Bulleted list (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Chart (Java).docx b/Examples/Data/Reporting engine template - Chart (Java).docx new file mode 100644 index 00000000..4eb6e954 Binary files /dev/null and b/Examples/Data/Reporting engine template - Chart (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Chart series (Java).docx b/Examples/Data/Reporting engine template - Chart series (Java).docx new file mode 100644 index 00000000..d27055a2 Binary files /dev/null and b/Examples/Data/Reporting engine template - Chart series (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Chart series color (Java).docx b/Examples/Data/Reporting engine template - Chart series color (Java).docx new file mode 100644 index 00000000..bca83ad8 Binary files /dev/null and b/Examples/Data/Reporting engine template - Chart series color (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Chart with filtering (Java).docx b/Examples/Data/Reporting engine template - Chart with filtering (Java).docx new file mode 100644 index 00000000..2aee8f93 Binary files /dev/null and b/Examples/Data/Reporting engine template - Chart with filtering (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Common master detail (Java).docx b/Examples/Data/Reporting engine template - Common master detail (Java).docx new file mode 100644 index 00000000..41223eb3 Binary files /dev/null and b/Examples/Data/Reporting engine template - Common master detail (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Contextual object member access (Java).docx b/Examples/Data/Reporting engine template - Contextual object member access (Java).docx new file mode 100644 index 00000000..43fd9c95 Binary files /dev/null and b/Examples/Data/Reporting engine template - Contextual object member access (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Csv data destination (Java).docx b/Examples/Data/Reporting engine template - Csv data destination (Java).docx new file mode 100644 index 00000000..cc802f1a Binary files /dev/null and b/Examples/Data/Reporting engine template - Csv data destination (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Data destination with nested elements (Java).docx b/Examples/Data/Reporting engine template - Data destination with nested elements (Java).docx new file mode 100644 index 00000000..6dc309b3 Binary files /dev/null and b/Examples/Data/Reporting engine template - Data destination with nested elements (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Data table (Java).docx b/Examples/Data/Reporting engine template - Data table (Java).docx new file mode 100644 index 00000000..e0c4f82a Binary files /dev/null and b/Examples/Data/Reporting engine template - Data table (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Extension methods (Java).docx b/Examples/Data/Reporting engine template - Extension methods (Java).docx new file mode 100644 index 00000000..5f4d1846 Binary files /dev/null and b/Examples/Data/Reporting engine template - Extension methods (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Fields (Java).docx b/Examples/Data/Reporting engine template - Fields (Java).docx new file mode 100644 index 00000000..32c9a59b Binary files /dev/null and b/Examples/Data/Reporting engine template - Fields (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Header variable (Java).docx b/Examples/Data/Reporting engine template - Header variable (Java).docx new file mode 100644 index 00000000..c44dd5b1 Binary files /dev/null and b/Examples/Data/Reporting engine template - Header variable (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Html (Java).html b/Examples/Data/Reporting engine template - Html (Java).html new file mode 100644 index 00000000..58edd756 --- /dev/null +++ b/Examples/Data/Reporting engine template - Html (Java).html @@ -0,0 +1,8 @@ +

          Video provides a powerful way to help you prove your point.

          +
            +
          1. When you click Online Video,
          2. +
          3. you can paste in the embed code for
          4. +
          5. the video you want to add.
          6. +
          7. https://forum.aspose.com/t/list-of-tags-available-in-linq-reporting-engine/236715/2
          8. +
          +

          \"OIP.jfif\"

          \ No newline at end of file diff --git a/Examples/Data/Reporting engine template - If greedy (Java).docx b/Examples/Data/Reporting engine template - If greedy (Java).docx new file mode 100644 index 00000000..90e09306 Binary files /dev/null and b/Examples/Data/Reporting engine template - If greedy (Java).docx differ diff --git a/Examples/Data/Reporting engine template - If-else (Java).docx b/Examples/Data/Reporting engine template - If-else (Java).docx new file mode 100644 index 00000000..1209d566 Binary files /dev/null and b/Examples/Data/Reporting engine template - If-else (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Index of (Java).docx b/Examples/Data/Reporting engine template - Index of (Java).docx new file mode 100644 index 00000000..cddc92b9 Binary files /dev/null and b/Examples/Data/Reporting engine template - Index of (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Inserting hyperlinks (Java).docx b/Examples/Data/Reporting engine template - Inserting hyperlinks (Java).docx new file mode 100644 index 00000000..2798bbeb Binary files /dev/null and b/Examples/Data/Reporting engine template - Inserting hyperlinks (Java).docx differ diff --git a/Examples/Data/Reporting engine template - JSON data destination (Java).docx b/Examples/Data/Reporting engine template - JSON data destination (Java).docx new file mode 100644 index 00000000..7504feb4 Binary files /dev/null and b/Examples/Data/Reporting engine template - JSON data destination (Java).docx differ diff --git a/Examples/Data/Reporting engine template - List numbering (Java).docx b/Examples/Data/Reporting engine template - List numbering (Java).docx new file mode 100644 index 00000000..9932c377 Binary files /dev/null and b/Examples/Data/Reporting engine template - List numbering (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Merging table cells dynamically (Java).docx b/Examples/Data/Reporting engine template - Merging table cells dynamically (Java).docx new file mode 100644 index 00000000..647a5cb3 Binary files /dev/null and b/Examples/Data/Reporting engine template - Merging table cells dynamically (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Multicolored numbered list (Java).docx b/Examples/Data/Reporting engine template - Multicolored numbered list (Java).docx new file mode 100644 index 00000000..2b4ba928 Binary files /dev/null and b/Examples/Data/Reporting engine template - Multicolored numbered list (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Nested data table (Java).docx b/Examples/Data/Reporting engine template - Nested data table (Java).docx new file mode 100644 index 00000000..f80dc953 Binary files /dev/null and b/Examples/Data/Reporting engine template - Nested data table (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Numbered list (Java).docx b/Examples/Data/Reporting engine template - Numbered list (Java).docx new file mode 100644 index 00000000..9a1535ea Binary files /dev/null and b/Examples/Data/Reporting engine template - Numbered list (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Operators (Java).docx b/Examples/Data/Reporting engine template - Operators (Java).docx new file mode 100644 index 00000000..2281e2af Binary files /dev/null and b/Examples/Data/Reporting engine template - Operators (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Pie chart (Java).docx b/Examples/Data/Reporting engine template - Pie chart (Java).docx new file mode 100644 index 00000000..9536cd94 Binary files /dev/null and b/Examples/Data/Reporting engine template - Pie chart (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Point color (Java).docx b/Examples/Data/Reporting engine template - Point color (Java).docx new file mode 100644 index 00000000..02479903 Binary files /dev/null and b/Examples/Data/Reporting engine template - Point color (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Remove empty paragraphs (Java).docx b/Examples/Data/Reporting engine template - Remove empty paragraphs (Java).docx new file mode 100644 index 00000000..8416f88e Binary files /dev/null and b/Examples/Data/Reporting engine template - Remove empty paragraphs (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Scatter chart (Java).docx b/Examples/Data/Reporting engine template - Scatter chart (Java).docx new file mode 100644 index 00000000..8dc51881 Binary files /dev/null and b/Examples/Data/Reporting engine template - Scatter chart (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Selective remove paragraphs.docx b/Examples/Data/Reporting engine template - Selective remove paragraphs.docx new file mode 100644 index 00000000..9c931482 Binary files /dev/null and b/Examples/Data/Reporting engine template - Selective remove paragraphs.docx differ diff --git a/Examples/Data/Reporting engine template - Table row (Java).docx b/Examples/Data/Reporting engine template - Table row (Java).docx new file mode 100644 index 00000000..017979f3 Binary files /dev/null and b/Examples/Data/Reporting engine template - Table row (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Table row conditional blocks (Java).docx b/Examples/Data/Reporting engine template - Table row conditional blocks (Java).docx new file mode 100644 index 00000000..ffa1bb18 Binary files /dev/null and b/Examples/Data/Reporting engine template - Table row conditional blocks (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Table row greedy (Java).docx b/Examples/Data/Reporting engine template - Table row greedy (Java).docx new file mode 100644 index 00000000..b46fdcc3 Binary files /dev/null and b/Examples/Data/Reporting engine template - Table row greedy (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Table with filtering (Java).docx b/Examples/Data/Reporting engine template - Table with filtering (Java).docx new file mode 100644 index 00000000..59265129 Binary files /dev/null and b/Examples/Data/Reporting engine template - Table with filtering (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Text color (Java).docx b/Examples/Data/Reporting engine template - Text color (Java).docx new file mode 100644 index 00000000..dd90eb32 Binary files /dev/null and b/Examples/Data/Reporting engine template - Text color (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Total (Java).docx b/Examples/Data/Reporting engine template - Total (Java).docx new file mode 100644 index 00000000..eb324dc7 Binary files /dev/null and b/Examples/Data/Reporting engine template - Total (Java).docx differ diff --git a/Examples/Data/Reporting engine template - Word 2016 Charts (Java).docx b/Examples/Data/Reporting engine template - Word 2016 Charts (Java).docx new file mode 100644 index 00000000..bd90ac42 Binary files /dev/null and b/Examples/Data/Reporting engine template - Word 2016 Charts (Java).docx differ diff --git a/Examples/Data/Reporting engine template - XML data destination (Java).docx b/Examples/Data/Reporting engine template - XML data destination (Java).docx new file mode 100644 index 00000000..9cd3d9cb Binary files /dev/null and b/Examples/Data/Reporting engine template - XML data destination (Java).docx differ diff --git a/Examples/Data/Revision footnotes.docx b/Examples/Data/Revision footnotes.docx new file mode 100644 index 00000000..a5cee6e7 Binary files /dev/null and b/Examples/Data/Revision footnotes.docx differ diff --git a/Examples/Data/Revision runs.docx b/Examples/Data/Revision runs.docx new file mode 100644 index 00000000..f3264cb1 Binary files /dev/null and b/Examples/Data/Revision runs.docx differ diff --git a/Examples/Data/Revision shape.docx b/Examples/Data/Revision shape.docx new file mode 100644 index 00000000..98b3da11 Binary files /dev/null and b/Examples/Data/Revision shape.docx differ diff --git a/Examples/Data/Revisions at list levels.docx b/Examples/Data/Revisions at list levels.docx new file mode 100644 index 00000000..e57d3e3a Binary files /dev/null and b/Examples/Data/Revisions at list levels.docx differ diff --git a/Examples/Data/Revisions.docx b/Examples/Data/Revisions.docx new file mode 100644 index 00000000..dedd9536 Binary files /dev/null and b/Examples/Data/Revisions.docx differ diff --git a/Examples/Data/Rotated cell text.docx b/Examples/Data/Rotated cell text.docx new file mode 100644 index 00000000..05a074da Binary files /dev/null and b/Examples/Data/Rotated cell text.docx differ diff --git a/Examples/Data/Rounded rectangle shape.docx b/Examples/Data/Rounded rectangle shape.docx new file mode 100644 index 00000000..96e93dc8 Binary files /dev/null and b/Examples/Data/Rounded rectangle shape.docx differ diff --git a/Examples/Data/Section breaks with numbering.docx b/Examples/Data/Section breaks with numbering.docx new file mode 100644 index 00000000..b31eaf23 Binary files /dev/null and b/Examples/Data/Section breaks with numbering.docx differ diff --git a/Examples/Data/Shadow color.docx b/Examples/Data/Shadow color.docx new file mode 100644 index 00000000..c8f2f54b Binary files /dev/null and b/Examples/Data/Shadow color.docx differ diff --git a/Examples/Data/Shape high dpi.docx b/Examples/Data/Shape high dpi.docx new file mode 100644 index 00000000..6e2233dd Binary files /dev/null and b/Examples/Data/Shape high dpi.docx differ diff --git a/Examples/Data/Shape shadow effect.docx b/Examples/Data/Shape shadow effect.docx new file mode 100644 index 00000000..0e3a6a65 Binary files /dev/null and b/Examples/Data/Shape shadow effect.docx differ diff --git a/Examples/Data/Shape stroke pattern border.docx b/Examples/Data/Shape stroke pattern border.docx new file mode 100644 index 00000000..ce107373 Binary files /dev/null and b/Examples/Data/Shape stroke pattern border.docx differ diff --git a/Examples/Data/Shape with linked chart.docx b/Examples/Data/Shape with linked chart.docx new file mode 100644 index 00000000..16065e4f Binary files /dev/null and b/Examples/Data/Shape with linked chart.docx differ diff --git a/Examples/Data/Signature line.docx b/Examples/Data/Signature line.docx new file mode 100644 index 00000000..41c30c34 Binary files /dev/null and b/Examples/Data/Signature line.docx differ diff --git a/Examples/Data/Smart tags.doc b/Examples/Data/Smart tags.doc new file mode 100644 index 00000000..db5968a6 Binary files /dev/null and b/Examples/Data/Smart tags.doc differ diff --git a/Examples/Data/SmartArt.docx b/Examples/Data/SmartArt.docx new file mode 100644 index 00000000..4425ac59 Binary files /dev/null and b/Examples/Data/SmartArt.docx differ diff --git a/Examples/Data/Special symbol.docx b/Examples/Data/Special symbol.docx new file mode 100644 index 00000000..605a105f Binary files /dev/null and b/Examples/Data/Special symbol.docx differ diff --git a/Examples/Data/Spreadsheet.xlsx b/Examples/Data/Spreadsheet.xlsx new file mode 100644 index 00000000..01e764d4 Binary files /dev/null and b/Examples/Data/Spreadsheet.xlsx differ diff --git a/Examples/Data/Stroke gradient outline.docx b/Examples/Data/Stroke gradient outline.docx new file mode 100644 index 00000000..dacf0104 Binary files /dev/null and b/Examples/Data/Stroke gradient outline.docx differ diff --git a/Examples/Data/Structured document tag with HTML content.docx b/Examples/Data/Structured document tag with HTML content.docx new file mode 100644 index 00000000..e92fb561 Binary files /dev/null and b/Examples/Data/Structured document tag with HTML content.docx differ diff --git a/Examples/Data/Structured document tags by id.docx b/Examples/Data/Structured document tags by id.docx new file mode 100644 index 00000000..ac9046ae Binary files /dev/null and b/Examples/Data/Structured document tags by id.docx differ diff --git a/Examples/Data/Structured document tags with building blocks.docx b/Examples/Data/Structured document tags with building blocks.docx new file mode 100644 index 00000000..1fa8ea71 Binary files /dev/null and b/Examples/Data/Structured document tags with building blocks.docx differ diff --git a/Examples/Data/Structured document tags.docx b/Examples/Data/Structured document tags.docx new file mode 100644 index 00000000..0cf843de Binary files /dev/null and b/Examples/Data/Structured document tags.docx differ diff --git a/Examples/Data/Style with alias.docx b/Examples/Data/Style with alias.docx new file mode 100644 index 00000000..a257a6d8 Binary files /dev/null and b/Examples/Data/Style with alias.docx differ diff --git a/Examples/Data/Styles destination.docx b/Examples/Data/Styles destination.docx new file mode 100644 index 00000000..78bd1701 Binary files /dev/null and b/Examples/Data/Styles destination.docx differ diff --git a/Examples/Data/Styles source.docx b/Examples/Data/Styles source.docx new file mode 100644 index 00000000..167f04d0 Binary files /dev/null and b/Examples/Data/Styles source.docx differ diff --git a/Examples/Data/Styles.docx b/Examples/Data/Styles.docx new file mode 100644 index 00000000..08582b2a Binary files /dev/null and b/Examples/Data/Styles.docx differ diff --git a/Examples/Data/Subdocument.docx b/Examples/Data/Subdocument.docx new file mode 100644 index 00000000..bb4fc431 Binary files /dev/null and b/Examples/Data/Subdocument.docx differ diff --git a/Examples/Data/Table column bookmark.doc b/Examples/Data/Table column bookmark.doc new file mode 100644 index 00000000..e2ffc361 Binary files /dev/null and b/Examples/Data/Table column bookmark.doc differ diff --git a/Examples/Data/Table column bookmarks.doc b/Examples/Data/Table column bookmarks.doc new file mode 100644 index 00000000..a87e9cb4 Binary files /dev/null and b/Examples/Data/Table column bookmarks.doc differ diff --git a/Examples/Data/Table column bookmarks.docx b/Examples/Data/Table column bookmarks.docx new file mode 100644 index 00000000..6fe7a8bc Binary files /dev/null and b/Examples/Data/Table column bookmarks.docx differ diff --git a/Examples/Data/Table of content template.docx b/Examples/Data/Table of content template.docx new file mode 100644 index 00000000..6d8361e9 Binary files /dev/null and b/Examples/Data/Table of content template.docx differ diff --git a/Examples/Data/Table of contents.docx b/Examples/Data/Table of contents.docx new file mode 100644 index 00000000..d50447e9 Binary files /dev/null and b/Examples/Data/Table of contents.docx differ diff --git a/Examples/Data/Table spanning two pages.docx b/Examples/Data/Table spanning two pages.docx new file mode 100644 index 00000000..adcad728 Binary files /dev/null and b/Examples/Data/Table spanning two pages.docx differ diff --git a/Examples/Data/Table with fields.docx b/Examples/Data/Table with fields.docx new file mode 100644 index 00000000..1c42434a Binary files /dev/null and b/Examples/Data/Table with fields.docx differ diff --git a/Examples/Data/Table with merged cells.docx b/Examples/Data/Table with merged cells.docx new file mode 100644 index 00000000..e769afd5 Binary files /dev/null and b/Examples/Data/Table with merged cells.docx differ diff --git a/Examples/Data/Table wrapped by text.docx b/Examples/Data/Table wrapped by text.docx new file mode 100644 index 00000000..3f13f7d2 Binary files /dev/null and b/Examples/Data/Table wrapped by text.docx differ diff --git a/Examples/Data/Tables.docx b/Examples/Data/Tables.docx new file mode 100644 index 00000000..57b191a5 Binary files /dev/null and b/Examples/Data/Tables.docx differ diff --git a/Examples/Data/TestShapesUnsupportedBevel.docx b/Examples/Data/TestShapesUnsupportedBevel.docx new file mode 100644 index 00000000..6c47616a Binary files /dev/null and b/Examples/Data/TestShapesUnsupportedBevel.docx differ diff --git a/Examples/Data/TestWarningsForBevels.docx b/Examples/Data/TestWarningsForBevels.docx new file mode 100644 index 00000000..f6053a01 Binary files /dev/null and b/Examples/Data/TestWarningsForBevels.docx differ diff --git a/Examples/Data/TestWarningsForLighting.docx b/Examples/Data/TestWarningsForLighting.docx new file mode 100644 index 00000000..583ba468 Binary files /dev/null and b/Examples/Data/TestWarningsForLighting.docx differ diff --git a/Examples/Data/TestWarningsForMaterial.docx b/Examples/Data/TestWarningsForMaterial.docx new file mode 100644 index 00000000..b16905e7 Binary files /dev/null and b/Examples/Data/TestWarningsForMaterial.docx differ diff --git a/Examples/Data/Text positioning operators.docx b/Examples/Data/Text positioning operators.docx new file mode 100644 index 00000000..423b1e21 Binary files /dev/null and b/Examples/Data/Text positioning operators.docx differ diff --git a/Examples/Data/TextBoxes.docx b/Examples/Data/TextBoxes.docx new file mode 100644 index 00000000..666ef9d4 Binary files /dev/null and b/Examples/Data/TextBoxes.docx differ diff --git a/Examples/Data/Textbox control.docm b/Examples/Data/Textbox control.docm new file mode 100644 index 00000000..8dc30f97 Binary files /dev/null and b/Examples/Data/Textbox control.docm differ diff --git a/Examples/Data/Textboxes in drawing canvas.docx b/Examples/Data/Textboxes in drawing canvas.docx new file mode 100644 index 00000000..e6e991e6 Binary files /dev/null and b/Examples/Data/Textboxes in drawing canvas.docx differ diff --git a/Examples/Data/Theme colors.docx b/Examples/Data/Theme colors.docx new file mode 100644 index 00000000..d02732fd Binary files /dev/null and b/Examples/Data/Theme colors.docx differ diff --git a/Examples/Data/Two color gradient.docx b/Examples/Data/Two color gradient.docx new file mode 100644 index 00000000..4194e6d5 Binary files /dev/null and b/Examples/Data/Two color gradient.docx differ diff --git a/Examples/Data/UTF-8 characters.rtf b/Examples/Data/UTF-8 characters.rtf new file mode 100644 index 00000000..14641515 --- /dev/null +++ b/Examples/Data/UTF-8 characters.rtf @@ -0,0 +1,41 @@ +{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff1\deff1\stshfdbch0\stshfloch37\stshfhich37\stshfbi37\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;} +{\f37\fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\f48\froman\fcharset238\fprq2 Times New Roman CE;}{\f49\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f51\froman\fcharset161\fprq2 Times New Roman Greek;} +{\f52\froman\fcharset162\fprq2 Times New Roman Tur;}{\f53\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f54\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f55\froman\fcharset186\fprq2 Times New Roman Baltic;} +{\f56\froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f58\fswiss\fcharset238\fprq2 Arial CE;}{\f59\fswiss\fcharset204\fprq2 Arial Cyr;}{\f61\fswiss\fcharset161\fprq2 Arial Greek;}{\f62\fswiss\fcharset162\fprq2 Arial Tur;} +{\f63\fbidi \fswiss\fcharset177\fprq2 Arial (Hebrew);}{\f64\fbidi \fswiss\fcharset178\fprq2 Arial (Arabic);}{\f65\fswiss\fcharset186\fprq2 Arial Baltic;}{\f66\fswiss\fcharset163\fprq2 Arial (Vietnamese);}{\f418\fswiss\fcharset238\fprq2 Calibri CE;} +{\f419\fswiss\fcharset204\fprq2 Calibri Cyr;}{\f421\fswiss\fcharset161\fprq2 Calibri Greek;}{\f422\fswiss\fcharset162\fprq2 Calibri Tur;}{\f423\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\f424\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);} +{\f425\fswiss\fcharset186\fprq2 Calibri Baltic;}{\f426\fswiss\fcharset163\fprq2 Calibri (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0; +\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{ +\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch \af1\afs22\alang1025 \ltrch \f1\fs22\lang1031\langfe1033\cgrid\langnp1031\langfenp1033 \snext0 \styrsid14448319 Normal;}{\*\cs10 \additive \ssemihidden \styrsid14448319 +Default Paragraph Font;}{\*\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv +\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch \af37\afs20 \ltrch \f37\fs20\lang1024\langfe1024\cgrid\langnp1024\langfenp1024 \snext11 \ssemihidden Normal Table;}{\s15\ql \li0\ri0\widctlpar +\tqc\tx4320\tqr\tx8640\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch \af1\afs22\alang1025 \ltrch \f1\fs22\lang1031\langfe1033\cgrid\langnp1031\langfenp1033 \sbasedon0 \snext15 \styrsid12323684 header;}{\s16\ql \li0\ri0\widctlpar +\tqc\tx4320\tqr\tx8640\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch \af1\afs22\alang1025 \ltrch \f1\fs22\lang1031\langfe1033\cgrid\langnp1031\langfenp1033 \sbasedon0 \snext16 \styrsid12323684 footer;}} +{\*\latentstyles\lsdstimax156\lsdlockeddef0{\lsdlockedexcept Normal;heading 1;heading 2;heading 3;heading 4;heading 5;heading 6;heading 7;heading 8;heading 9;toc 1;toc 2;toc 3;toc 4;toc 5;toc 6;toc 7;toc 8;toc 9;caption;Title;Default Paragraph Font;Subtitle;Strong;Emphasis;Table Grid;}} +{\*\pgptbl {\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}}{\*\rsidtbl \rsid668722\rsid1010229\rsid1511220\rsid1922300\rsid3432523\rsid4354540\rsid5064206\rsid6886727\rsid7347400\rsid8206008 +\rsid8212565\rsid8545038\rsid9127334\rsid10443128\rsid10909089\rsid11541526\rsid12323684\rsid12660976\rsid12719381\rsid12797030\rsid13005796\rsid13331677\rsid14448319\rsid16083549}{\*\generator Microsoft Word 11.0.6568;}{\info{\author RPC}{\operator RPC} +{\creatim\yr2020\mo1\dy26\min29}{\revtim\yr2020\mo5\dy22\hr19\min47}{\version18}{\edmins12}{\nofpages1}{\nofwords9}{\nofchars57}{\*\company }{\nofcharsws65}{\vern24579}}\margl1417\margr1417\margt1417\margb1134\ltrsect +\deftab708\widowctrl\ftnbj\aenddoc\hyphhotz425\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\hyphcaps0\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1417\dgvorigin1417\dghshow1\dgvshow1 +\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct +\asianbrkrule\rsidroot14448319\newtblstyruls\nogrowautofit \fet0{\*\ftnsep \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch \af1\afs22\alang1025 \ltrch +\f1\fs22\lang1031\langfe1033\cgrid\langnp1031\langfenp1033 {\rtlch \af1 \ltrch \insrsid12323684 \chftnsep +\par }}{\*\ftnsepc \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch \af1\afs22\alang1025 \ltrch \f1\fs22\lang1031\langfe1033\cgrid\langnp1031\langfenp1033 {\rtlch \af1 \ltrch \insrsid12323684 +\chftnsepc +\par }}{\*\aftnsep \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch \af1\afs22\alang1025 \ltrch \f1\fs22\lang1031\langfe1033\cgrid\langnp1031\langfenp1033 {\rtlch \af1 \ltrch \insrsid12323684 +\chftnsep +\par }}{\*\aftnsepc \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch \af1\afs22\alang1025 \ltrch \f1\fs22\lang1031\langfe1033\cgrid\langnp1031\langfenp1033 {\rtlch \af1 \ltrch \insrsid12323684 +\chftnsepc +\par }}\ltrpar \sectd \ltrsect\linex0\endnhere\titlepg\sectdefaultcl\sftnbj {\headerf \ltrpar \pard\plain \ltrpar\qr \li0\ri0\sa240\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid7347400 \rtlch \af1\afs22\alang1025 \ltrch +\f1\fs22\lang1031\langfe1033\cgrid\langnp1031\langfenp1033 {\rtlch \af1 \ltrch \insrsid5064206 This document contains UTF-8 characters represented by the Windows-1252 charset}{\rtlch \af1 \ltrch \insrsid12323684 +\par }\pard \ltrpar\qr \li0\ri0\sa480\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid7347400 {\rtlch \af1 \ltrch \insrsid7347400 These characters will have to be detected as being in the UTF-8 encoding to be read properly +\par }}{\*\pnseclvl1\pnucrm\pnqc\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnqc\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnqc\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnqc\pnstart1\pnindent720\pnhang +{\pntxta )}}{\*\pnseclvl5\pndec\pnqc\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnqc\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnqc\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}} +{\*\pnseclvl8\pnlcltr\pnqc\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnqc\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\nowidctlpar\faauto\rin0\lin0\itap0\pararsid8212565 \rtlch +\af1\afs22\alang1025 \ltrch \f1\fs22\lang1031\langfe1033\cgrid\langnp1031\langfenp1033 {\rtlch \af37\afs18 \ltrch \f37\fs18\cf1\insrsid13331677\charrsid13331677 \'e2\'80\'9c}{\rtlch \af37\afs18 \ltrch \f37\fs18\cf1\insrsid8545038 John Doe}{\rtlch +\af37\afs18 \ltrch \f37\fs18\cf1\insrsid16083549\charrsid16083549 \'c2\'b4}{\rtlch \af37\afs18 \ltrch \f37\fs18\cf1\insrsid8545038 s list of }{\rtlch \af37\afs18 \ltrch \f37\fs18\cf1\insrsid13331677 currency symbols}{\rtlch \af37\afs18 \ltrch +\f37\fs18\cf1\insrsid10443128\charrsid10443128 \'e2\'80\u157\'9d}{\rtlch \af37\afs18 \ltrch \f37\fs18\cf1\insrsid11541526\charrsid11541526 \'e2\'84\'a2}{\rtlch \af37\afs18 \ltrch \f37\fs18\cf1\insrsid8545038\charrsid11541526 +\par }\pard \ltrpar\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid8545038 {\rtlch \af37\afs18 \ltrch \f37\fs18\cf1\insrsid8545038\charrsid4354540 \'e2\'82\'ac}{\rtlch \af37\afs18 \ltrch \f37\fs18\cf1\insrsid8545038 , }{ +\rtlch \af37\afs18 \ltrch \f37\fs18\cf1\insrsid8545038\charrsid4354540 \'c2\'a2}{\rtlch \af37\afs18 \ltrch \f37\fs18\cf1\insrsid8545038 , }{\rtlch \af37\afs18 \ltrch \f37\fs18\cf1\insrsid8545038\charrsid4354540 \'c2\'a3}{\rtlch \af37\afs18 \ltrch +\f37\fs18\cf1\insrsid8545038 , }{\rtlch \af37\afs18 \ltrch \f37\fs18\cf1\insrsid8545038\charrsid4354540 \'c2\'a5}{\rtlch \af37\afs18 \ltrch \f37\fs18\cf1\insrsid8545038 , }{\rtlch \af37\afs18 \ltrch \f37\fs18\cf1\insrsid8545038\charrsid4354540 \'c2\'a4}{ +\rtlch \af1 \ltrch \insrsid9127334\charrsid8545038 +\par }} \ No newline at end of file diff --git a/Examples/Data/Unoptimized document.docx b/Examples/Data/Unoptimized document.docx new file mode 100644 index 00000000..ed079ca3 Binary files /dev/null and b/Examples/Data/Unoptimized document.docx differ diff --git a/Examples/Data/Unused styles.docx b/Examples/Data/Unused styles.docx new file mode 100644 index 00000000..7ef5cd86 Binary files /dev/null and b/Examples/Data/Unused styles.docx differ diff --git a/Examples/Data/VBA project.docm b/Examples/Data/VBA project.docm new file mode 100644 index 00000000..e70765d0 Binary files /dev/null and b/Examples/Data/VBA project.docm differ diff --git a/Examples/Data/VML conditional.htm b/Examples/Data/VML conditional.htm new file mode 100644 index 00000000..64eb0469 --- /dev/null +++ b/Examples/Data/VML conditional.htm @@ -0,0 +1,16 @@ + + + + Aspose Test + + + +

          + + (null) +

          + + + diff --git a/Examples/Data/Various fields.docx b/Examples/Data/Various fields.docx new file mode 100644 index 00000000..20be329d Binary files /dev/null and b/Examples/Data/Various fields.docx differ diff --git a/Examples/Data/Various shapes.docx b/Examples/Data/Various shapes.docx new file mode 100644 index 00000000..27e400bd Binary files /dev/null and b/Examples/Data/Various shapes.docx differ diff --git a/Examples/Data/Vba protected.docm b/Examples/Data/Vba protected.docm new file mode 100644 index 00000000..89194849 Binary files /dev/null and b/Examples/Data/Vba protected.docm differ diff --git a/Examples/Data/Versions.doc b/Examples/Data/Versions.doc new file mode 100644 index 00000000..d031c064 Binary files /dev/null and b/Examples/Data/Versions.doc differ diff --git a/Examples/Data/WMF with image.docx b/Examples/Data/WMF with image.docx new file mode 100644 index 00000000..aa7fec7a Binary files /dev/null and b/Examples/Data/WMF with image.docx differ diff --git a/Examples/Data/WMF with text.docx b/Examples/Data/WMF with text.docx new file mode 100644 index 00000000..bc2b6abc Binary files /dev/null and b/Examples/Data/WMF with text.docx differ diff --git a/Examples/Data/Web extension.docx b/Examples/Data/Web extension.docx new file mode 100644 index 00000000..da21b954 Binary files /dev/null and b/Examples/Data/Web extension.docx differ diff --git a/Examples/Data/Word document with missing file extension b/Examples/Data/Word document with missing file extension new file mode 100644 index 00000000..872cbba4 Binary files /dev/null and b/Examples/Data/Word document with missing file extension differ diff --git a/Examples/Data/Xlsx DateTime.docx b/Examples/Data/Xlsx DateTime.docx new file mode 100644 index 00000000..42e4cc92 Binary files /dev/null and b/Examples/Data/Xlsx DateTime.docx differ diff --git a/Examples/Data/Xlsx Document.xlsx b/Examples/Data/Xlsx Document.xlsx new file mode 100644 index 00000000..79f8fd20 Binary files /dev/null and b/Examples/Data/Xlsx Document.xlsx differ diff --git a/Examples/Data/Zip file.zip b/Examples/Data/Zip file.zip new file mode 100644 index 00000000..f92df763 Binary files /dev/null and b/Examples/Data/Zip file.zip differ diff --git a/Examples/src/main/resources/RenderingAndPrinting/hyph_de_CH.dic b/Examples/Data/hyph_de_CH.dic old mode 100755 new mode 100644 similarity index 99% rename from Examples/src/main/resources/RenderingAndPrinting/hyph_de_CH.dic rename to Examples/Data/hyph_de_CH.dic index 97751f81..b374b40e --- a/Examples/src/main/resources/RenderingAndPrinting/hyph_de_CH.dic +++ b/Examples/Data/hyph_de_CH.dic @@ -1,5 +1,6 @@ ISO8859-1 .aa6l +.aa6l .6a1ba .ab3a4s .a1be diff --git a/Examples/src/main/resources/RenderingAndPrinting/hyph_en_US.dic b/Examples/Data/hyph_en_US.dic old mode 100755 new mode 100644 similarity index 100% rename from Examples/src/main/resources/RenderingAndPrinting/hyph_en_US.dic rename to Examples/Data/hyph_en_US.dic diff --git a/Examples/Data/morzal.pfx b/Examples/Data/morzal.pfx new file mode 100644 index 00000000..cce904de Binary files /dev/null and b/Examples/Data/morzal.pfx differ diff --git a/Examples/DocsExamples/Java/pom.xml b/Examples/DocsExamples/Java/pom.xml new file mode 100644 index 00000000..c0e365b4 --- /dev/null +++ b/Examples/DocsExamples/Java/pom.xml @@ -0,0 +1,133 @@ + + + 4.0.0 + + + UTF-8 + + + com.aspose.docsexamples + DocsExamples + 1.0-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M4 + + ${basedir}/src/main/java/ + ${project.build.directory}/classes/ + + **/*.java + **/**/*.java + **/**/**/*.java + **/**/**/**/*.java + + + + + + + + + AsposeJavaAPI + Aspose Java API + https://releases.aspose.com/java/repo/ + + + com.springsource.repository.bundles.external + SpringSource Enterprise Bundle Repository - External Bundle Releases + https://repository.springsource.com/maven/bundles/external + + + + + + com.aspose + aspose-words + 25.8 + jdk17 + + + com.aspose + aspose-words + 25.8 + shaping-harfbuzz-plugin + + + com.aspose + aspose-barcode + 25.6 + jdk18 + + + com.aspose + aspose-pdf + 25.6 + jdk17 + + + com.aspose + aspose-email + 25.6 + jdk16 + + + org.testng + testng + 7.5.1 + + + javax.media.jai + com.springsource.javax.media.jai.core + 1.1.3 + + + net.sf.ucanaccess + ucanaccess + 3.0.6 + + + commons-io + commons-io + 2.16.1 + + + org.apache.commons + commons-collections4 + 4.4 + + + org.apache.commons + commons-lang3 + 3.17.0 + + + org.apache.poi + poi + 5.0.0 + + + org.jsoup + jsoup + 1.18.1 + + + org.apache.xmlgraphics + batik-transcoder + 1.14 + + + \ No newline at end of file diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/AI_powered_Features/WorkingWithAI.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/AI_powered_Features/WorkingWithAI.java new file mode 100644 index 00000000..6181421b --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/AI_powered_Features/WorkingWithAI.java @@ -0,0 +1,68 @@ +package DocsExamples.AI_powered_Features; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +public class WorkingWithAI extends DocsExamplesBase +{ + @Test (enabled = false, description = "This test should be run manually to manage API requests amount") + public void aiSummarize() throws Exception + { + //ExStart:AiSummarize + //GistId:1e379bedb2b759c1be24c64aad54d13d + Document firstDoc = new Document(getMyDir() + "Big document.docx"); + Document secondDoc = new Document(getMyDir() + "Document.docx"); + + String apiKey = System.getenv("API_KEY"); + // Use OpenAI or Google generative language models. + AiModel model = ((OpenAiModel)AiModel.create(AiModelType.GPT_4_O_MINI).withApiKey(apiKey)).withOrganization("Organization").withProject("Project"); + + SummarizeOptions options = new SummarizeOptions(); + + options.setSummaryLength(SummaryLength.SHORT); + Document oneDocumentSummary = model.summarize(firstDoc, options); + oneDocumentSummary.save(getArtifactsDir() + "AI.AiSummarize.One.docx"); + + options.setSummaryLength(SummaryLength.LONG); + Document multiDocumentSummary = model.summarize(new Document[] { firstDoc, secondDoc }, options); + multiDocumentSummary.save(getArtifactsDir() + "AI.AiSummarize.Multi.docx"); + //ExEnd:AiSummarize + } + + @Test (enabled = false, description = "This test should be run manually to manage API requests amount") + public void aiTranslate() throws Exception + { + //ExStart:AiTranslate + //GistId:ea14b3e44c0233eecd663f783a21c4f6 + Document doc = new Document(getMyDir() + "Document.docx"); + + String apiKey = System.getenv("API_KEY"); + // Use Google generative language models. + AiModel model = (GoogleAiModel)AiModel.create(AiModelType.GEMINI_15_FLASH).withApiKey(apiKey); + + Document translatedDoc = model.translate(doc, Language.ARABIC); + translatedDoc.save(getArtifactsDir() + "AI.AiTranslate.docx"); + //ExEnd:AiTranslate + } + + @Test (enabled = false, description = "This test should be run manually to manage API requests amount") + public void aiGrammar() throws Exception + { + //ExStart:AiGrammar + //GistId:98a646d19cd7708ed0cd3d97b993a053 + Document doc = new Document(getMyDir() + "Big document.docx"); + + String apiKey = System.getenv("API_KEY"); + // Use OpenAI generative language models. + AiModel model = AiModel.create(AiModelType.GPT_4_O_MINI).withApiKey(apiKey); + + CheckGrammarOptions grammarOptions = new CheckGrammarOptions(); + grammarOptions.setImproveStylistics(true); + + Document proofedDoc = model.checkGrammar(doc, grammarOptions); + proofedDoc.save(getArtifactsDir() + "AI.AiGrammar.docx"); + //ExEnd:AiGrammar + } +} + diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/DocsExamplesBase.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/DocsExamplesBase.java new file mode 100644 index 00000000..edccf441 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/DocsExamplesBase.java @@ -0,0 +1,158 @@ +package DocsExamples; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2021 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.CurrentThreadSettings; +import com.aspose.words.License; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; + +import java.io.File; +import java.util.Locale; + +public class DocsExamplesBase { + /** + * Test artifacts directory. + */ + private final File artifactsDirPath = new File(getArtifactsDir()); + + /** + * Delete all dirs and files from directory. + * + * @param dir directory to be deleted + */ + private static void deleteDir(final File dir) { + String[] entries = dir.list(); + for (String s : entries) { + File currentFile = new File(dir.getPath(), s); + if (currentFile.isDirectory()) { + deleteDir(currentFile); + } else { + currentFile.delete(); + } + } + dir.delete(); + } + + /** + * Delete and create new empty directory for test artifacts. + * + * @throws Exception exception for setUnlimitedLicense() + */ + @BeforeClass(alwaysRun = true) + public void setUp() throws Exception { + CurrentThreadSettings.setLocale(Locale.US); + + if (artifactsDirPath.exists()) { + deleteDir(artifactsDirPath); + } + artifactsDirPath.mkdir(); + + setUnlimitedLicense(); + } + + /** + * Delete all dirs and files from directory for test artifacts. + */ + @AfterClass(alwaysRun = true) + public void tearDown() { + deleteDir(artifactsDirPath); + } + + /** + * Set java licence for using library without any restrictions. + * + * @throws Exception exception for setting licence + */ + private static void setUnlimitedLicense() throws Exception { + // This is where the test license is on my development machine. + String testLicenseFileName = getLicenseDir() + "Aspose.Total.Java.lic"; + if (new File(testLicenseFileName).exists()) { + // This shows how to use an Aspose.Words license when you have purchased one. + // You don't have to specify full path as shown here. You can specify just the + // file name if you copy the license file into the same folder as your application + // binaries or you add the license to your project as an embedded resource. + License wordsLicense = new License(); + wordsLicense.setLicense(testLicenseFileName); + } + } + + /** + * Gets the path to the codebase directory. + */ + static String getMainDataDir() { + return mMainDataDir; + } + + /** + * Gets the path to the documents used by the code examples. + */ + public static String getMyDir() { + return mMyDir; + } + + /** + * Gets the path to the images used by the code examples. + */ + public static String getImagesDir() { + return mImagesDir; + } + + /** + * Gets the path of the demo database. + */ + public static String getDatabaseDir() { + return mDatabaseDir; + } + + /** + * Gets the path to the license used by the code examples. + */ + static String getLicenseDir() { + return mLicenseDir; + } + + /** + * Gets the path to the artifacts used by the code examples. + */ + public static String getArtifactsDir() { + return mArtifactsDir; + } + + /** + * Gets the path of the free fonts. Ends with a back slash. + */ + public static String getFontsDir() { + return mFontsDir; + } + + private static final String mAssemblyDir; + private static final String mMainDataDir; + private static final String mMyDir; + private static final String mImagesDir; + private static final String mDatabaseDir; + private static final String mLicenseDir; + private static final String mArtifactsDir; + private static final String mFontsDir; + + static { + try { + mAssemblyDir = System.getProperty("user.dir"); + mMainDataDir = new File(mAssemblyDir).getParentFile().getParentFile() + File.separator; + mMyDir = mMainDataDir + "Data" + File.separator; + mArtifactsDir = mMyDir + "Artifacts" + File.separator; + mImagesDir = mMyDir + "Images" + File.separator; + mDatabaseDir = mMyDir + "Database" + File.separator; + mLicenseDir = mMyDir + "License" + File.separator; + mFontsDir = mMyDir + "MyFonts" + File.separator; + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/About.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/About.java similarity index 94% rename from Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/About.java rename to Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/About.java index 9c618eeb..0c930097 100644 --- a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/About.java +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/About.java @@ -5,7 +5,7 @@ * is only intended as a supplement to the documentation, and is provided * "as is", without warranty of any kind, either expressed or implied. */ -package com.aspose.words.examples.viewers_visualizers.document_explorer; +package DocsExamples.Document_explorer; import java.awt.*; import java.awt.event.ActionEvent; @@ -42,5 +42,6 @@ public void actionPerformed(ActionEvent e) { private void onOK() { aboutForm.dispose(); } + AboutForm aboutForm; } diff --git a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/AboutForm.form b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/AboutForm.form similarity index 100% rename from Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/AboutForm.form rename to Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/AboutForm.form diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/AboutForm.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/AboutForm.java new file mode 100644 index 00000000..abb81287 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/AboutForm.java @@ -0,0 +1,185 @@ +/* + * Copyright 2001-2014 Aspose Pty Ltd. All Rights Reserved. + * + * This file is part of Aspose.Words. The source code in this file + * is only intended as a supplement to the documentation, and is provided + * "as is", without warranty of any kind, either expressed or implied. + */ +package DocsExamples.Document_explorer; + +public class AboutForm extends javax.swing.JDialog { + + /** + * Creates new form AboutForm + */ + public AboutForm() { + + /* Set the Nimbus look and feel */ + // + /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. + * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html + */ + try { + for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { + if ("Nimbus".equals(info.getName())) { + javax.swing.UIManager.setLookAndFeel(info.getClassName()); + break; + } + } + } catch (ClassNotFoundException ex) { + java.util.logging.Logger.getLogger(MainForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + java.util.logging.Logger.getLogger(MainForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + java.util.logging.Logger.getLogger(MainForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (javax.swing.UnsupportedLookAndFeelException ex) { + java.util.logging.Logger.getLogger(MainForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } + // + + initComponents(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jSplitPane1 = new javax.swing.JSplitPane(); + jPanel1 = new javax.swing.JPanel(); + jLabel2 = new javax.swing.JLabel(); + jScrollPane1 = new javax.swing.JScrollPane(); + jTextPane1 = new javax.swing.JTextPane(); + jSplitPane2 = new javax.swing.JSplitPane(); + jScrollPane2 = new javax.swing.JScrollPane(); + jTextPane2 = new javax.swing.JTextPane(); + jScrollPane3 = new javax.swing.JScrollPane(); + jTextPane3 = new javax.swing.JTextPane(); + jPanel2 = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + closeButton = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setIconImages(null); + setModalExclusionType(null); + setName("AboutForm"); // NOI18N + setResizable(false); + + jSplitPane1.setDividerLocation(200); + + jPanel1.setBackground(new java.awt.Color(255, 255, 255)); + + jLabel2.setBackground(new java.awt.Color(255, 255, 255)); + jLabel2.setForeground(new java.awt.Color(255, 255, 255)); + jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLabel2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/viewersandvisualizers/documentexplorer/java/images/aspose.gif"))); // NOI18N + jLabel2.setIconTextGap(0); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 199, Short.MAX_VALUE) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 199, Short.MAX_VALUE) + ); + + jSplitPane1.setLeftComponent(jPanel1); + + jScrollPane1.setViewportView(jTextPane1); + + jSplitPane1.setRightComponent(jScrollPane1); + + jSplitPane2.setDividerLocation(70); + jSplitPane2.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); + jSplitPane2.setEnabled(false); + + jTextPane2.setEditable(false); + jTextPane2.setBorder(null); + jTextPane2.setFont(new java.awt.Font("Verdana", 1, 24)); // NOI18N + jTextPane2.setText("Document Explorer Demo for Aspose.Words "); + jScrollPane2.setViewportView(jTextPane2); + + jSplitPane2.setTopComponent(jScrollPane2); + + jTextPane3.setEditable(false); + jTextPane3.setBorder(null); + jTextPane3.setText("Use DocumentExplorer to:\n- Learn from source code how to use Aspose.Words in your project.\n- Visually explore document elements in the Aspose.Words Object Model.\nusing Aspose.Words.\n- Quickly convert between DOC, DOCX, ODF, EPUB, PDF, RTF, SWF, WordML, HTML, MHTML and plain text formats.\n"); + jScrollPane3.setViewportView(jTextPane3); + + jSplitPane2.setRightComponent(jScrollPane3); + + jSplitPane1.setRightComponent(jSplitPane2); + + jLabel1.setFont(new java.awt.Font("Verdana", 0, 14)); // NOI18N + jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLabel1.setText("Copyright � 2002-2011 Aspose Pty Ltd. All Rights Reserved. "); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(108, 108, 108) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 529, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(87, Short.MAX_VALUE)) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 34, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 11, Short.MAX_VALUE)) + ); + + closeButton.setText("OK"); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(closeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 59, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 201, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(closeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + + pack(); + }// //GEN-END:initComponents + + // Variables declaration - do not modify//GEN-BEGIN:variables + protected javax.swing.JButton closeButton; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JScrollPane jScrollPane2; + private javax.swing.JScrollPane jScrollPane3; + private javax.swing.JSplitPane jSplitPane1; + private javax.swing.JSplitPane jSplitPane2; + private javax.swing.JTextPane jTextPane1; + private javax.swing.JTextPane jTextPane2; + private javax.swing.JTextPane jTextPane3; + // End of variables declaration//GEN-END:variables +} diff --git a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/Dialogs.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/Dialogs.java similarity index 98% rename from Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/Dialogs.java rename to Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/Dialogs.java index 79e2f462..9196dafc 100644 --- a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/Dialogs.java +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/Dialogs.java @@ -5,7 +5,7 @@ * is only intended as a supplement to the documentation, and is provided * "as is", without warranty of any kind, either expressed or implied. */ -package com.aspose.words.examples.viewers_visualizers.document_explorer; +package DocsExamples.Document_explorer; import com.aspose.words.FileFormatUtil; import com.aspose.words.SaveFormat; diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/DocumentExplorer.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/DocumentExplorer.java new file mode 100644 index 00000000..430129dc --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/DocumentExplorer.java @@ -0,0 +1,15 @@ +/* + * Copyright 2001-2014 Aspose Pty Ltd. All Rights Reserved. + * + * This file is part of Aspose.Words. The source code in this file + * is only intended as a supplement to the documentation, and is provided + * "as is", without warranty of any kind, either expressed or implied. + */ +package DocsExamples.Document_explorer; + +public class DocumentExplorer { + + public static void main(String[] args) throws Exception { + new Main(); + } +} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/DocumentItems.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/DocumentItems.java similarity index 99% rename from Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/DocumentItems.java rename to Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/DocumentItems.java index 22dca1ca..ff812168 100644 --- a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/DocumentItems.java +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/DocumentItems.java @@ -5,7 +5,7 @@ * is only intended as a supplement to the documentation, and is provided * "as is", without warranty of any kind, either expressed or implied. */ -package com.aspose.words.examples.viewers_visualizers.document_explorer; +package DocsExamples.Document_explorer; import com.aspose.words.*; @@ -25,6 +25,7 @@ public DocumentItem(Node node) { public boolean isRemovable() { return false; } + public static final String NODE_TYPE_STRING = "DOCUMENT"; } @@ -37,6 +38,7 @@ public SectionItem(Node node) { public boolean isRemovable() { return this.getNode() != ((Document) this.getNode().getDocument()).getLastSection(); } + public static final String NODE_TYPE_STRING = "SECTION"; } @@ -57,6 +59,7 @@ protected String getIconName() throws Exception { public String getName() throws Exception { return MessageFormat.format("{0} - {1}", super.getName(), getHeaderFooterTypeAsString((HeaderFooter) this.getNode())); } + public static final String NODE_TYPE_STRING = "HEADER_FOOTER"; } @@ -69,6 +72,7 @@ public BodyItem(Node node) { public boolean isRemovable() { return false; } + public static final String NODE_TYPE_STRING = "BODY"; } @@ -77,6 +81,7 @@ public class TableItem extends Item { public TableItem(Node node) { super(node); } + public static final String NODE_TYPE_STRING = "TABLE"; } @@ -85,6 +90,7 @@ public class RowItem extends Item { public RowItem(Node node) { super(node); } + public static final String NODE_TYPE_STRING = "ROW"; } @@ -93,6 +99,7 @@ public class CellItem extends Item { public CellItem(Node node) { super(node); } + public static final String NODE_TYPE_STRING = "CELL"; } @@ -106,6 +113,7 @@ public boolean isRemovable() { Paragraph para = (Paragraph) this.getNode(); return !para.isEndOfSection(); } + public static final String NODE_TYPE_STRING = "PARAGRAPH"; } @@ -114,6 +122,7 @@ public class RunItem extends Item { public RunItem(Node node) { super(node); } + public static final String NODE_TYPE_STRING = "RUN"; } @@ -122,6 +131,7 @@ public class FieldStartItem extends Item { public FieldStartItem(Node node) { super(node); } + public static final String NODE_TYPE_STRING = "FIELD_START"; } @@ -130,6 +140,7 @@ public class FieldSeparatorItem extends Item { public FieldSeparatorItem(Node node) { super(node); } + public static final String NODE_TYPE_STRING = "FIELD_SEPARATOR"; } @@ -138,6 +149,7 @@ public class FieldEndItem extends Item { public FieldEndItem(Node node) { super(node); } + public static final String NODE_TYPE_STRING = "FIELD_END"; } @@ -150,6 +162,7 @@ public BookmarkStartItem(Node node) { public String getName() throws Exception { return MessageFormat.format("{0} - \"{1}\"", super.getName(), ((BookmarkStart) this.getNode()).getName()); } + public static final String NODE_TYPE_STRING = "BOOKMARK_START"; } @@ -162,6 +175,7 @@ public BookmarkEndItem(Node node) { public String getName() throws Exception { return MessageFormat.format("{0} - \"{1}\"", super.getName(), ((BookmarkEnd) this.getNode()).getName()); } + public static final String NODE_TYPE_STRING = "BOOKMARK_END"; } @@ -170,6 +184,7 @@ public class CustomXmlMarkupItem extends Item { public CustomXmlMarkupItem(Node node) { super(node); } + public static final String NODE_TYPE_STRING = "CUSTOM_XML_MARKUP"; } @@ -178,6 +193,7 @@ public class StructuredDocumentTagItem extends Item { public StructuredDocumentTagItem(Node node) { super(node); } + public static final String NODE_TYPE_STRING = "STRUCTURED_DOCUMENT_TAG"; } @@ -190,6 +206,7 @@ public String getName() throws Exception { public CommentItem(Node node) { super(node); } + public static final String NODE_TYPE_STRING = "COMMENT"; } @@ -202,6 +219,7 @@ public String getName() throws Exception { public CommentRangeStartItem(Node node) { super(node); } + public static final String NODE_TYPE_STRING = "COMMENT_RANGE_START"; } @@ -214,6 +232,7 @@ public String getName() throws Exception { public CommentRangeEndItem(Node node) { super(node); } + public static final String NODE_TYPE_STRING = "COMMENT_RANGE_END"; } @@ -222,6 +241,7 @@ public class DrawingMLItem extends Item { public DrawingMLItem(Node node) { super(node); } + public static final String NODE_TYPE_STRING = "DRAWING_ML"; } @@ -230,6 +250,7 @@ public class OfficeMathItem extends Item { public OfficeMathItem(Node node) { super(node); } + public static final String NODE_TYPE_STRING = "OFFICE_MATH"; } @@ -238,6 +259,7 @@ public class SmartTagItem extends Item { public SmartTagItem(Node node) { super(node); } + public static final String NODE_TYPE_STRING = "SMART_TAG"; } @@ -246,6 +268,7 @@ public class GroupShapeItem extends Item { public GroupShapeItem(Node node) { super(node); } + public static final String NODE_TYPE_STRING = "GROUP_SHAPE"; } @@ -254,6 +277,7 @@ public class FootnoteItem extends Item { public FootnoteItem(Node node) { super(node); } + public static final String NODE_TYPE_STRING = "FOOTNOTE"; } @@ -292,6 +316,7 @@ protected String getIconName() throws Exception { } } } + public static final String NODE_TYPE_STRING = "SHAPE"; } @@ -317,6 +342,7 @@ protected String getIconName() throws Exception { return super.getIconName(); } } + public static final String NODE_TYPE_STRING = "FORM_FIELD"; } @@ -325,6 +351,7 @@ public class SpecialCharItem extends Item { public SpecialCharItem(Node node) { super(node); } + public static final String NODE_TYPE_STRING = "SPECIAL_CHAR"; } } diff --git a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/ErrorDialog.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/ErrorDialog.java similarity index 96% rename from Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/ErrorDialog.java rename to Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/ErrorDialog.java index 6c452cac..b8c07ddd 100644 --- a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/ErrorDialog.java +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/ErrorDialog.java @@ -5,7 +5,7 @@ * is only intended as a supplement to the documentation, and is provided * "as is", without warranty of any kind, either expressed or implied. */ -package com.aspose.words.examples.viewers_visualizers.document_explorer; +package DocsExamples.Document_explorer; import java.awt.*; import java.awt.event.ActionEvent; @@ -56,5 +56,6 @@ public void windowClosing(WindowEvent e) { private void onOK() { errorDialog.dispose(); } + ErrorDialogForm errorDialog; } \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/ErrorDialogForm.form b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/ErrorDialogForm.form similarity index 100% rename from Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/ErrorDialogForm.form rename to Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/ErrorDialogForm.form diff --git a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/ErrorDialogForm.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/ErrorDialogForm.java similarity index 80% rename from Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/ErrorDialogForm.java rename to Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/ErrorDialogForm.java index a7d0f847..b34e0e14 100644 --- a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/ErrorDialogForm.java +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/ErrorDialogForm.java @@ -5,7 +5,7 @@ * is only intended as a supplement to the documentation, and is provided * "as is", without warranty of any kind, either expressed or implied. */ -package com.aspose.words.examples.viewers_visualizers.document_explorer; +package DocsExamples.Document_explorer; public class ErrorDialogForm extends javax.swing.JDialog { @@ -67,24 +67,24 @@ private void initComponents() { javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addGap(0, 467, Short.MAX_VALUE) - .addComponent(closeButton))) - .addContainerGap()) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane1) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(0, 467, Short.MAX_VALUE) + .addComponent(closeButton))) + .addContainerGap()) ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 159, Short.MAX_VALUE) - .addGap(11, 11, 11) - .addComponent(closeButton) - .addContainerGap()) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 159, Short.MAX_VALUE) + .addGap(11, 11, 11) + .addComponent(closeButton) + .addContainerGap()) ); pack(); @@ -124,6 +124,7 @@ public void run() { } }); } + // Variables declaration - do not modify//GEN-BEGIN:variables protected javax.swing.JButton closeButton; private javax.swing.JScrollPane jScrollPane1; diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/Globals.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/Globals.java new file mode 100644 index 00000000..4c7ad9e7 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/Globals.java @@ -0,0 +1,124 @@ +/* + * Copyright 2001-2014 Aspose Pty Ltd. All Rights Reserved. + * + * This file is part of Aspose.Words. The source code in this file + * is only intended as a supplement to the documentation, and is provided + * "as is", without warranty of any kind, either expressed or implied. + */ +package DocsExamples.Document_explorer; + +import com.aspose.words.Document; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; + +/** + * This class is used as a repository for objects, that should be available from any place of the project code. + */ +public class Globals { + /** + * This class is purely static, that's why we prevent instance creation by declaring the constructor as private. + */ + private Globals() { + } + + // Titles used within the application. + static final String APPLICATION_TITLE = "Document Explorer"; + static final String UNEXPECTED_EXCEPTION_DIALOG_TITLE = APPLICATION_TITLE + " - unexpected error occured"; + static final String OPEN_DOCUMENT_DIALOG_TITLE = "Open Document"; + static final String SAVE_DOCUMENT_DIALOG_TITLE = "Save Document As"; + + // Open File filters + static final OpenFileFilter OPEN_FILE_FILTER_ALL_SUPPORTED_FORMATS = new OpenFileFilter( + new String[]{".doc", ".dot", ".docx", ".dotx", ".docm", ".dotm", ".xml", ".wml", ".rtf", ".odt", ".ott", ".htm", ".html", ".xhtml", ".mht", ".mhtm", ".mhtml"}, "All Supported Formats (*.doc;*.dot;*.docx;*.dotx;*.docm;*.dotm;*.xml;*.wml;*.rtf;*.odt;*.ott;*.htm;*.html;*.xhtml;*.mht;*.mhtm;*.mhtml)"); + + static final OpenFileFilter OPEN_FILE_FILTER_DOC_FORMAT = new OpenFileFilter( + new String[]{".doc", ".doct"}, "Word 97-2003 Documents (*.doc;*.dot)"); + + static final OpenFileFilter OPEN_FILE_FILTER_DOCX_FORMAT = new OpenFileFilter( + new String[]{".docx", ".dotx", ".docm", ".dotm"}, "Word 2007 OOXML Documents (*.docx;*.dotx;*.docm;*.dotm)"); + + static final OpenFileFilter OPEN_FILE_FILTER_XML_FORMAT = new OpenFileFilter( + new String[]{".xml", ".wml"}, "XML Documents (*.xml;*.wml)"); + + static final OpenFileFilter OPEN_FILE_FILTER_RTF_FORMAT = new OpenFileFilter( + new String[]{".rtf"}, "Rich Text Format (*.rtf)"); + + static final OpenFileFilter OPEN_FILE_FILTER_ODT_FORMAT = new OpenFileFilter( + new String[]{".odt", ".ott"}, "OpenDocument Text (*.odt;*.ott)"); + + static final OpenFileFilter OPEN_FILE_FILTER_HTML_FORMAT = new OpenFileFilter( + new String[]{".htm", ".html", ".xhtml", ".mht", ".mhtm", ".mhtml"}, "Web Pages (*.htm;*.html;*.xhtml;*.mht;*.mhtm;*.mhtml)"); + + // Save File Filters + static final SaveFileFilter SAVE_FILE_FILTER_DOC = new SaveFileFilter( + ".doc", "Word 97-2003 Document (*.doc)"); + + static final SaveFileFilter SAVE_FILE_FILTER_DOCX = new SaveFileFilter( + ".docx", "Word 2007 OOXML Document (*.docx)"); + + static final SaveFileFilter SAVE_FILE_FILTER_DOCM = new SaveFileFilter( + ".docm", "Word 2007 OOXML Macro-Enabled Document (*.docm)"); + + static final SaveFileFilter SAVE_FILE_FILTER_PDF = new SaveFileFilter( + ".pdf", "PDF (*.pdf)"); + + static final SaveFileFilter SAVE_FILE_FILTER_XPS = new SaveFileFilter( + ".xps", "XPS Document (*.xps)"); + + static final SaveFileFilter SAVE_FILE_FILTER_PDT = new SaveFileFilter( + ".odt", "OpenDocument Text (*.odt)"); + + static final SaveFileFilter SAVE_FILE_FILTER_HTML = new SaveFileFilter( + ".html", "Web Page (*.html)"); + + static final SaveFileFilter SAVE_FILE_FILTER_MHT = new SaveFileFilter( + ".mht", "Single File Web Page (*.mht)"); + + static final SaveFileFilter SAVE_FILE_FILTER_RTF = new SaveFileFilter( + ".rtf", "Rich Text Format (*.rtf)"); + + static final SaveFileFilter SAVE_FILE_FILTER_XML = new SaveFileFilter( + ".xml", "Word 2003 WordprocessingML (*.xml)"); + + static final SaveFileFilter SAVE_FILE_FILTER_FOPC = new SaveFileFilter( + ".fopc", "FlatOPC XML Document (*.fopc)"); + + static final SaveFileFilter SAVE_FILE_FILTER_TXT = new SaveFileFilter( + ".txt", "Plain Text (*.txt)"); + + static final SaveFileFilter SAVE_FILE_FILTER_EPUB = new SaveFileFilter( + ".epub", "IDPF EPUB Document (*.epub)"); + + static final SaveFileFilter SAVE_FILE_FILTER_SWF = new SaveFileFilter( + ".swf", "Macromedia Flash File (*.swf)"); + + static final SaveFileFilter SAVE_FILE_FILTER_XAML = new SaveFileFilter( + ".xaml", "XAML Fixed Document (*.xaml)"); + + /** + * Reference for application's main form. + */ + static MainForm mMainForm; + + /** + * Reference for currently loaded Document. + */ + static Document mDocument; + + /** + * Reference for current Tree Model + */ + static DefaultTreeModel mTreeModel; + + /** + * Reference for the current Tree + */ + static JTree mTree; + + /** + * Reference for the current root node. + */ + static DefaultMutableTreeNode mRootNode; +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/Item.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/Item.java new file mode 100644 index 00000000..827a4cd3 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/Item.java @@ -0,0 +1,271 @@ +/* + * Copyright 2001-2014 Aspose Pty Ltd. All Rights Reserved. + * + * This file is part of Aspose.Words. The source code in this file + * is only intended as a supplement to the documentation, and is provided + * "as is", without warranty of any kind, either expressed or implied. + */ +package DocsExamples.Document_explorer; + +import com.aspose.words.*; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +/** + * Base class used to provide GUI representation for document nodes. + */ +public class Item { + private Node mNode; + private DefaultMutableTreeNode mTreeNode; + private ImageIcon mIcon; + + private static ArrayList mControlCharFields; + private static Map mNodeTypes; + private static Map mHeaderFooterTypes; + private static Map mItemSet; + private static ArrayList mIconNames = new ArrayList(); + + /** + * Creates Item for the supplied document node. + */ + public Item(Node node) { + mNode = node; + } + + /** + * Returns the node in the document that this Item represents. + */ + public Node getNode() { + return mNode; + } + + /** + * The display name for this Item. Can be customized by overriding this method in inheriting classes. + */ + public String getName() throws Exception { + return getNodeTypeString(mNode); + } + + /** + * The text of the corresponding document node. + */ + public String getText() throws Exception { + String text = mNode.getText(); + + // Most control characters are converted to human readable form. + // E.g. [!PageBreak!], [!Cell!], etc. + for (Field fieldInfo : mControlCharFields) { + if (fieldInfo.getType() == char.class && Modifier.isStatic(fieldInfo.getModifiers())) { + Character ch = fieldInfo.getChar(null); + + // Represent a paragraph break using the special formatting marker. This makes the text easier to read. + if (fieldInfo.getName().equals("PARAGRAPH_BREAK_CHAR")) + text = text.replace(ch.toString(), "?" + "\n"); // JTextArea lines are separated using simple "\n" character and not using system independent new line character. + else + text = text.replace(ch.toString(), java.text.MessageFormat.format("[!{0}!]", fieldInfo.getName().replace("_CHAR", ""))); + } + } + + // All break chars should be supplemented with line feeds + text = text.replace("BREAK!]", "BREAK!]\n"); + return text; + } + + /** + * Creates a TreeNode for this item to be displayed in the Document Explorer TreeView control. + */ + public DefaultMutableTreeNode getTreeNode() throws Exception { + if (mTreeNode == null) { + mTreeNode = new DefaultMutableTreeNode(this); + if (!mIconNames.contains(getIconName())) { + mIconNames.add(getIconName()); + } + + if (mNode instanceof CompositeNode && ((CompositeNode) mNode).getChildNodes(NodeType.ANY, false).getCount() > 0) { + mTreeNode.add(new DefaultMutableTreeNode("#dummy")); + } + } + return mTreeNode; + } + + /** + * Returns the icon to display in the Document Explorer TreeView control. + */ + public ImageIcon getIcon() throws Exception { + if (mIcon == null) { + mIcon = loadIcon(getIconName()); + if (mIcon == null) + mIcon = loadIcon("Node"); + } + return mIcon; + } + + /** + * The icon for this node can be customized by overriding this property in the inheriting classes. + * The name represents name of .ico file without extension located in the Icons folder of the project. + */ + protected String getIconName() throws Exception { + return getClass().getSimpleName().replace("Item", ""); + } + + /** + * Provides lazy on-expand loading of underlying tree nodes. + */ + public void onExpand() throws Exception { + if ("#dummy".equals(getTreeNode().getFirstChild().toString())) { + getTreeNode().removeAllChildren(); + Globals.mTreeModel.reload(getTreeNode()); + for (Object o : ((CompositeNode) mNode).getChildNodes(NodeType.ANY, false)) { + Node n = (Node) o; + getTreeNode().add(Item.createItem(n).getTreeNode()); + } + } + } + + /** + * Loads and returns an icon from the assembly resource stream. + */ + private ImageIcon loadIcon(String iconName) { + java.net.URL imgURL = MainForm.class.getResource("images/" + iconName + ".gif"); + if (imgURL != null) + return new ImageIcon(imgURL); + else + return null; + } + + /** + * Removes this node from the document and the tree. + */ + public void remove() throws Exception { + if (this.isRemovable()) { + mNode.remove(); + TreeNode parent = mTreeNode.getParent(); + mTreeNode.removeFromParent(); + Globals.mTreeModel.reload(parent); + TreePath path = new TreePath(Globals.mRootNode); + Globals.mTree.setSelectionPath(path); + } + } + + /** + * Returns if this node can be removed from the document. Some nodes such as the last paragraph in the + * document cannot be removed. + */ + public boolean isRemovable() { + return true; + } + + /** + * Static ctor. + */ + static { + // Populate a list of node types along with their class implementation. + mItemSet = new HashMap(); + for (Class itemClass : DocumentItems.class.getDeclaredClasses()) { + try { + String nodeTypeString = (String) itemClass.getField("NODE_TYPE_STRING").get(null); + mItemSet.put(nodeTypeString, itemClass.getName()); + } catch (Exception e) { + // IllegalAccessException, NoSuchFieldException or NoSuchMethodException - skip such exceptions if there are any. + } + } + + // Fill a list containing the information of each control char. + mControlCharFields = new ArrayList(); + Field[] fields = ControlChar.class.getFields(); + for (Field fieldInfo : fields) { + if (fieldInfo.getType() == char.class && Modifier.isStatic(fieldInfo.getModifiers())) { + if (!fieldInfo.getName().equals("SPACE_CHAR")) + mControlCharFields.add(fieldInfo); + } + } + + // Map node type integer values to their equivalent string name. + mNodeTypes = new HashMap(); + Field[] nodeTypefields = NodeType.class.getFields(); + + for (Field fieldInfo : nodeTypefields) { + if (fieldInfo.getType() == int.class && Modifier.isStatic(fieldInfo.getModifiers())) { + try { + int integerValue = fieldInfo.getInt(null); + mNodeTypes.put(integerValue, fieldInfo.getName()); + } catch (IllegalAccessException e) { + // Skip any invalid fields. + } + } + } + + // Maps header/footer type integer values to string names. + mHeaderFooterTypes = new HashMap(); + fields = HeaderFooterType.class.getFields(); + + for (Field fieldInfo : fields) { + if (fieldInfo.getType() == int.class && Modifier.isStatic(fieldInfo.getModifiers())) { + try { + int integerValue = fieldInfo.getInt(null); + mHeaderFooterTypes.put(integerValue, fieldInfo.getName()); + } catch (IllegalAccessException e) { + // Skip any invalid fields. + } + } + } + } + + /** + * Item class factory implementation. + */ + public static Item createItem(Node node) throws ClassNotFoundException, NoSuchMethodException, + IllegalAccessException, InvocationTargetException, + InstantiationException { + String typeName = getNodeTypeString(node); + if (mItemSet.containsKey(typeName)) + return (Item) Class.forName(mItemSet.get(typeName)). + getConstructor(DocumentItems.class, Node.class). + newInstance(null, node); + else + return new Item(node); + } + + /** + * Object.toString method used by Tree. + */ + public String toString() { + // Introduced non-checked RuntimeException on purpose to not change Object.toString() signature + try { + return getName(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Convert numerical representation of the node type to string. + */ + private static String getNodeTypeString(Node node) { + int nodeType = node.getNodeType(); + if (mNodeTypes.containsKey(nodeType)) + return mNodeTypes.get(nodeType); + else + return ""; + } + + /** + * Convert numerical representation of HeaderFooter integer type to string. + */ + protected static String getHeaderFooterTypeAsString(HeaderFooter headerFooter) throws Exception { + int headerFooterType = headerFooter.getHeaderFooterType(); + if (mHeaderFooterTypes.containsKey(headerFooterType)) + return mHeaderFooterTypes.get(headerFooterType); + else + return ""; + } +} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/Main.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/Main.java similarity index 97% rename from Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/Main.java rename to Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/Main.java index c849aa45..7bd79862 100644 --- a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/Main.java +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/Main.java @@ -5,7 +5,7 @@ * is only intended as a supplement to the documentation, and is provided * "as is", without warranty of any kind, either expressed or implied. */ -package com.aspose.words.examples.viewers_visualizers.document_explorer; +package DocsExamples.Document_explorer; import com.aspose.words.Document; import com.aspose.words.License; @@ -23,18 +23,17 @@ /** * The main form of the DocumentExplorer demo. - * -* DocumentExplorer allows to open DOC, DOT, DOCX, XML, WML, RTF, ODT, OTT, + *

          + * DocumentExplorer allows to open DOC, DOT, DOCX, XML, WML, RTF, ODT, OTT, * HTML, XHTML and MHTML files using Aspose.Words. - * -* Once a document is opened, you can explore its object model in the tree. You + *

          + * Once a document is opened, you can explore its object model in the tree. You * can also save the document into DOC, DOCX, ODF, EPUB, PDF, SWF, RTF, WordML, * HTML, MHTML and plain text formats. - * */ public class Main implements TreeWillExpandListener, TreeSelectionListener, KeyListener { - String imgPath = com.aspose.words.examples.Utils.getDataDir(DocumentExplorer.class) + "images" + File.separator; + String imgPath = Utils.getDataDir() + "Document explorer images" + File.separator; public Main() throws Exception { @@ -251,7 +250,7 @@ private void expandAll(JTree tree, TreePath parent, boolean expand) { } if (node.getChildCount() >= 0) { - for (Enumeration e = node.children(); e.hasMoreElements();) { + for (Enumeration e = node.children(); e.hasMoreElements(); ) { TreeNode n = (TreeNode) e.nextElement(); TreePath path = parent.pathByAddingChild(n); expandAll(tree, path, expand); diff --git a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/MainForm.form b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/MainForm.form similarity index 100% rename from Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/MainForm.form rename to Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/MainForm.form diff --git a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/MainForm.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/MainForm.java similarity index 75% rename from Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/MainForm.java rename to Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/MainForm.java index dea919e9..6e294cf5 100644 --- a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/MainForm.java +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/MainForm.java @@ -5,10 +5,7 @@ * is only intended as a supplement to the documentation, and is provided * "as is", without warranty of any kind, either expressed or implied. */ -package com.aspose.words.examples.viewers_visualizers.document_explorer; - -import com.aspose.words.examples.*; -import com.aspose.words.examples.Utils; +package DocsExamples.Document_explorer; import java.io.File; @@ -115,7 +112,7 @@ private void initComponents() { jToolBar1.setRollover(true); - String imgPath = Utils.getDataDir(DocumentExplorer.class) + "images" + File.separator; + String imgPath = Utils.getDataDir() + "Document explorer images" + File.separator; System.out.println("image path: " + imgPath); toolOpenDocument.setIcon(new javax.swing.ImageIcon(imgPath + "tlb_1.gif")); // NOI18N @@ -209,42 +206,43 @@ private void initComponents() { javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(316, 316, 316) - .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(15, 15, 15) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(treeScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 209, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(jScrollPane1)) - .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGap(0, 0, 0))) - .addContainerGap()) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(316, 316, 316) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(15, 15, 15) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(treeScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 209, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(jScrollPane1)) + .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(0, 0, 0))) + .addContainerGap()) ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 34, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(17, 17, 17) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(treeScrollPane) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 135, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, 0)) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 34, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(17, 17, 17) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(treeScrollPane) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 135, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0)) ); pack(); }// //GEN-END:initComponents + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JMenu jMenu1; private javax.swing.JMenu jMenu2; diff --git a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/OpenFileFilter.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/OpenFileFilter.java similarity index 94% rename from Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/OpenFileFilter.java rename to Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/OpenFileFilter.java index 1409630e..b916eb01 100644 --- a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/OpenFileFilter.java +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/OpenFileFilter.java @@ -5,7 +5,7 @@ * is only intended as a supplement to the documentation, and is provided * "as is", without warranty of any kind, either expressed or implied. */ -package com.aspose.words.examples.viewers_visualizers.document_explorer; +package DocsExamples.Document_explorer; import javax.swing.filechooser.FileFilter; import java.io.File; @@ -43,6 +43,7 @@ public boolean accept(File f) { public String getDescription() { return mDescription; } + String[] mExtensions; String mDescription; } diff --git a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/SaveDialogChangeListener.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/SaveDialogChangeListener.java similarity index 97% rename from Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/SaveDialogChangeListener.java rename to Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/SaveDialogChangeListener.java index a112d032..2cb4db9f 100644 --- a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/SaveDialogChangeListener.java +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/SaveDialogChangeListener.java @@ -5,7 +5,7 @@ * is only intended as a supplement to the documentation, and is provided * "as is", without warranty of any kind, either expressed or implied. */ -package com.aspose.words.examples.viewers_visualizers.document_explorer; +package DocsExamples.Document_explorer; import javax.swing.*; import java.beans.PropertyChangeEvent; @@ -75,6 +75,7 @@ private void directoryChanged(PropertyChangeEvent e) { mChooser.updateUI(); } } + private static JFileChooser mChooser; private static File mNewFile; private static File mOldFile; diff --git a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/SaveFileFilter.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/SaveFileFilter.java similarity index 94% rename from Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/SaveFileFilter.java rename to Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/SaveFileFilter.java index c55ed368..45a02c24 100644 --- a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/SaveFileFilter.java +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/SaveFileFilter.java @@ -5,7 +5,7 @@ * is only intended as a supplement to the documentation, and is provided * "as is", without warranty of any kind, either expressed or implied. */ -package com.aspose.words.examples.viewers_visualizers.document_explorer; +package DocsExamples.Document_explorer; import javax.swing.filechooser.FileFilter; import java.io.File; @@ -41,6 +41,7 @@ public boolean accept(File f) { public String getDescription() { return mDescription; } + String mExtension; String mDescription; } diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/Utils.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/Utils.java new file mode 100644 index 00000000..58ef612e --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Document_explorer/Utils.java @@ -0,0 +1,83 @@ +/* + * Copyright 2001-2014 Aspose Pty Ltd. All Rights Reserved. + * + * This file is part of Aspose.Words. The source code in this file + * is only intended as a supplement to the documentation, and is provided + * "as is", without warranty of any kind, either expressed or implied. + */ +package DocsExamples.Document_explorer; + +import javax.swing.*; +import java.io.File; + +public class Utils { + + private Utils() { + } + + /* + * Gets the file extension of the passed file. + */ + public static String getExtension(String s) { + String ext = ""; + int i = s.lastIndexOf('.'); + + if (i > 0 && i < s.length() - 1) { + ext = s.substring(i + 1).toLowerCase(); + } + + return ext; + } + + /* + * Changes the extension of a file. + * + * Note: The extension should include a dot. + */ + public static File setExtension(File f, String ext) { + String name = f.getName(); + String newName; + + assert !"".equals(name) : "Empty file name."; + + // Don't change if the new extension is the same as the original. + if (name.endsWith(ext)) { + return f; + } + + int lastIndexOfDot = name.lastIndexOf('.'); + + if (lastIndexOfDot < 0) // File name without any extension. + { + newName = name + ext; + } else // Change the existing extension. + { + newName = name.substring(0, lastIndexOfDot) + ext; + } + + return new File(f.getParent(), newName); + } + + /** + * Returns an ImageIcon, or null if the path was invalid. + */ + public static ImageIcon createImageIcon(String path) { + java.net.URL imgURL = MainForm.class.getResource(path); + if (imgURL != null) { + return new ImageIcon(imgURL); + } else { + return null; + } + } + + public static String getDataDir() { + String userDir = System.getProperty("user.dir"); + String topDir = new File(userDir).getParentFile().getParentFile() + .getParentFile().getParentFile() + .getParentFile().getParentFile() + .getParentFile() + File.separator; + String dataDir = topDir + "Data" + File.separator; + + return dataDir; + } +} \ No newline at end of file diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/BaseConversions.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/BaseConversions.java new file mode 100644 index 00000000..009e4276 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/BaseConversions.java @@ -0,0 +1,246 @@ +package DocsExamples.File_formats_and_conversions; + +import DocsExamples.DocsExamplesBase; +import com.aspose.email.*; +import com.aspose.words.*; +import org.apache.commons.io.FileUtils; +import org.testng.annotations.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; + +@Test +public class BaseConversions extends DocsExamplesBase { + @Test + public void docToDocx() throws Exception { + //ExStart:LoadAndSave + //GistId:9d2a393f6dff9d785e7747a48e590d9d + Document doc = new Document(getMyDir() + "Document.doc"); + + doc.save(getArtifactsDir() + "BaseConversions.DocToDocx.docx"); + //ExEnd:LoadAndSave + } + + @Test + public void docxToRtf() throws Exception { + //ExStart:LoadAndSaveToStream + //GistId:9d2a393f6dff9d785e7747a48e590d9d + //ExStart:OpenFromStream + //GistId:ae20848f6cefd3f85ab9bcbbdda340c7 + // Read only access is enough for Aspose.Words to load a document. + FileInputStream stream = new FileInputStream(getMyDir() + "Document.docx"); + + Document doc = new Document(stream); + // You can close the stream now, it is no longer needed because the document is in memory. + stream.close(); + //ExEnd:OpenFromStream + + // ... do something with the document. + + // Convert the document to a different format and save to stream. + ByteArrayOutputStream dstStream = new ByteArrayOutputStream(); + doc.save(dstStream, SaveFormat.RTF); + //ExEnd:LoadAndSaveToStream + + FileUtils.writeByteArrayToFile(new File(getArtifactsDir() + "BaseConversions.DocxToRtf.rtf"), dstStream.toByteArray()); + } + + @Test + public void docxToPdf() throws Exception { + //ExStart:DocxToPdf + //GistId:b237846932dfcde42358bd0c887661a5 + Document doc = new Document(getMyDir() + "Document.docx"); + doc.save(getArtifactsDir() + "BaseConversions.DocxToPdf.pdf"); + //ExEnd:DocxToPdf + } + + @Test + public void docxToByte() throws Exception { + //ExStart:DocxToByte + //GistId:86d59d944009f305e7e24b3e276cd17d + Document doc = new Document(getMyDir() + "Document.docx"); + + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + doc.save(outStream, SaveFormat.DOCX); + + ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray()); + + Document docFromBytes = new Document(inStream); + //ExEnd:DocxToByte + } + + @Test + public void docxToEpub() throws Exception { + //ExStart:DocxToEpub + Document doc = new Document(getMyDir() + "Document.docx"); + + doc.save(getArtifactsDir() + "BaseConversions.DocxToEpub.epub"); + //ExEnd:DocxToEpub + } + + @Test + public void docxToHtml() throws Exception { + //ExStart:DocxToHtml + //GistId:c2ec8aa36ef37670eceec8da5c612b86 + Document doc = new Document(getMyDir() + "Document.docx"); + + doc.save(getArtifactsDir() + "BaseConversions.DocxToHtml.html"); + //ExEnd:DocxToHtml + } + + @Test(enabled = false, description = "Only for example") + public void docxToMhtml() throws Exception { + //ExStart:DocxToMhtml + //GistId:1bcfd5d0ec402f0f54cd747eb22d8da5 + Document doc = new Document(getMyDir() + "Document.docx"); + + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + doc.save(outStream, SaveFormat.MHTML); + + ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray()); + + // Create an Aspose.Network MIME email message from the stream. + MailMessage message = MailMessage.load(inStream, new MhtmlLoadOptions()); + message.setFrom(MailAddress.to_MailAddress("your_from@email.com")); + message.setTo(MailAddressCollection.to_MailAddressCollection(MailAddress.to_MailAddress("your_to@email.com"))); + message.setSubject("Aspose.Words + Aspose.Email MHTML Test Message"); + + // Send the message using Aspose.Email. + SmtpClient client = new SmtpClient(); + client.setHost("your_smtp.com"); + client.send(message); + //ExEnd:DocxToMhtml + } + + @Test + public void docxToMarkdown() throws Exception { + //ExStart:DocxToMarkdown + //GistId:642767bbe8d8bec8eab080120b707990 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Some text!"); + + doc.save(getArtifactsDir() + "BaseConversions.DocxToMarkdown.md"); + //ExEnd:DocxToMarkdown + } + + @Test + public void docxToTxt() throws Exception { + //ExStart:DocxToTxt + //GistId:1975a35426bcd195a2e7c61d20a1580c + Document doc = new Document(getMyDir() + "Document.docx"); + doc.save(getArtifactsDir() + "BaseConversions.DocxToTxt.txt"); + //ExEnd:DocxToTxt + } + + @Test + public void docxToXlsx() throws Exception { + //ExStart:DocxToXlsx + //GistId:82fb3ee435d5abdc1472a58774ebe98c + Document doc = new Document(getMyDir() + "Document.docx"); + doc.save(getArtifactsDir() + "BaseConversions.DocxToXlsx.xlsx"); + //ExEnd:DocxToXlsx + } + + @Test + public void txtToDocx() throws Exception { + //ExStart:TxtToDocx + // The encoding of the text file is automatically detected. + Document doc = new Document(getMyDir() + "English text.txt"); + doc.save(getArtifactsDir() + "BaseConversions.TxtToDocx.docx"); + //ExEnd:TxtToDocx + } + + @Test + public void DocxToJpeg() throws Exception { + //ExStart:DocxToJpeg + //GistId:b237846932dfcde42358bd0c887661a5 + Document doc = new Document(getMyDir() + "Document.docx"); + doc.save(getArtifactsDir() + "BaseConversions.DocxToJpeg.jpeg"); + //ExEnd:DocxToJpeg + } + + @Test + public void findReplaceXlsx() throws Exception { + //ExStart:FindReplaceXlsx + //GistId:50971daf8f0c9ef4b0250c4a526b1652 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Ruby bought a ruby necklace."); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Set the "MatchCase" flag to "true" to apply case sensitivity while finding strings to replace. + // Set the "MatchCase" flag to "false" to ignore character case while searching for text to replace. + options.setMatchCase(true); + + doc.getRange().replace("Ruby", "Jade", options); + + doc.save(getArtifactsDir() + "BaseConversions.FindReplaceXlsx.xlsx"); + //ExEnd:FindReplaceXlsx + } + + @Test + public void compressXlsx() throws Exception { + //ExStart:CompressXlsx + //GistId:50971daf8f0c9ef4b0250c4a526b1652 + Document doc = new Document(getMyDir() + "Document.docx"); + + XlsxSaveOptions saveOptions = new XlsxSaveOptions(); + saveOptions.setCompressionLevel(CompressionLevel.MAXIMUM); + + doc.save(getArtifactsDir() + "BaseConversions.CompressXlsx.xlsx", saveOptions); + //ExEnd:CompressXlsx + } + + @Test + public void imagesToPdf() throws Exception { + //ExStart:ImageToPdf + //GistId:b237846932dfcde42358bd0c887661a5 + convertImageToPdf(getImagesDir() + "Logo.jpg", getArtifactsDir() + "BaseConversions.JpgToPdf.pdf"); + convertImageToPdf(getImagesDir() + "Transparent background logo.png", getArtifactsDir() + "BaseConversions.PngToPdf.pdf"); + convertImageToPdf(getImagesDir() + "Windows MetaFile.wmf", getArtifactsDir() + "BaseConversions.WmfToPdf.pdf"); + convertImageToPdf(getImagesDir() + "Tagged Image File Format.tiff", getArtifactsDir() + "BaseConversions.TiffToPdf.pdf"); + convertImageToPdf(getImagesDir() + "Graphics Interchange Format.gif", getArtifactsDir() + "BaseConversions.GifToPdf.pdf"); + //ExEnd:ImageToPdf + } + + //ExStart:ConvertImageToPdf + //GistId:b237846932dfcde42358bd0c887661a5 + + /** + * Converts an image to PDF using Aspose.Words for Java. + * + * @param inputFileName File name of input image file. + * @param outputFileName Output PDF file name. + * @throws Exception + */ + private void convertImageToPdf(String inputFileName, String outputFileName) throws Exception { + // Create Aspose.Words.Document and DocumentBuilder. + // The builder makes it simple to add content to the document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert the image into the document and position it at the top left corner of the page. + Shape image = builder.insertImage(inputFileName); + image.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE); + image.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE); + image.setLeft(0); + image.setTop(0); + image.setWrapType(WrapType.NONE); + + // We want the size of the page to be the same as the size of the image. + // Convert pixels to points to size the page to the actual image size. + PageSetup ps = builder.getPageSetup(); + ps.setPageWidth(image.getWidth()); + ps.setPageHeight(image.getHeight()); + + doc.save(outputFileName); + } + //ExEnd:ConvertImageToPdf +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Complex_examples_and_helpers/WorkingWithDocumentInDatabase.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Complex_examples_and_helpers/WorkingWithDocumentInDatabase.java new file mode 100644 index 00000000..a4e7fa3b --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Complex_examples_and_helpers/WorkingWithDocumentInDatabase.java @@ -0,0 +1,89 @@ +package DocsExamples.File_formats_and_conversions.Complex_examples_and_helpers; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Document; +import com.aspose.words.SaveFormat; +import com.aspose.words.net.System.Data.DataTable; +import org.testng.annotations.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.nio.file.Paths; +import java.sql.*; +import java.text.MessageFormat; + +@Test +public class WorkingWithDocumentInDatabase extends DocsExamplesBase { + @Test + public void loadAndSaveDocToDatabase() throws Exception { + Document doc = new Document(getMyDir() + "Document.docx"); + //ExStart:OpenDatabaseConnection + //GistId:86d59d944009f305e7e24b3e276cd17d + Class.forName("net.ucanaccess.jdbc.UcanaccessDriver"); + String connString = "jdbc:ucanaccess://" + getDatabaseDir() + "Northwind.accdb"; + + Connection connection = DriverManager.getConnection(connString, "Admin", ""); + //ExEnd:OpenDatabaseConnection + + //ExStart:OpenRetrieveAndDelete + //GistId:86d59d944009f305e7e24b3e276cd17d + storeToDatabase(doc, connection); + + Document dbDoc = readFromDatabase("Document.docx", connection); + dbDoc.save(getArtifactsDir() + "WorkingWithDocumentInDatabase.LoadAndSaveDocToDatabase.docx"); + + deleteFromDatabase("Document.docx", connection); + + connection.close(); + //ExEnd:OpenRetrieveAndDelete + } + + //ExStart:StoreToDatabase + //GistId:86d59d944009f305e7e24b3e276cd17d + private void storeToDatabase(Document doc, Connection connection) throws Exception { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + doc.save(stream, SaveFormat.DOCX); + + String fileName = Paths.get(doc.getOriginalFileName()).getFileName().toString(); + + String sql = "INSERT INTO Documents (Name, Data) VALUES(?, ?)"; + + PreparedStatement pStatement = connection.prepareStatement(sql); + pStatement.setString(1, fileName); + pStatement.setBytes(2, stream.toByteArray()); + pStatement.execute(); + } + //ExEnd:StoreToDatabase + + //ExStart:ReadFromDatabase + //GistId:86d59d944009f305e7e24b3e276cd17d + private Document readFromDatabase(String fileName, Connection connection) throws Exception { + Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery("SELECT * FROM Documents WHERE Name='" + fileName + "'"); + + DataTable dataTable = new DataTable(resultSet, "Documents"); + + if (dataTable.getRows().getCount() == 0) + throw new IllegalArgumentException( + MessageFormat.format("Could not find any record matching the document \"{0}\" in the database.", fileName)); + + // The document is stored in byte form in the FileContent column. + // Retrieve these bytes of the first matching record to a new buffer. + byte[] buffer = (byte[]) dataTable.getRows().get(0).get("Data"); + + ByteArrayInputStream newStream = new ByteArrayInputStream(buffer); + + Document doc = new Document(newStream); + + return doc; + } + //ExEnd:ReadFromDatabase + + //ExStart:DeleteFromDatabase + //GistId:86d59d944009f305e7e24b3e276cd17d + private void deleteFromDatabase(String fileName, Connection connection) throws SQLException { + Statement statement = connection.createStatement(); + statement.execute("DELETE * FROM Documents WHERE Name='" + fileName + "'"); + } + //ExEnd:DeleteFromDatabase +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Load_options/WorkingWithHtmlLoadOptions.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Load_options/WorkingWithHtmlLoadOptions.java new file mode 100644 index 00000000..609c397e --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Load_options/WorkingWithHtmlLoadOptions.java @@ -0,0 +1,33 @@ +package DocsExamples.File_formats_and_conversions.Load_options; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Document; +import com.aspose.words.HtmlControlType; +import com.aspose.words.HtmlLoadOptions; +import com.aspose.words.SaveFormat; +import org.testng.annotations.Test; + +import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; + +@Test +public class WorkingWithHtmlLoadOptions extends DocsExamplesBase { + @Test + public void preferredControlType() throws Exception { + //ExStart:LoadHtmlElementsWithPreferredControlType + final String html = "" + + "" + + ""; + + HtmlLoadOptions loadOptions = new HtmlLoadOptions(); + loadOptions.setPreferredControlType(HtmlControlType.STRUCTURED_DOCUMENT_TAG); + + Document doc = new Document(new ByteArrayInputStream(html.getBytes(StandardCharsets.UTF_8)), loadOptions); + + doc.save(getArtifactsDir() + "WorkingWithHtmlLoadOptions.PreferredControlType.docx", SaveFormat.DOCX); + //ExEnd:LoadHtmlElementsWithPreferredControlType + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Load_options/WorkingWithLoadOptions.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Load_options/WorkingWithLoadOptions.java new file mode 100644 index 00000000..3354dbd6 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Load_options/WorkingWithLoadOptions.java @@ -0,0 +1,193 @@ +package DocsExamples.File_formats_and_conversions.Load_options; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.nio.charset.Charset; +import java.text.MessageFormat; + +@Test +public class WorkingWithLoadOptions extends DocsExamplesBase { + @Test + public void updateDirtyFields() throws Exception { + //ExStart:UpdateDirtyFields + //GistId:cffe9d4fecedd3037a074e56c4c92054 + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setUpdateDirtyFields(true); + + Document doc = new Document(getMyDir() + "Dirty field.docx", loadOptions); + + doc.save(getArtifactsDir() + "WorkingWithLoadOptions.UpdateDirtyFields.docx"); + //ExEnd:UpdateDirtyFields + } + + @Test + public void loadEncryptedDocument() throws Exception { + //ExStart:LoadSaveEncryptedDocument + //GistId:821ff3a1df0c75b2af641299b393fb60 + //ExStart:OpenEncryptedDocument + //GistId:9216df344e0dc0025f5eda608b9f33d8 + Document doc = new Document(getMyDir() + "Encrypted.docx", new LoadOptions("docPassword")); + //ExEnd:OpenEncryptedDocument + + doc.save(getArtifactsDir() + "WorkingWithLoadOptions.LoadAndSaveEncryptedOdt.odt", new OdtSaveOptions("newPassword")); + //ExEnd:LoadSaveEncryptedDocument + } + + @Test(expectedExceptions = IncorrectPasswordException.class) + public void loadEncryptedDocumentWithoutPassword() throws Exception { + //ExStart:LoadEncryptedDocumentWithoutPassword + //GistId:821ff3a1df0c75b2af641299b393fb60 + // We will not be able to open this document with Microsoft Word or + // Aspose.Words without providing the correct password. + Document doc = new Document(getMyDir() + "Encrypted.docx"); + //ExEnd:LoadEncryptedDocumentWithoutPassword + } + + @Test + public void convertShapeToOfficeMath() throws Exception { + //ExStart:ConvertShapeToOfficeMath + //GistId:ae9835338c044aaa3ac54592b7062db8 + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setConvertShapeToOfficeMath(true); + + Document doc = new Document(getMyDir() + "Office math.docx", loadOptions); + + doc.save(getArtifactsDir() + "WorkingWithLoadOptions.ConvertShapeToOfficeMath.docx", SaveFormat.DOCX); + //ExEnd:ConvertShapeToOfficeMath + } + + @Test + public void setMsWordVersion() throws Exception { + //ExStart:SetMsWordVersion + //GistId:9216df344e0dc0025f5eda608b9f33d8 + // Create a new LoadOptions object, which will load documents according to MS Word 2019 specification by default + // and change the loading version to Microsoft Word 2010. + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setMswVersion(MsWordVersion.WORD_2010); + + Document doc = new Document(getMyDir() + "Document.docx", loadOptions); + + doc.save(getArtifactsDir() + "WorkingWithLoadOptions.SetMsWordVersion.docx"); + //ExEnd:SetMsWordVersion + } + + @Test + public void tempFolder() throws Exception { + //ExStart:TempFolder + //GistId:9216df344e0dc0025f5eda608b9f33d8 + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setTempFolder(getArtifactsDir()); + + Document doc = new Document(getMyDir() + "Document.docx", loadOptions); + //ExEnd:TempFolder + } + + @Test + public void warningCallback() throws Exception { + //ExStart:WarningCallback + //GistId:9216df344e0dc0025f5eda608b9f33d8 + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setWarningCallback(new DocumentLoadingWarningCallback()); + + Document doc = new Document(getMyDir() + "Document.docx", loadOptions); + //ExEnd:WarningCallback + } + + //ExStart:IWarningCallback + //GistId:9216df344e0dc0025f5eda608b9f33d8 + public static class DocumentLoadingWarningCallback implements IWarningCallback { + public void warning(WarningInfo info) { + // Prints warnings and their details as they arise during document loading. + System.out.println(MessageFormat.format("WARNING: {0}, source: {1}", info.getWarningType(), info.getSource())); + System.out.println(MessageFormat.format("\tDescription: {0}", info.getDescription())); + } + } + //ExEnd:IWarningCallback + + @Test + public void resourceLoadingCallback() throws Exception { + //ExStart:ResourceLoadingCallback + //GistId:9216df344e0dc0025f5eda608b9f33d8 + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setResourceLoadingCallback(new HtmlLinkedResourceLoadingCallback()); + + // When we open an Html document, external resources such as references to CSS stylesheet files + // and external images will be handled customarily by the loading callback as the document is loaded. + Document doc = new Document(getMyDir() + "Images.html", loadOptions); + doc.save(getArtifactsDir() + "WorkingWithLoadOptions.ResourceLoadingCallback.pdf"); + //ExEnd:ResourceLoadingCallback + } + + //ExStart:IResourceLoadingCallback + //GistId:9216df344e0dc0025f5eda608b9f33d8 + private static class HtmlLinkedResourceLoadingCallback implements IResourceLoadingCallback { + public int resourceLoading(ResourceLoadingArgs args) throws Exception { + switch (args.getResourceType()) { + case ResourceType.CSS_STYLE_SHEET: + System.out.println("External CSS Stylesheet found upon loading: " + args.getOriginalUri()); + // CSS file will don't used in the document. + return ResourceLoadingAction.SKIP; + + case ResourceType.IMAGE: + // Replaces all images with a substitute. + BufferedImage newImage = ImageIO.read(new File(getImagesDir() + "Logo.jpg")); + + try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + ImageIO.write(newImage, "jpg", baos); + byte[] imageBytes = baos.toByteArray(); + args.setData(imageBytes); + } + + // New images will be used instead of presented in the document. + return ResourceLoadingAction.USER_PROVIDED; + + case ResourceType.DOCUMENT: + System.out.println("External document found upon loading: " + args.getOriginalUri()); + // Will be used as usual. + return ResourceLoadingAction.DEFAULT; + + default: + throw new IllegalArgumentException("Unexpected ResourceType value."); + } + } + } + //ExEnd:IResourceLoadingCallback + + @Test + public void loadWithEncoding() throws Exception { + //ExStart:LoadWithEncoding + //GistId:9216df344e0dc0025f5eda608b9f33d8 + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setEncoding(Charset.forName("US-ASCII")); + + // Load the document while passing the LoadOptions object, then verify the document's contents. + Document doc = new Document(getMyDir() + "English text.txt", loadOptions); + //ExEnd:LoadWithEncoding + } + + @Test + public void convertMetafilesToPng() throws Exception { + //ExStart:ConvertMetafilesToPng + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setConvertMetafilesToPng(true); + + Document doc = new Document(getMyDir() + "WMF with image.docx", loadOptions); + //ExEnd:ConvertMetafilesToPng + } + + @Test + public void loadChm() throws Exception { + //ExStart:LoadCHM + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setEncoding(Charset.forName("windows-1251")); + + Document doc = new Document(getMyDir() + "HTML help.chm", loadOptions); + //ExEnd:LoadCHM + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Load_options/WorkingWithRtfLoadOptions.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Load_options/WorkingWithRtfLoadOptions.java new file mode 100644 index 00000000..462f1d6c --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Load_options/WorkingWithRtfLoadOptions.java @@ -0,0 +1,21 @@ +package DocsExamples.File_formats_and_conversions.Load_options; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Document; +import com.aspose.words.RtfLoadOptions; +import org.testng.annotations.Test; + +@Test +public class WorkingWithRtfLoadOptions extends DocsExamplesBase { + @Test + public void recognizeUtf8Text() throws Exception { + //ExStart:RecognizeUtf8Text + RtfLoadOptions loadOptions = new RtfLoadOptions(); + loadOptions.setRecognizeUtf8Text(true); + + Document doc = new Document(getMyDir() + "UTF-8 characters.rtf", loadOptions); + + doc.save(getArtifactsDir() + "WorkingWithRtfLoadOptions.RecognizeUtf8Text.rtf"); + //ExEnd:RecognizeUtf8Text + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Load_options/WorkingWithTxtLoadOptions.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Load_options/WorkingWithTxtLoadOptions.java new file mode 100644 index 00000000..c3ddddb8 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Load_options/WorkingWithTxtLoadOptions.java @@ -0,0 +1,124 @@ +package DocsExamples.File_formats_and_conversions.Load_options; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.io.ByteArrayInputStream; + +@Test +public class WorkingWithTxtLoadOptions extends DocsExamplesBase { + @Test + public void detectNumberingWithWhitespaces() throws Exception { + //ExStart:DetectNumberingWithWhitespaces + //GistId:c92d84644de8ee6e7148950debea90d6 + // Create a plaintext document in the form of a string with parts that may be interpreted as lists. + // Upon loading, the first three lists will always be detected by Aspose.Words, + // and List objects will be created for them after loading. + final String TEXT_DOC = "Full stop delimiters:\n" + + "1. First list item 1\n" + + "2. First list item 2\n" + + "3. First list item 3\n\n" + + "Right bracket delimiters:\n" + + "1) Second list item 1\n" + + "2) Second list item 2\n" + + "3) Second list item 3\n\n" + + "Bullet delimiters:\n" + + "• Third list item 1\n" + + "• Third list item 2\n" + + "• Third list item 3\n\n" + + "Whitespace delimiters:\n" + + "1 Fourth list item 1\n" + + "2 Fourth list item 2\n" + + "3 Fourth list item 3"; + + // The fourth list, with whitespace inbetween the list number and list item contents, + // will only be detected as a list if "DetectNumberingWithWhitespaces" in a LoadOptions object is set to true, + // to avoid paragraphs that start with numbers being mistakenly detected as lists. + TxtLoadOptions loadOptions = new TxtLoadOptions(); + loadOptions.setDetectNumberingWithWhitespaces(true); + + // Load the document while applying LoadOptions as a parameter and verify the result. + Document doc = new Document(new ByteArrayInputStream(TEXT_DOC.getBytes()), loadOptions); + + doc.save(getArtifactsDir() + "WorkingWithTxtLoadOptions.DetectNumberingWithWhitespaces.docx"); + //ExEnd:DetectNumberingWithWhitespaces + } + + @Test + public void handleSpacesOptions() throws Exception { + //ExStart:HandleSpacesOptions + //GistId:c92d84644de8ee6e7148950debea90d6 + final String TEXT_DOC = " Line 1 \n" + + " Line 2 \n" + + " Line 3 "; + + TxtLoadOptions loadOptions = new TxtLoadOptions(); + loadOptions.setLeadingSpacesOptions(TxtLeadingSpacesOptions.TRIM); + loadOptions.setTrailingSpacesOptions(TxtTrailingSpacesOptions.TRIM); + + Document doc = new Document(new ByteArrayInputStream(TEXT_DOC.getBytes()), loadOptions); + + doc.save(getArtifactsDir() + "WorkingWithTxtLoadOptions.HandleSpacesOptions.docx"); + //ExEnd:HandleSpacesOptions + } + + @Test + public void documentTextDirection() throws Exception { + //ExStart:DocumentTextDirection + //GistId:c92d84644de8ee6e7148950debea90d6 + TxtLoadOptions loadOptions = new TxtLoadOptions(); + loadOptions.setDocumentDirection(DocumentDirection.AUTO); + + Document doc = new Document(getMyDir() + "Hebrew text.txt", loadOptions); + + Paragraph paragraph = doc.getFirstSection().getBody().getFirstParagraph(); + System.out.println(paragraph.getParagraphFormat().getBidi()); + + doc.save(getArtifactsDir() + "WorkingWithTxtLoadOptions.DocumentTextDirection.docx"); + //ExEnd:DocumentTextDirection + } + + @Test + public void exportHeadersFootersMode() throws Exception { + //ExStart:ExportHeadersFootersMode + //GistId:c92d84644de8ee6e7148950debea90d6 + Document doc = new Document(); + + // Insert even and primary headers/footers into the document. + // The primary header/footers will override the even headers/footers. + doc.getFirstSection().getHeadersFooters().add(new HeaderFooter(doc, HeaderFooterType.HEADER_EVEN)); + doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.HEADER_EVEN).appendParagraph("Even header"); + doc.getFirstSection().getHeadersFooters().add(new HeaderFooter(doc, HeaderFooterType.FOOTER_EVEN)); + doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_EVEN).appendParagraph("Even footer"); + doc.getFirstSection().getHeadersFooters().add(new HeaderFooter(doc, HeaderFooterType.HEADER_PRIMARY)); + doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.HEADER_PRIMARY).appendParagraph("Primary header"); + doc.getFirstSection().getHeadersFooters().add(new HeaderFooter(doc, HeaderFooterType.FOOTER_PRIMARY)); + doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY).appendParagraph("Primary footer"); + + // Insert pages to display these headers and footers. + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Page 1"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 2"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.write("Page 3"); + + TxtSaveOptions options = new TxtSaveOptions(); + options.setSaveFormat(SaveFormat.TEXT); + + // All headers and footers are placed at the very end of the output document. + options.setExportHeadersFootersMode(TxtExportHeadersFootersMode.ALL_AT_END); + doc.save(getArtifactsDir() + "WorkingWithTxtLoadOptions.HeadersFootersMode.AllAtEnd.txt", options); + + // Only primary headers and footers are exported at the beginning and end of each section. + options.setExportHeadersFootersMode(TxtExportHeadersFootersMode.PRIMARY_ONLY); + doc.save(getArtifactsDir() + "WorkingWithTxtLoadOptions.HeadersFootersMode.PrimaryOnly.txt", options); + + // No headers and footers are exported. + options.setExportHeadersFootersMode(TxtExportHeadersFootersMode.NONE); + doc.save(getArtifactsDir() + "WorkingWithTxtLoadOptions.HeadersFootersMode.None.txt", options); + //ExEnd:ExportHeadersFootersMode + } +} + diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithDocSaveOptions.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithDocSaveOptions.java new file mode 100644 index 00000000..3e9871e1 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithDocSaveOptions.java @@ -0,0 +1,50 @@ +package DocsExamples.File_formats_and_conversions.Save_options; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.DocSaveOptions; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import org.testng.annotations.Test; + +@Test +public class WorkingWithDocSaveOptions extends DocsExamplesBase { + @Test + public void encryptDocumentWithPassword() throws Exception { + //ExStart:EncryptDocumentWithPassword + //GistId:821ff3a1df0c75b2af641299b393fb60 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Hello world!"); + + DocSaveOptions saveOptions = new DocSaveOptions(); + saveOptions.setPassword("password"); + + doc.save(getArtifactsDir() + "WorkingWithDocSaveOptions.EncryptDocumentWithPassword.docx", saveOptions); + //ExEnd:EncryptDocumentWithPassword + } + + @Test + public void doNotCompressSmallMetafiles() throws Exception { + //ExStart:DoNotCompressSmallMetafiles + Document doc = new Document(getMyDir() + "Microsoft equation object.docx"); + + DocSaveOptions saveOptions = new DocSaveOptions(); + saveOptions.setAlwaysCompressMetafiles(false); + + doc.save(getArtifactsDir() + "WorkingWithDocSaveOptions.NotCompressSmallMetafiles.docx", saveOptions); + //ExEnd:DoNotCompressSmallMetafiles + } + + @Test + public void doNotSavePictureBullet() throws Exception { + //ExStart:DoNotSavePictureBullet + Document doc = new Document(getMyDir() + "Image bullet points.docx"); + + DocSaveOptions saveOptions = new DocSaveOptions(); + saveOptions.setSavePictureBullet(false); + + doc.save(getArtifactsDir() + "WorkingWithDocSaveOptions.DoNotSavePictureBullet.docx", saveOptions); + //ExEnd:DoNotSavePictureBullet + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithHtmlFixedSaveOptions.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithHtmlFixedSaveOptions.java new file mode 100644 index 00000000..9eaa7214 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithHtmlFixedSaveOptions.java @@ -0,0 +1,35 @@ +package DocsExamples.File_formats_and_conversions.Save_options; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Document; +import com.aspose.words.HtmlFixedSaveOptions; +import org.testng.annotations.Test; + +@Test +public class WorkingWithHtmlFixedSaveOptions extends DocsExamplesBase { + @Test + public void useFontFromTargetMachine() throws Exception { + //ExStart:UseFontFromTargetMachine + Document doc = new Document(getMyDir() + "Bullet points with alternative font.docx"); + + HtmlFixedSaveOptions saveOptions = new HtmlFixedSaveOptions(); + saveOptions.setUseTargetMachineFonts(true); + + doc.save(getArtifactsDir() + "WorkingWithHtmlFixedSaveOptions.UseFontFromTargetMachine.html", saveOptions); + //ExEnd:UseFontFromTargetMachine + } + + @Test + public void writeAllCssRulesInSingleFile() throws Exception { + //ExStart:WriteAllCssRulesInSingleFile + Document doc = new Document(getMyDir() + "Document.docx"); + + // Setting this property to true restores the old behavior (separate files) for compatibility with legacy code. + // All CSS rules are written into single file "styles.css. + HtmlFixedSaveOptions saveOptions = new HtmlFixedSaveOptions(); + saveOptions.setSaveFontFaceCssSeparately(false); + + doc.save(getArtifactsDir() + "WorkingWithHtmlFixedSaveOptions.WriteAllCssRulesInSingleFile.html", saveOptions); + //ExEnd:WriteAllCssRulesInSingleFile + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithHtmlSaveOptions.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithHtmlSaveOptions.java new file mode 100644 index 00000000..abe276a4 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithHtmlSaveOptions.java @@ -0,0 +1,165 @@ +package DocsExamples.File_formats_and_conversions.Save_options; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.file.Paths; + +@Test +public class WorkingWithHtmlSaveOptions extends DocsExamplesBase { + @Test + public void exportRoundtripInformation() throws Exception { + //ExStart:ExportRoundtripInformation + //GistId:c2ec8aa36ef37670eceec8da5c612b86 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + saveOptions.setExportRoundtripInformation(true); + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ExportRoundtripInformation.html", saveOptions); + //ExEnd:ExportRoundtripInformation + } + + @Test + public void exportFontsAsBase64() throws Exception { + //ExStart:ExportFontsAsBase64 + //GistId:c2ec8aa36ef37670eceec8da5c612b86 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + saveOptions.setExportFontsAsBase64(true); + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ExportFontsAsBase64.html", saveOptions); + //ExEnd:ExportFontsAsBase64 + } + + @Test + public void exportResources() throws Exception { + //ExStart:ExportResources + //GistId:c2ec8aa36ef37670eceec8da5c612b86 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + saveOptions.setCssStyleSheetType(CssStyleSheetType.EXTERNAL); + saveOptions.setExportFontResources(true); + saveOptions.setResourceFolder(getArtifactsDir() + "Resources"); + saveOptions.setResourceFolderAlias("http://example.com/resources"); + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ExportResources.html", saveOptions); + //ExEnd:ExportResources + } + + @Test + public void convertMetafilesToPng() throws Exception { + //ExStart:ConvertMetafilesToPng + String html = "" + + "" + + "Hello world!" + + "" + + ""; + + // Use 'ConvertSvgToEmf' to turn back the legacy behavior + // where all SVG images loaded from an HTML document were converted to EMF. + // Now SVG images are loaded without conversion + // if the MS Word version specified in load options supports SVG images natively. + HtmlLoadOptions loadOptions = new HtmlLoadOptions(); + loadOptions.setConvertSvgToEmf(true); + + Charset charset = StandardCharsets.UTF_8; + Document doc = new Document(new ByteArrayInputStream(html.getBytes(charset)), loadOptions); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + saveOptions.setMetafileFormat(HtmlMetafileFormat.PNG); + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ConvertMetafilesToPng.html", saveOptions); + //ExEnd:ConvertMetafilesToPng + } + + @Test + public void convertMetafilesToSvg() throws Exception { + //ExStart:ConvertMetafilesToSvg + String html = "" + + "" + + " "; + + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Here is an SVG image: "); + builder.insertHtml(html); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + saveOptions.setMetafileFormat(HtmlMetafileFormat.SVG); + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ConvertMetafilesToSvg.html", saveOptions); + //ExEnd:ConvertMetafilesToSvg + } + + @Test + public void addCssClassNamePrefix() throws Exception { + //ExStart:AddCssClassNamePrefix + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + saveOptions.setCssStyleSheetType(CssStyleSheetType.EXTERNAL); + saveOptions.setCssClassNamePrefix("pfx_"); + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.AddCssClassNamePrefix.html", saveOptions); + //ExEnd:AddCssClassNamePrefix + } + + @Test + public void exportCidUrlsForMhtmlResources() throws Exception { + //ExStart:ExportCidUrlsForMhtmlResources + Document doc = new Document(getMyDir() + "Content-ID.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(SaveFormat.MHTML); + saveOptions.setPrettyFormat(true); + saveOptions.setExportCidUrlsForMhtmlResources(true); + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ExportCidUrlsForMhtmlResources.mhtml", saveOptions); + //ExEnd:ExportCidUrlsForMhtmlResources + } + + @Test + public void resolveFontNames() throws Exception { + //ExStart:ResolveFontNames + Document doc = new Document(getMyDir() + "Missing font.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(SaveFormat.HTML); + saveOptions.setPrettyFormat(true); + saveOptions.setResolveFontNames(true); + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ResolveFontNames.html", saveOptions); + //ExEnd:ResolveFontNames + } + + @Test + public void exportTextInputFormFieldAsText() throws Exception { + //ExStart:ExportTextInputFormFieldAsText + //GistId:a6f7799aa265589fb56915bb1e401b05 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + File imagesDir = new File(Paths.get(getArtifactsDir(), "Images").toString()); + + // The folder specified needs to exist and should be empty. + if (imagesDir.exists()) + imagesDir.delete(); + + imagesDir.mkdir(); + + // Set an option to export form fields as plain text, not as HTML input elements. + HtmlSaveOptions saveOptions = new HtmlSaveOptions(SaveFormat.HTML); + saveOptions.setExportTextInputFormFieldAsText(true); + saveOptions.setImagesFolder(imagesDir.getPath()); + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ExportTextInputFormFieldAsText.html", saveOptions); + //ExEnd:ExportTextInputFormFieldAsText + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithImageSaveOptions.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithImageSaveOptions.java new file mode 100644 index 00000000..c41a8ff0 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithImageSaveOptions.java @@ -0,0 +1,140 @@ +package DocsExamples.File_formats_and_conversions.Save_options; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.awt.*; +import java.text.MessageFormat; + +@Test +public class WorkingWithImageSaveOptions extends DocsExamplesBase { + @Test + public void exposeThresholdControlForTiffBinarization() throws Exception { + //ExStart:ExposeThresholdControl + //GistId:402579012106180dd1687e6d7f6386b8 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.TIFF); + saveOptions.setTiffCompression(TiffCompression.CCITT_3); + saveOptions.setImageColorMode(ImageColorMode.GRAYSCALE); + saveOptions.setTiffBinarizationMethod(ImageBinarizationMethod.FLOYD_STEINBERG_DITHERING); + saveOptions.setThresholdForFloydSteinbergDithering((byte) 254); + + doc.save(getArtifactsDir() + "WorkingWithImageSaveOptions.ExposeThresholdControl.tiff", saveOptions); + //ExEnd:ExposeThresholdControl + } + + @Test + public void getTiffPageRange() throws Exception { + //ExStart:GetTiffPageRange + //GistId:402579012106180dd1687e6d7f6386b8 + Document doc = new Document(getMyDir() + "Rendering.docx"); + //ExStart:SaveAsTiff + //GistId:402579012106180dd1687e6d7f6386b8 + doc.save(getArtifactsDir() + "WorkingWithImageSaveOptions.MultipageTiff.tiff"); + //ExEnd:SaveAsTiff + + //ExStart:SaveAsTIFFUsingImageSaveOptions + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.TIFF); + saveOptions.setPageSet(new PageSet(new PageRange(0, 1))); + saveOptions.setTiffCompression(TiffCompression.CCITT_4); + saveOptions.setResolution(160f); + + doc.save(getArtifactsDir() + "WorkingWithImageSaveOptions.GetTiffPageRange.tiff", saveOptions); + //ExEnd:SaveAsTIFFUsingImageSaveOptions + //ExEnd:GetTiffPageRange + } + + @Test + public void format1BppIndexed() throws Exception { + //ExStart:Format1BppIndexed + //GistId:a6f7799aa265589fb56915bb1e401b05 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.PNG); + saveOptions.setPageSet(new PageSet(1)); + saveOptions.setImageColorMode(ImageColorMode.BLACK_AND_WHITE); + saveOptions.setPixelFormat(ImagePixelFormat.FORMAT_1_BPP_INDEXED); + + doc.save(getArtifactsDir() + "WorkingWithImageSaveOptions.Format1BppIndexed.Png", saveOptions); + //ExEnd:Format1BppIndexed + } + + @Test + public void getJpegPageRange() throws Exception { + //ExStart:GetJpegPageRange + //GistId:3e41a25b97b6091491b45ebf20f273b5 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.JPEG); + + // Set the "PageSet" to "0" to convert only the first page of a document. + options.setPageSet(new PageSet(0)); + + // Change the image's brightness and contrast. + // Both are on a 0-1 scale and are at 0.5 by default. + options.setImageBrightness(0.3f); + options.setImageContrast(0.7f); + + // Change the horizontal resolution. + // The default value for these properties is 96.0, for a resolution of 96dpi. + options.setHorizontalResolution(72f); + + doc.save(getArtifactsDir() + "WorkingWithImageSaveOptions.GetJpegPageRange.jpeg", options); + //ExEnd:GetJpegPageRange + } + + @Test + //ExStart:PageSavingCallback + public static void pageSavingCallback() throws Exception { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + ImageSaveOptions imageSaveOptions = new ImageSaveOptions(SaveFormat.PNG); + imageSaveOptions.setPageSet(new PageSet(new PageRange(0, doc.getPageCount() - 1))); + imageSaveOptions.setPageSavingCallback(new HandlePageSavingCallback()); + + doc.save(getArtifactsDir() + "WorkingWithImageSaveOptions.PageSavingCallback.png", imageSaveOptions); + } + + private static class HandlePageSavingCallback implements IPageSavingCallback { + public void pageSaving(PageSavingArgs args) { + args.setPageFileName(MessageFormat.format(getArtifactsDir() + "Page_{0}.png", args.getPageIndex())); + } + } + //ExEnd:PageSavingCallback + + @Test + public void horizontalLayout() throws Exception { + //ExStart:HorizontalLayout + //GistId:90715b6eecef1740f54f3eddb072b5d2 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.JPEG); + options.setPageLayout(MultiPageLayout.horizontal(10)); + + doc.save(getArtifactsDir() + "WorkingWithImageSaveOptions.HorizontalLayout.jpg", options); + //ExEnd:HorizontalLayout + } + + @Test + public void gridLayout() throws Exception { + //ExStart:GridLayout + //GistId:90715b6eecef1740f54f3eddb072b5d2 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.JPEG); + // Set up a grid layout with: + // - 3 columns per row. + // - 10pts spacing between pages (horizontal and vertical). + options.setPageLayout(MultiPageLayout.grid(3, 10, 10)); + + // Customize the background and border. + options.getPageLayout().setBackColor(Color.lightGray); + options.getPageLayout().setBorderColor(Color.blue); + options.getPageLayout().setBorderWidth(2); + + doc.save(getArtifactsDir() + "ImageSaveOptions.GridLayout.jpg", options); + //ExEnd:GridLayout + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithMarkdownSaveOptions.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithMarkdownSaveOptions.java new file mode 100644 index 00000000..5d938792 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithMarkdownSaveOptions.java @@ -0,0 +1,58 @@ +package DocsExamples.File_formats_and_conversions.Save_options; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.io.ByteArrayOutputStream; + +@Test +public class WorkingWithMarkdownSaveOptions extends DocsExamplesBase { + @Test + public void markdownTableContentAlignment() throws Exception { + //ExStart:MarkdownTableContentAlignment + //GistId:50b2b6a8785c07713e7c09d772e9a396 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertCell(); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.RIGHT); + builder.write("Cell1"); + builder.insertCell(); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.write("Cell2"); + + // Makes all paragraphs inside the table to be aligned. + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + saveOptions.setTableContentAlignment(TableContentAlignment.LEFT); + + doc.save(getArtifactsDir() + "WorkingWithMarkdownSaveOptions.LeftTableContentAlignment.md", saveOptions); + + saveOptions.setTableContentAlignment(TableContentAlignment.RIGHT); + doc.save(getArtifactsDir() + "WorkingWithMarkdownSaveOptions.RightTableContentAlignment.md", saveOptions); + + saveOptions.setTableContentAlignment(TableContentAlignment.CENTER); + doc.save(getArtifactsDir() + "WorkingWithMarkdownSaveOptions.CenterTableContentAlignment.md", saveOptions); + + // The alignment in this case will be taken from the first paragraph in corresponding table column. + saveOptions.setTableContentAlignment(TableContentAlignment.AUTO); + doc.save(getArtifactsDir() + "WorkingWithMarkdownSaveOptions.AutoTableContentAlignment.md", saveOptions); + //ExEnd:MarkdownTableContentAlignment + } + + @Test + public void imagesFolder() throws Exception { + //ExStart:ImagesFolder + //GistId:642767bbe8d8bec8eab080120b707990 + Document doc = new Document(getMyDir() + "Image bullet points.docx"); + + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + saveOptions.setImagesFolder(getArtifactsDir() + "Images"); + + try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) { + doc.save(stream, saveOptions); + } + //ExEnd:ImagesFolder + } +} + diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithOdtSaveOptions.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithOdtSaveOptions.java new file mode 100644 index 00000000..71f8f63c --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithOdtSaveOptions.java @@ -0,0 +1,24 @@ +package DocsExamples.File_formats_and_conversions.Save_options; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Document; +import com.aspose.words.OdtSaveMeasureUnit; +import com.aspose.words.OdtSaveOptions; +import org.testng.annotations.Test; + +@Test +public class WorkingWithOdtSaveOptions extends DocsExamplesBase { + @Test + public void measureUnit() throws Exception { + //ExStart:MeasureUnit + Document doc = new Document(getMyDir() + "Document.docx"); + + // Open Office uses centimeters when specifying lengths, widths and other measurable formatting + // and content properties in documents whereas MS Office uses inches. + OdtSaveOptions saveOptions = new OdtSaveOptions(); + saveOptions.setMeasureUnit(OdtSaveMeasureUnit.INCHES); + + doc.save(getArtifactsDir() + "WorkingWithOdtSaveOptions.MeasureUnit.odt", saveOptions); + //ExEnd:MeasureUnit + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithOoxmlSaveOptions.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithOoxmlSaveOptions.java new file mode 100644 index 00000000..8d407e17 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithOoxmlSaveOptions.java @@ -0,0 +1,71 @@ +package DocsExamples.File_formats_and_conversions.Save_options; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +@Test +public class WorkingWithOoxmlSaveOptions extends DocsExamplesBase { + @Test + public void encryptDocxWithPassword() throws Exception { + //ExStart:EncryptDocxWithPassword + Document doc = new Document(getMyDir() + "Document.docx"); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + saveOptions.setPassword("password"); + + doc.save(getArtifactsDir() + "WorkingWithOoxmlSaveOptions.EncryptDocxWithPassword.docx", saveOptions); + //ExEnd:EncryptDocxWithPassword + } + + @Test + public void ooxmlComplianceIso29500_2008_Strict() throws Exception { + //ExStart:OoxmlComplianceIso29500_2008_Strict + Document doc = new Document(getMyDir() + "Document.docx"); + + doc.getCompatibilityOptions().optimizeFor(MsWordVersion.WORD_2016); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + saveOptions.setCompliance(OoxmlCompliance.ISO_29500_2008_STRICT); + + doc.save(getArtifactsDir() + "WorkingWithOoxmlSaveOptions.OoxmlComplianceIso29500_2008_Strict.docx", saveOptions); + //ExEnd:OoxmlComplianceIso29500_2008_Strict + } + + @Test + public void updateLastSavedTime() throws Exception { + //ExStart:UpdateLastSavedTime + //GistId:a6f7799aa265589fb56915bb1e401b05 + Document doc = new Document(getMyDir() + "Document.docx"); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + saveOptions.setUpdateLastSavedTimeProperty(true); + + doc.save(getArtifactsDir() + "WorkingWithOoxmlSaveOptions.UpdateLastSavedTime.docx", saveOptions); + //ExEnd:UpdateLastSavedTime + } + + @Test + public void keepLegacyControlChars() throws Exception { + //ExStart:KeepLegacyControlChars + Document doc = new Document(getMyDir() + "Legacy control character.doc"); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(SaveFormat.FLAT_OPC); + saveOptions.setKeepLegacyControlChars(true); + + doc.save(getArtifactsDir() + "WorkingWithOoxmlSaveOptions.KeepLegacyControlChars.docx", saveOptions); + //ExEnd:KeepLegacyControlChars + } + + @Test + public void setCompressionLevel() throws Exception { + //ExStart:SetCompressionLevel + Document doc = new Document(getMyDir() + "Document.docx"); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); + saveOptions.setCompressionLevel(CompressionLevel.SUPER_FAST); + + doc.save(getArtifactsDir() + "WorkingWithOoxmlSaveOptions.SetCompressionLevel.docx", saveOptions); + //ExEnd:SetCompressionLevel + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithPclSaveOptions.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithPclSaveOptions.java new file mode 100644 index 00000000..d13c8690 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithPclSaveOptions.java @@ -0,0 +1,24 @@ +package DocsExamples.File_formats_and_conversions.Save_options; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Document; +import com.aspose.words.PclSaveOptions; +import com.aspose.words.SaveFormat; +import org.testng.annotations.Test; + +@Test +public class WorkingWithPclSaveOptions extends DocsExamplesBase { + @Test + public void rasterizeTransformedElements() throws Exception { + //ExStart:RasterizeTransformedElements + //GistId:9d2a393f6dff9d785e7747a48e590d9d + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PclSaveOptions saveOptions = new PclSaveOptions(); + saveOptions.setSaveFormat(SaveFormat.PCL); + saveOptions.setRasterizeTransformedElements(false); + + doc.save(getArtifactsDir() + "WorkingWithPclSaveOptions.RasterizeTransformedElements.pcl", saveOptions); + //ExEnd:RasterizeTransformedElements + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithPdfSaveOptions.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithPdfSaveOptions.java new file mode 100644 index 00000000..4556c733 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithPdfSaveOptions.java @@ -0,0 +1,391 @@ +package DocsExamples.File_formats_and_conversions.Save_options; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.Date; + +@Test +public class WorkingWithPdfSaveOptions extends DocsExamplesBase { + @Test + public void displayDocTitleInWindowTitleBar() throws Exception { + //ExStart:DisplayDocTitleInWindowTitleBar + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setDisplayDocTitle(true); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.DisplayDocTitleInWindowTitlebar.pdf", saveOptions); + //ExEnd:DisplayDocTitleInWindowTitleBar + } + + @Test + //ExStart:PdfRenderWarnings + //GistId:c33834c88b84242b9b28c1cfc22eb762 + public void pdfRenderWarnings() throws Exception { + Document doc = new Document(getMyDir() + "WMF with image.docx"); + + MetafileRenderingOptions metafileRenderingOptions = new MetafileRenderingOptions(); + metafileRenderingOptions.setEmulateRasterOperations(false); + metafileRenderingOptions.setRenderingMode(MetafileRenderingMode.VECTOR_WITH_FALLBACK); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setMetafileRenderingOptions(metafileRenderingOptions); + + // If Aspose.Words cannot correctly render some of the metafile records + // to vector graphics then Aspose.Words renders this metafile to a bitmap. + HandleDocumentWarnings callback = new HandleDocumentWarnings(); + doc.setWarningCallback(callback); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.PdfRenderWarnings.pdf", saveOptions); + + // While the file saves successfully, rendering warnings that occurred during saving are collected here. + for (WarningInfo warningInfo : callback.mWarnings) { + System.out.println(warningInfo.getDescription()); + } + } + + public static class HandleDocumentWarnings implements IWarningCallback { + ///

          + /// Our callback only needs to implement the "Warning" method. This method is called whenever there is a + /// potential issue during document processing. The callback can be set to listen for warnings generated during + /// document load and/or document save. + /// + public void warning(WarningInfo info) { + // For now type of warnings about unsupported metafile records changed + // from DataLoss/UnexpectedContent to MinorFormattingLoss. + if (info.getWarningType() == WarningType.MINOR_FORMATTING_LOSS) { + System.out.println("Unsupported operation: " + info.getDescription()); + mWarnings.warning(info); + } + } + + public WarningInfoCollection mWarnings = new WarningInfoCollection(); + } + //ExEnd:PdfRenderWarnings + + @Test + public void digitallySignedPdfUsingCertificateHolder() throws Exception { + //ExStart:DigitallySignedPdfUsingCertificateHolder + //GistId:39ea49b7754e472caf41179f8b5970a0 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Test Signed PDF."); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setDigitalSignatureDetails(new PdfDigitalSignatureDetails( + CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"), "reason", "location", + new Date())); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.DigitallySignedPdfUsingCertificateHolder.pdf", saveOptions); + //ExEnd:DigitallySignedPdfUsingCertificateHolder + } + + @Test + public void embeddedAllFonts() throws Exception { + //ExStart:EmbeddedAllFonts + //GistId:a5d65fc091d4330c8b66a17170524341 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // The output PDF will be embedded with all fonts found in the document. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setEmbedFullFonts(true); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.EmbeddedAllFonts.pdf", saveOptions); + //ExEnd:EmbeddedAllFonts + } + + @Test + public void embeddedSubsetFonts() throws Exception { + //ExStart:EmbeddedSubsetFonts + //GistId:a5d65fc091d4330c8b66a17170524341 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // The output PDF will contain subsets of the fonts in the document. + // Only the glyphs used in the document are included in the PDF fonts. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setEmbedFullFonts(false); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.EmbeddedSubsetFonts.pdf", saveOptions); + //ExEnd:EmbeddedSubsetFonts + } + + @Test + public void disableEmbedWindowsFonts() throws Exception { + //ExStart:DisableEmbedWindowsFonts + //GistId:a5d65fc091d4330c8b66a17170524341 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // The output PDF will be saved without embedding standard windows fonts. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setFontEmbeddingMode(PdfFontEmbeddingMode.EMBED_NONE); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.DisableEmbedWindowsFonts.pdf", saveOptions); + //ExEnd:DisableEmbedWindowsFonts + } + + @Test + public void skipEmbeddedArialAndTimesRomanFonts() throws Exception { + //ExStart:SkipEmbeddedArialAndTimesRomanFonts + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setFontEmbeddingMode(PdfFontEmbeddingMode.EMBED_ALL); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.SkipEmbeddedArialAndTimesRomanFonts.pdf", saveOptions); + //ExEnd:SkipEmbeddedArialAndTimesRomanFonts + } + + @Test + public void avoidEmbeddingCoreFonts() throws Exception { + //ExStart:AvoidEmbeddingCoreFonts + //GistId:a5d65fc091d4330c8b66a17170524341 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // The output PDF will not be embedded with core fonts such as Arial, Times New Roman etc. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setUseCoreFonts(true); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.AvoidEmbeddingCoreFonts.pdf", saveOptions); + //ExEnd:AvoidEmbeddingCoreFonts + } + + @Test + public void escapeUri() throws Exception { + //ExStart:EscapeUri + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertHyperlink("Testlink", "https://www.google.com/search?q= aspose", false); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.EscapeUri.pdf"); + //ExEnd:EscapeUri + } + + @Test + public void exportHeaderFooterBookmarks() throws Exception { + //ExStart:ExportHeaderFooterBookmarks + //GistId:a5d65fc091d4330c8b66a17170524341 + Document doc = new Document(getMyDir() + "Bookmarks in headers and footers.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.getOutlineOptions().setDefaultBookmarksOutlineLevel(1); + saveOptions.setHeaderFooterBookmarksExportMode(HeaderFooterBookmarksExportMode.FIRST); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.ExportHeaderFooterBookmarks.pdf", saveOptions); + //ExEnd:ExportHeaderFooterBookmarks + } + + @Test + public void emulateRenderingToSizeOnPage() throws Exception { + //ExStart:EmulateRenderingToSizeOnPage + Document doc = new Document(getMyDir() + "WMF with text.docx"); + + MetafileRenderingOptions metafileRenderingOptions = new MetafileRenderingOptions(); + metafileRenderingOptions.setEmulateRenderingToSizeOnPage(false); + + // If Aspose.Words cannot correctly render some of the metafile records to vector graphics + // then Aspose.Words renders this metafile to a bitmap. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setMetafileRenderingOptions(metafileRenderingOptions); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.EmulateRenderingToSizeOnPage.pdf", saveOptions); + //ExEnd:EmulateRenderingToSizeOnPage + } + + @Test + public void additionalTextPositioning() throws Exception { + //ExStart:AdditionalTextPositioning + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setAdditionalTextPositioning(true); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.AdditionalTextPositioning.pdf", saveOptions); + //ExEnd:AdditionalTextPositioning + } + + @Test + public void conversionToPdf17() throws Exception { + //ExStart:ConversionToPdf17 + //GistId:b237846932dfcde42358bd0c887661a5 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setCompliance(PdfCompliance.PDF_17); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.ConversionToPdf17.pdf", saveOptions); + //ExEnd:ConversionToPdf17 + } + + @Test + public void downsamplingImages() throws Exception { + //ExStart:DownsamplingImages + //GistId:a5d65fc091d4330c8b66a17170524341 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // We can set a minimum threshold for downsampling. + // This value will prevent the second image in the input document from being downsampled. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.getDownsampleOptions().setResolution(36); + saveOptions.getDownsampleOptions().setResolutionThreshold(128); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.DownsamplingImages.pdf", saveOptions); + //ExEnd:DownsamplingImages + } + + @Test + public void outlineOptions() throws Exception { + //ExStart:OutlineOptions + //GistId:a5d65fc091d4330c8b66a17170524341 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.getOutlineOptions().setHeadingsOutlineLevels(3); + saveOptions.getOutlineOptions().setExpandedOutlineLevels(1); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.OutlineOptions.pdf", saveOptions); + //ExEnd:OutlineOptions + } + + @Test + public void customPropertiesExport() throws Exception { + //ExStart:CustomPropertiesExport + //GistId:a5d65fc091d4330c8b66a17170524341 + Document doc = new Document(); + doc.getCustomDocumentProperties().add("Company", "Aspose"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setCustomPropertiesExport(PdfCustomPropertiesExport.STANDARD); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.CustomPropertiesExport.pdf", saveOptions); + //ExEnd:CustomPropertiesExport + } + + @Test + public void exportDocumentStructure() throws Exception { + //ExStart:ExportDocumentStructure + //GistId:a5d65fc091d4330c8b66a17170524341 + Document doc = new Document(getMyDir() + "Paragraphs.docx"); + + // The file size will be increased and the structure will be visible in the "Content" navigation pane + // of Adobe Acrobat Pro, while editing the .pdf. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setExportDocumentStructure(true); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.ExportDocumentStructure.pdf", saveOptions); + //ExEnd:ExportDocumentStructure + } + + @Test + public void imageCompression() throws Exception { + //ExStart:ImageCompression + //GistId:a5d65fc091d4330c8b66a17170524341 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setImageCompression(PdfImageCompression.JPEG); + saveOptions.setPreserveFormFields(true); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.ImageCompression.pdf", saveOptions); + + PdfSaveOptions saveOptionsA2U = new PdfSaveOptions(); + saveOptionsA2U.setCompliance(PdfCompliance.PDF_A_2_U); + saveOptionsA2U.setImageCompression(PdfImageCompression.JPEG); + saveOptionsA2U.setJpegQuality(100); // Use JPEG compression at 50% quality to reduce file size. + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.ImageCompression_A2u.pdf", saveOptionsA2U); + //ExEnd:ImageCompression + } + + @Test + public void updateLastPrinted() throws Exception { + //ExStart:UpdateLastPrinted + //GistId:a6f7799aa265589fb56915bb1e401b05 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setUpdateLastPrintedProperty(true); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.UpdateLastPrinted.pdf", saveOptions); + //ExEnd:UpdateLastPrinted + } + + @Test + public void dml3DEffectsRendering() throws Exception { + //ExStart:Dml3DEffectsRendering + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setDml3DEffectsRenderingMode(Dml3DEffectsRenderingMode.ADVANCED); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.Dml3DEffectsRendering.pdf", saveOptions); + //ExEnd:Dml3DEffectsRendering + } + + @Test + public void interpolateImages() throws Exception { + //ExStart:SetImageInterpolation + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setInterpolateImages(true); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.InterpolateImages.pdf", saveOptions); + //ExEnd:SetImageInterpolation + } + + @Test + public void optimizeOutput() throws Exception { + //ExStart:OptimizeOutput + //GistId:b237846932dfcde42358bd0c887661a5 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setOptimizeOutput(true); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.OptimizeOutput.pdf", saveOptions); + //ExEnd:OptimizeOutput + } + + @Test + public void updateScreenTip() throws Exception { + //ExStart:UpdateScreenTip + //GistId:d92cef7ddb3b69b3f59a83b0c749326d + Document doc = new Document(getMyDir() + "Table of contents.docx"); + + // Get all hyperlink fields that are TOC links (SubAddress starts with "#_Toc"). + FieldCollection fields = doc.getRange().getFields(); + ArrayList tocHyperLinks = new ArrayList<>(); + + for (Field field : fields) { + if (field.getType() == FieldType.FIELD_HYPERLINK) { + FieldHyperlink hyperlink = (FieldHyperlink) field; + if (hyperlink.getSubAddress() != null && hyperlink.getSubAddress().startsWith("#_Toc")) { + tocHyperLinks.add(hyperlink); + } + } + } + + // Update ScreenTip for each TOC hyperlink + for (FieldHyperlink link : tocHyperLinks) { + link.setScreenTip(link.getDisplayResult()); + } + + // Configure PDF save options + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setCompliance(PdfCompliance.PDF_UA_1); + saveOptions.setDisplayDocTitle(true); + saveOptions.setExportDocumentStructure(true); + + // Configure outline options + saveOptions.getOutlineOptions().setHeadingsOutlineLevels(3); + saveOptions.getOutlineOptions().setCreateMissingOutlineLevels(true); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.UpdateScreenTip.pdf", saveOptions); + //ExEnd:UpdateScreenTip + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithRtfSaveOptions.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithRtfSaveOptions.java new file mode 100644 index 00000000..16f4e20b --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithRtfSaveOptions.java @@ -0,0 +1,22 @@ +package DocsExamples.File_formats_and_conversions.Save_options; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Document; +import com.aspose.words.RtfSaveOptions; +import org.testng.annotations.Test; + +@Test +public class WorkingWithRtfSaveOptions extends DocsExamplesBase { + @Test + public void savingImagesAsWmf() throws Exception { + //ExStart:SavingImagesAsWmf + //GistId:5b273ed7ba940f81b6a42a3a78609316 + Document doc = new Document(getMyDir() + "Document.docx"); + + RtfSaveOptions saveOptions = new RtfSaveOptions(); + saveOptions.setSaveImagesAsWmf(true); + + doc.save(getArtifactsDir() + "WorkingWithRtfSaveOptions.SavingImagesAsWmf.rtf", saveOptions); + //ExEnd:SavingImagesAsWmf + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithTxtSaveOptions.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithTxtSaveOptions.java new file mode 100644 index 00000000..e24ff473 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/Save_options/WorkingWithTxtSaveOptions.java @@ -0,0 +1,75 @@ +package DocsExamples.File_formats_and_conversions.Save_options; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.TxtSaveOptions; +import org.testng.annotations.Test; + +@Test +public class WorkingWithTxtSaveOptions extends DocsExamplesBase { + @Test + public void addBidiMarks() throws Exception { + //ExStart:AddBidiMarks + //GistId:c92d84644de8ee6e7148950debea90d6 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + builder.getParagraphFormat().setBidi(true); + builder.writeln("שלום עולם!"); + builder.writeln("مرحبا بالعالم!"); + + TxtSaveOptions saveOptions = new TxtSaveOptions(); + saveOptions.setAddBidiMarks(true); + + doc.save(getArtifactsDir() + "WorkingWithTxtSaveOptions.AddBidiMarks.txt", saveOptions); + //ExEnd:AddBidiMarks + } + + @Test + public void useTabForListIndentation() throws Exception { + //ExStart:UseTabForListIndentation + //GistId:c92d84644de8ee6e7148950debea90d6 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a list with three levels of indentation. + builder.getListFormat().applyNumberDefault(); + builder.writeln("Item 1"); + builder.getListFormat().listIndent(); + builder.writeln("Item 2"); + builder.getListFormat().listIndent(); + builder.write("Item 3"); + + TxtSaveOptions saveOptions = new TxtSaveOptions(); + saveOptions.getListIndentation().setCount(1); + saveOptions.getListIndentation().setCharacter('\t'); + + doc.save(getArtifactsDir() + "WorkingWithTxtSaveOptions.UseTabForListIndentation.txt", saveOptions); + //ExEnd:UseTabForListIndentation + } + + @Test + public void useSpaceForListIndentation() throws Exception { + //ExStart:UseSpaceForListIndentation + //GistId:c92d84644de8ee6e7148950debea90d6 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a list with three levels of indentation. + builder.getListFormat().applyNumberDefault(); + builder.writeln("Item 1"); + builder.getListFormat().listIndent(); + builder.writeln("Item 2"); + builder.getListFormat().listIndent(); + builder.write("Item 3"); + + TxtSaveOptions saveOptions = new TxtSaveOptions(); + saveOptions.getListIndentation().setCount(3); + saveOptions.getListIndentation().setCharacter(' '); + + doc.save(getArtifactsDir() + "WorkingWithTxtSaveOptions.UseSpaceForListIndentation.txt", saveOptions); + //ExEnd:UseSpaceForListIndentation + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/WorkingWithFileFormat.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/WorkingWithFileFormat.java new file mode 100644 index 00000000..d8c7e3a4 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/File_formats_and_conversions/WorkingWithFileFormat.java @@ -0,0 +1,140 @@ +package DocsExamples.File_formats_and_conversions; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.FileFormatInfo; +import com.aspose.words.FileFormatUtil; +import com.aspose.words.LoadFormat; +import org.apache.commons.io.FileUtils; +import org.testng.annotations.Test; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Test +public class WorkingWithFileFormat extends DocsExamplesBase { + @Test + public void detectFileFormat() throws Exception { + //ExStart:CheckFormatCompatibility + //GistId:13b31394822a30faeb5b68ad2b82fd75 + File supportedDir = new File(getArtifactsDir() + "Supported"); + File unknownDir = new File(getArtifactsDir() + "Unknown"); + File encryptedDir = new File(getArtifactsDir() + "Encrypted"); + File pre97Dir = new File(getArtifactsDir() + "Pre97"); + + // Create the directories if they do not already exist. + if (supportedDir.exists() == false) + supportedDir.mkdir(); + if (unknownDir.exists() == false) + unknownDir.mkdir(); + if (encryptedDir.exists() == false) + encryptedDir.mkdir(); + if (pre97Dir.exists() == false) + pre97Dir.mkdir(); + + //ExStart:GetFiles + //GistId:13b31394822a30faeb5b68ad2b82fd75 + Set listFiles = Stream.of(new File(getMyDir()).listFiles()) + .filter(file -> !file.getName().endsWith("Corrupted document.docx") && !Files.isDirectory(file.toPath())) + .map(File::getPath) + .collect(Collectors.toSet()); + //ExEnd:GetFiles + for (String fileName : listFiles) { + String nameOnly = Paths.get(fileName).getFileName().toString(); + + System.out.println(nameOnly); + FileFormatInfo info = FileFormatUtil.detectFileFormat(fileName); + + // Display the document type + switch (info.getLoadFormat()) { + case LoadFormat.DOC: + System.out.println("\tMicrosoft Word 97-2003 document."); + break; + case LoadFormat.DOT: + System.out.println("\tMicrosoft Word 97-2003 template."); + break; + case LoadFormat.DOCX: + System.out.println("\tOffice Open XML WordprocessingML Macro-Free Document."); + break; + case LoadFormat.DOCM: + System.out.println("\tOffice Open XML WordprocessingML Macro-Enabled Document."); + break; + case LoadFormat.DOTX: + System.out.println("\tOffice Open XML WordprocessingML Macro-Free Template."); + break; + case LoadFormat.DOTM: + System.out.println("\tOffice Open XML WordprocessingML Macro-Enabled Template."); + break; + case LoadFormat.FLAT_OPC: + System.out.println("\tFlat OPC document."); + break; + case LoadFormat.RTF: + System.out.println("\tRTF format."); + break; + case LoadFormat.WORD_ML: + System.out.println("\tMicrosoft Word 2003 WordprocessingML format."); + break; + case LoadFormat.HTML: + System.out.println("\tHTML format."); + break; + case LoadFormat.MHTML: + System.out.println("\tMHTML (Web archive) format."); + break; + case LoadFormat.ODT: + System.out.println("\tOpenDocument Text."); + break; + case LoadFormat.OTT: + System.out.println("\tOpenDocument Text Template."); + break; + case LoadFormat.DOC_PRE_WORD_60: + System.out.println("\tMS Word 6 or Word 95 format."); + break; + case LoadFormat.UNKNOWN: + System.out.println("\tUnknown format."); + break; + } + + if (info.isEncrypted()) { + System.out.println("\tAn encrypted document."); + FileUtils.copyFile(new File(fileName), new File(encryptedDir, nameOnly)); + } else { + switch (info.getLoadFormat()) { + case LoadFormat.DOC_PRE_WORD_60: + FileUtils.copyFile(new File(fileName), new File(pre97Dir, nameOnly)); + break; + case LoadFormat.UNKNOWN: + FileUtils.copyFile(new File(fileName), new File(unknownDir, nameOnly)); + break; + default: + FileUtils.copyFile(new File(fileName), new File(supportedDir, nameOnly)); + break; + } + } + } + //ExEnd:CheckFormatCompatibility + } + + @Test + public void detectDocumentSignatures() throws Exception { + //ExStart:DetectDocumentSignatures + //GistId:39ea49b7754e472caf41179f8b5970a0 + FileFormatInfo info = FileFormatUtil.detectFileFormat(getMyDir() + "Digitally signed.docx"); + + if (info.hasDigitalSignature()) { + System.out.println("Document {Path.GetFileName(MyDir + "); + } + //ExEnd:DetectDocumentSignatures + } + + @Test + public void verifyEncryptedDocument() throws Exception { + //ExStart:VerifyEncryptedDocument + //GistId:821ff3a1df0c75b2af641299b393fb60 + FileFormatInfo info = FileFormatUtil.detectFileFormat(getMyDir() + "Encrypted.docx"); + System.out.println(info.isEncrypted()); + //ExEnd:VerifyEncryptedDocument + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Getting_started/ApplyLicense.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Getting_started/ApplyLicense.java new file mode 100644 index 00000000..7371ff1e --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Getting_started/ApplyLicense.java @@ -0,0 +1,87 @@ +package DocsExamples.Getting_started; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Document; +import com.aspose.words.License; +import com.aspose.words.Metered; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.FileInputStream; + +@Test +public class ApplyLicense extends DocsExamplesBase { + @Test + public void applyLicenseFromFile() { + //ExStart:ApplyLicenseFromFile + //GistId:aae6b7a56c4792497614b4ee8f6f8eec + License license = new License(); + + // This line attempts to set a license from several locations relative to the executable and Aspose.Words.dll. + // You can also use the additional overload to load a license from a stream, this is useful, + // for instance, when the license is stored as an embedded resource. + try { + license.setLicense("Aspose.Words.lic"); + + System.out.println("License set successfully."); + } catch (Exception e) { + // We do not ship any license with this example, + // visit the Aspose site to obtain either a temporary or permanent license. + System.out.println("\nThere was an error setting the license: " + e.getMessage()); + } + //ExEnd:ApplyLicenseFromFile + } + + @Test + public void applyLicenseFromStream() { + //ExStart:ApplyLicenseFromStream + //GistId:aae6b7a56c4792497614b4ee8f6f8eec + License license = new License(); + + try { + license.setLicense(new FileInputStream(new File("Aspose.Words.lic"))); + + System.out.println("License set successfully."); + } catch (Exception e) { + // We do not ship any license with this example, + // visit the Aspose site to obtain either a temporary or permanent license. + System.out.println("\nThere was an error setting the license: " + e.getMessage()); + } + //ExEnd:ApplyLicenseFromStream + } + + @Test + public void applyLicenseFromResources() { + //ExStart:ApplyLicenseFromResources + //GistId:aae6b7a56c4792497614b4ee8f6f8eec + License license = new License(); + + try { + license.setLicense(ApplyLicense.class.getResourceAsStream("Aspose.Words.lic")); + + System.out.println("License set successfully."); + } catch (Exception e) { + // We do not ship any license with this example, + // visit the Aspose site to obtain either a temporary or permanent license. + System.out.println("\nThere was an error setting the license: " + e.getMessage()); + } + //ExEnd:ApplyLicenseFromResources + } + + @Test + public void applyMeteredLicense() { + //ExStart:ApplyMeteredLicense + //GistId:aae6b7a56c4792497614b4ee8f6f8eec + try { + Metered metered = new Metered(); + metered.setMeteredKey("*****", "*****"); + + Document doc = new Document(getMyDir() + "Document.docx"); + + System.out.println(doc.getPageCount()); + } catch (Exception e) { + System.out.println("\nThere was an error setting the license: " + e.getMessage()); + } + //ExEnd:ApplyMeteredLicense + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Getting_started/HelloWorld.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Getting_started/HelloWorld.java new file mode 100644 index 00000000..f5bb0b34 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Getting_started/HelloWorld.java @@ -0,0 +1,29 @@ +package DocsExamples.Getting_started; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.ImportFormatMode; +import org.testng.annotations.Test; + +@Test +public class HelloWorld extends DocsExamplesBase { + @Test + public void simpleHelloWorld() throws Exception { + //ExStart:HelloWorld + //GistId:4e111aa3d11a41428c8a0cadfc23b972 + Document docA = new Document(); + DocumentBuilder builder = new DocumentBuilder(docA); + + // Insert text to the document start. + builder.moveToDocumentStart(); + builder.write("First Hello World paragraph"); + + Document docB = new Document(getMyDir() + "Document.docx"); + // Add document B to the and of document A, preserving document B formatting. + docA.appendDocument(docB, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + docA.save(getArtifactsDir() + "HelloWorld.SimpleHelloWorld.pdf"); + //ExEnd:HelloWorld + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/LINQ_Reporting_Engine/BaseOperations.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/LINQ_Reporting_Engine/BaseOperations.java new file mode 100644 index 00000000..7bc98688 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/LINQ_Reporting_Engine/BaseOperations.java @@ -0,0 +1,95 @@ +package DocsExamples.LINQ_Reporting_Engine; + +import DocsExamples.DocsExamplesBase; +import TestData.Common; +import TestData.TestBuilders.ColorItemTestBuilder; +import TestData.TestClasses.ClientTestClass; +import TestData.TestClasses.ColorItemTestClass; +import TestData.TestClasses.ManagerTestClass; +import TestData.TestClasses.SenderTestClass; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.ReportingEngine; +import org.testng.annotations.Test; + +import java.awt.*; +import java.util.ArrayList; + +@Test +public class BaseOperations extends DocsExamplesBase { + @Test + public void helloWorld() throws Exception { + //ExStart:HelloWorld + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("<<[sender.getName()]>> says: <<[sender.getMessage()]>>"); + + SenderTestClass sender = new SenderTestClass(); + sender.setName("LINQ Reporting Engine"); + sender.setMessage("Hello World"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, sender, "sender"); + + doc.save(getArtifactsDir() + "ReportingEngine.HelloWorld.docx"); + //ExEnd:HelloWorld + } + + @Test + public void singleRow() throws Exception { + //ExStart:SingleRow + Document doc = new Document(getMyDir() + "Reporting engine template - Table row (Java).docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.getKnownTypes().add(ManagerTestClass.class); + engine.buildReport(doc, Common.getManagers(), "Managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.SingleRow.docx"); + //ExEnd:SingleRow + } + + @Test + public void commonMasterDetail() throws Exception { + //ExStart:CommonMasterDetail + Document doc = new Document(getMyDir() + "Reporting engine template - Common master detail (Java).docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.getKnownTypes().add(ManagerTestClass.class); + engine.buildReport(doc, Common.getManagers(), "managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.CommonMasterDetail.docx"); + //ExEnd:CommonMasterDetail + } + + @Test + public void conditionalBlocks() throws Exception { + //ExStart:ConditionalBlocks + Document doc = new Document(getMyDir() + "Reporting engine template - Table row conditional blocks (Java).docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.getKnownTypes().add(ClientTestClass.class); + engine.buildReport(doc, Common.getClients(), "clients"); + + doc.save(getArtifactsDir() + "ReportingEngine.ConditionalBlock.docx"); + //ExEnd:ConditionalBlocks + } + + @Test + public void settingBackgroundColor() throws Exception { + //ExStart:SettingBackgroundColor + Document doc = new Document(getMyDir() + "Reporting engine template - Background color (Java).docx"); + + ArrayList colors = new ArrayList<>(); + colors.add(new ColorItemTestBuilder().withColor("Black", Color.BLACK).build()); + colors.add(new ColorItemTestBuilder().withColor("Red", new Color((255), (0), (0))).build()); + colors.add(new ColorItemTestBuilder().withColor("Empty", null).build()); + + ReportingEngine engine = new ReportingEngine(); + engine.getKnownTypes().add(ColorItemTestClass.class); + engine.buildReport(doc, colors, "Colors"); + + doc.save(getArtifactsDir() + "ReportingEngine.BackColor.docx"); + //ExEnd:SettingBackgroundColor + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/LINQ_Reporting_Engine/BuildOptions.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/LINQ_Reporting_Engine/BuildOptions.java new file mode 100644 index 00000000..91462c75 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/LINQ_Reporting_Engine/BuildOptions.java @@ -0,0 +1,26 @@ +package DocsExamples.LINQ_Reporting_Engine; + +import DocsExamples.DocsExamplesBase; +import TestData.Common; +import TestData.TestClasses.ManagerTestClass; +import com.aspose.words.Document; +import com.aspose.words.ReportBuildOptions; +import com.aspose.words.ReportingEngine; +import org.testng.annotations.Test; + +@Test +public class BuildOptions extends DocsExamplesBase { + @Test + public void removeEmptyParagraphs() throws Exception { + //ExStart:RemoveEmptyParagraphs + Document doc = new Document(getMyDir() + "Reporting engine template - Remove empty paragraphs (Java).docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.setOptions(ReportBuildOptions.REMOVE_EMPTY_PARAGRAPHS); + engine.getKnownTypes().add(ManagerTestClass.class); + engine.buildReport(doc, Common.getManagers(), "Managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.RemoveEmptyParagraphs.docx"); + //ExEnd:RemoveEmptyParagraphs + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/LINQ_Reporting_Engine/Charts.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/LINQ_Reporting_Engine/Charts.java new file mode 100644 index 00000000..70e2d611 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/LINQ_Reporting_Engine/Charts.java @@ -0,0 +1,77 @@ +package DocsExamples.LINQ_Reporting_Engine; + +import DocsExamples.DocsExamplesBase; +import TestData.Common; +import TestData.TestClasses.ContractTestClass; +import TestData.TestClasses.ManagerTestClass; +import com.aspose.words.Document; +import com.aspose.words.ReportingEngine; +import org.testng.annotations.Test; + +@Test +public class Charts extends DocsExamplesBase { + @Test + public void createBubbleChart() throws Exception { + //ExStart:BubbleChart + Document doc = new Document(getMyDir() + "Reporting engine template - Bubble chart (Java).docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.getKnownTypes().add(ManagerTestClass.class); + engine.buildReport(doc, Common.getManagers(), "managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.CreateBubbleChart.docx"); + //ExEnd:BubbleChart + } + + @Test + public void setChartSeriesNameDynamically() throws Exception { + //ExStart:SetChartSeriesNameDynamically + Document doc = new Document(getMyDir() + "Reporting engine template - Chart (Java).docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.getKnownTypes().add(ManagerTestClass.class); + engine.buildReport(doc, Common.getManagers(), "managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.SetChartSeriesNameDynamically.docx"); + //ExEnd:SetChartSeriesNameDynamically + } + + @Test + public void chartWithFilteringGroupingOrdering() throws Exception { + //ExStart:ChartWithFilteringGroupingOrdering + Document doc = new Document(getMyDir() + "Reporting engine template - Chart with filtering (Java).docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.getKnownTypes().add(ContractTestClass.class); + engine.buildReport(doc, Common.getContracts(), "contracts"); + + doc.save(getArtifactsDir() + "ReportingEngine.ChartWithFilteringGroupingOrdering.docx"); + //ExEnd:ChartWithFilteringGroupingOrdering + } + + @Test + public void pieChart() throws Exception { + //ExStart:PieChart + Document doc = new Document(getMyDir() + "Reporting engine template - Pie chart (Java).docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.getKnownTypes().add(ManagerTestClass.class); + engine.buildReport(doc, Common.getManagers(), "managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.PieChart.docx"); + //ExEnd:PieChart + } + + @Test + public void scatterChart() throws Exception { + //ExStart:ScatterChart + Document doc = new Document(getMyDir() + "Reporting engine template - Scatter chart (Java).docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.getKnownTypes().add(ContractTestClass.class); + engine.buildReport(doc, Common.getContracts(), "contracts"); + + doc.save(getArtifactsDir() + "ReportingEngine.ScatterChart.docx"); + //ExEnd:ScatterChart + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/LINQ_Reporting_Engine/Lists.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/LINQ_Reporting_Engine/Lists.java new file mode 100644 index 00000000..a08f9b58 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/LINQ_Reporting_Engine/Lists.java @@ -0,0 +1,81 @@ +package DocsExamples.LINQ_Reporting_Engine; + +import DocsExamples.DocsExamplesBase; +import TestData.Common; +import TestData.TestClasses.ClientTestClass; +import TestData.TestClasses.ManagerTestClass; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.ReportingEngine; +import org.testng.annotations.Test; + +@Test +public class Lists extends DocsExamplesBase { + @Test + public void createBulletedList() throws Exception { + //ExStart:BulletedList + Document doc = new Document(getMyDir() + "Reporting engine template - Bulleted list (Java).docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.getKnownTypes().add(ClientTestClass.class); + engine.buildReport(doc, Common.getClients(), "clients"); + + doc.save(getArtifactsDir() + "ReportingEngine.CreateBulletedList.docx"); + //ExEnd:BulletedList + } + + @Test + public void inParagraphList() throws Exception { + //ExStart:InParagraphList + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("<><<[indexOf() !=0 ? ”, ”: ””]>><<[getName()]>><>"); + + ReportingEngine engine = new ReportingEngine(); + engine.getKnownTypes().add(ClientTestClass.class); + engine.buildReport(doc, Common.getClients(), "clients"); + + doc.save(getArtifactsDir() + "ReportingEngine.InParagraphList.docx"); + //ExEnd:InParagraphList + } + + @Test + public void inTableList() throws Exception { + //ExStart:InTableList + Document doc = new Document(getMyDir() + "Reporting engine template - Contextual object member access (Java).docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.getKnownTypes().add(ManagerTestClass.class); + engine.buildReport(doc, Common.getManagers(), "Managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.InTableList.docx"); + //ExEnd:InTableList + } + + @Test + public void multicoloredNumberedList() throws Exception { + //ExStart:MulticoloredNumberedList + Document doc = new Document(getMyDir() + "Reporting engine template - Multicolored numbered list (Java).docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.getKnownTypes().add(ClientTestClass.class); + engine.buildReport(doc, Common.getClients(), "clients"); + + doc.save(getArtifactsDir() + "ReportingEngine.MulticoloredNumberedList.doc"); + //ExEnd:MulticoloredNumberedList + } + + @Test + public void numberedList() throws Exception { + //ExStart:NumberedList + Document doc = new Document(getMyDir() + "Reporting engine template - Numbered list (Java).docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.getKnownTypes().add(ClientTestClass.class); + engine.buildReport(doc, Common.getClients(), "clients"); + + doc.save(getArtifactsDir() + "ReportingEngine.NumberedList.docx"); + //ExEnd:NumberedList + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/LINQ_Reporting_Engine/Tables.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/LINQ_Reporting_Engine/Tables.java new file mode 100644 index 00000000..11d220fe --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/LINQ_Reporting_Engine/Tables.java @@ -0,0 +1,52 @@ +package DocsExamples.LINQ_Reporting_Engine; + +import DocsExamples.DocsExamplesBase; +import TestData.Common; +import TestData.TestClasses.ContractTestClass; +import TestData.TestClasses.ManagerTestClass; +import com.aspose.words.Document; +import com.aspose.words.ReportingEngine; +import org.testng.annotations.Test; + +@Test +public class Tables extends DocsExamplesBase { + @Test + public void inTableAlternateContent() throws Exception { + //ExStart:InTableAlternateContent + Document doc = new Document(getMyDir() + "Reporting engine template - Total (Java).docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.getKnownTypes().add(ContractTestClass.class); + engine.buildReport(doc, Common.getContracts(), "Contracts"); + + doc.save(getArtifactsDir() + "ReportingEngine.InTableAlternateContent.docx"); + //ExEnd:InTableAlternateContent + } + + @Test + public void inTableMasterDetail() throws Exception { + //ExStart:InTableMasterDetail + Document doc = new Document(getMyDir() + "Reporting engine template - Nested data table (Java).docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.getKnownTypes().add(ManagerTestClass.class); + engine.getKnownTypes().add(ContractTestClass.class); + engine.buildReport(doc, Common.getManagers(), "Managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.InTableMasterDetail.docx"); + //ExEnd:InTableMasterDetail + } + + @Test + public void inTableWithFilteringGroupingSorting() throws Exception { + //ExStart:InTableWithFilteringGroupingSorting + Document doc = new Document(getMyDir() + "Reporting engine template - Table with filtering (Java).docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.getKnownTypes().add(ContractTestClass.class); + engine.buildReport(doc, Common.getContracts(), "contracts"); + + doc.save(getArtifactsDir() + "ReportingEngine.InTableWithFilteringGroupingSorting.docx"); + //ExEnd:InTableWithFilteringGroupingSorting + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Mail_Merge_And_Reporting/BaseOperations.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Mail_Merge_And_Reporting/BaseOperations.java new file mode 100644 index 00000000..e067a718 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Mail_Merge_And_Reporting/BaseOperations.java @@ -0,0 +1,343 @@ +package DocsExamples.Mail_Merge_And_Reporting; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.IMailMergeDataSource; +import com.aspose.words.MailMergeRegionInfo; +import com.aspose.words.net.System.Data.DataRow; +import com.aspose.words.net.System.Data.DataSet; +import com.aspose.words.net.System.Data.DataTable; +import com.aspose.words.ref.Ref; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.sql.*; +import java.text.MessageFormat; +import java.util.ArrayList; + +@Test +public class BaseOperations extends DocsExamplesBase { + @Test + public void simpleMailMerge() throws Exception { + //ExStart:ExecuteSimpleMailMerge + //GistId:341b834e9b6a84ac6885e907e0ea4229 + // Include the code for our template. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create Merge Fields. + builder.insertField(" MERGEFIELD CustomerName "); + builder.insertParagraph(); + builder.insertField(" MERGEFIELD Item "); + builder.insertParagraph(); + builder.insertField(" MERGEFIELD Quantity "); + + // Fill the fields in the document with user data. + doc.getMailMerge().execute(new String[]{"CustomerName", "Item", "Quantity"}, + new Object[]{"John Doe", "Hawaiian", "2"}); + + doc.save(getArtifactsDir() + "BaseOperations.SimpleMailMerge.docx"); + //ExEnd:ExecuteSimpleMailMerge + } + + @Test + public void useIfElseMustache() throws Exception { + //ExStart:UseIfElseMustache + //GistId:544788f602e697802e313a641cedb9b8 + Document doc = new Document(getMyDir() + "Mail merge destinations - Mustache syntax.docx"); + + doc.getMailMerge().setUseNonMergeFields(true); + doc.getMailMerge().execute(new String[]{"GENDER"}, new Object[]{"MALE"}); + + doc.save(getArtifactsDir() + "BaseOperations.IfElseMustache.docx"); + //ExEnd:UseIfElseMustache + } + + @Test + public void mustacheSyntaxUsingDataTable() throws Exception { + //ExStart:MustacheSyntaxUsingDataTable + //GistId:544788f602e697802e313a641cedb9b8 + Document doc = new Document(getMyDir() + "Mail merge destinations - Vendor.docx"); + + // Loop through each row and fill it with data. + DataTable dataTable = new DataTable("list"); + dataTable.getColumns().add("Number"); + for (int i = 0; i < 10; i++) { + DataRow dataRow = dataTable.newRow(); + dataTable.getRows().add(dataRow); + dataRow.set(0, "Number " + i); + } + + // Activate performing a mail merge operation into additional field types. + doc.getMailMerge().setUseNonMergeFields(true); + + doc.getMailMerge().executeWithRegions(dataTable); + + doc.save(getArtifactsDir() + "WorkingWithXmlData.MustacheSyntaxUsingDataTable.docx"); + //ExEnd:MustacheSyntaxUsingDataTable + } + + @Test + public void executeWithRegionsDataTable() throws Exception { + //ExStart:ExecuteWithRegionsDataTable + //GistId:de5e13f5d5bb7d8cb88da900b4f9ed8b + Document doc = new Document(getMyDir() + "Mail merge destinations - Orders.docx"); + + // Use custom data source implementation + int orderId = 10444; + + // Execute mail merge with Orders data + OrderDataSource orderData = getTestOrder(orderId); + doc.getMailMerge().executeWithRegions(orderData); + + // Execute mail merge with OrderDetails data (sorted by ExtendedPrice DESC) + OrderDetailsDataSource orderDetailsData = getTestOrderDetails(orderId, "ExtendedPrice DESC"); + doc.getMailMerge().executeWithRegions(orderDetailsData); + + doc.save(getArtifactsDir() + "MailMerge.ExecuteWithRegions.docx"); + //ExEnd:ExecuteWithRegionsDataTable + } + + //ExStart:ExecuteWithRegionsDataTableMethods + private OrderDataSource getTestOrder(int orderId) throws SQLException { + String sql = "SELECT * FROM AsposeWordOrders WHERE OrderId = " + orderId; + ResultSet rs = executeQuery(sql); + return new OrderDataSource(rs, "Orders"); + } + + private OrderDetailsDataSource getTestOrderDetails(int orderId, String sortOrder) throws SQLException { + String sql = "SELECT * FROM AsposeWordOrderDetails WHERE OrderId = " + orderId + + " ORDER BY " + (sortOrder != null ? sortOrder.replace(" DESC", " DESC") : "ProductID"); + ResultSet rs = executeQuery(sql); + return new OrderDetailsDataSource(rs, "OrderDetails"); + } + + /// + /// Utility function that creates a connection, command, executes the command and returns the result in a DataTable. + /// + private ResultSet executeQuery(String commandText) throws SQLException { + String connString = "jdbc:ucanaccess://" + getDatabaseDir() + "Northwind.accdb"; + Connection conn = DriverManager.getConnection(connString, "Admin", ""); + Statement stmt = conn.createStatement(); + return stmt.executeQuery(commandText); + } + //ExEnd:ExecuteWithRegionsDataTableMethods + + @Test + public void produceMultipleDocuments() throws Exception { + //ExStart:ProduceMultipleDocuments + //GistId:341b834e9b6a84ac6885e907e0ea4229 + Class.forName("net.ucanaccess.jdbc.UcanaccessDriver"); + String connString = "jdbc:ucanaccess://" + getDatabaseDir() + "Northwind.accdb"; + + Document doc = new Document(getMyDir() + "Mail merge destination - Suppliers.docx"); + + Connection connection = DriverManager.getConnection(connString, "Admin", ""); + + Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery("SELECT * FROM Customers"); + + DataTable dataTable = new DataTable(resultSet, "Customers"); + + // Perform a loop through each DataRow to iterate through the DataTable. Clone the template document + // instead of loading it from disk for better speed performance before the mail merge operation. + // You can load the template document from a file or stream but it is faster to load the document + // only once and then clone it in memory before each mail merge operation. + int counter = 1; + for (DataRow row : dataTable.getRows()) { + Document dstDoc = (Document) doc.deepClone(true); + + dstDoc.getMailMerge().execute(row); + + dstDoc.save(MessageFormat.format(getArtifactsDir() + "BaseOperations.ProduceMultipleDocuments_{0}.docx", counter++)); + } + + connection.close(); + //ExEnd:ProduceMultipleDocuments + } + + @Test + public void mailMergeWithRegions() throws Exception { + //ExStart:MailMergeWithRegions + //GistId:341b834e9b6a84ac6885e907e0ea4229 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // The start point of mail merge with regions the dataset. + builder.insertField(" MERGEFIELD TableStart:Customers"); + + // Data from rows of the "CustomerName" column of the "Customers" table will go in this MERGEFIELD. + builder.write("Orders for "); + builder.insertField(" MERGEFIELD CustomerName"); + builder.write(":"); + + // Create column headers. + builder.startTable(); + builder.insertCell(); + builder.write("Item"); + builder.insertCell(); + builder.write("Quantity"); + builder.endRow(); + + // We have a second data table called "Orders", which has a many-to-one relationship with "Customers" + // picking up rows with the same CustomerID value. + builder.insertCell(); + builder.insertField(" MERGEFIELD TableStart:Orders"); + builder.insertField(" MERGEFIELD ItemName"); + builder.insertCell(); + builder.insertField(" MERGEFIELD Quantity"); + builder.insertField(" MERGEFIELD TableEnd:Orders"); + builder.endTable(); + + // The end point of mail merge with regions. + builder.insertField(" MERGEFIELD TableEnd:Customers"); + + // Pass our dataset to perform mail merge with regions. + DataSet customersAndOrders = createDataSet(); + doc.getMailMerge().executeWithRegions(customersAndOrders); + + doc.save(getArtifactsDir() + "BaseOperations.MailMergeWithRegions.docx"); + //ExEnd:MailMergeWithRegions + } + + //ExStart:CreateDataSet + //GistId:341b834e9b6a84ac6885e907e0ea4229 + private DataSet createDataSet() { + // Create the customers table. + DataTable tableCustomers = new DataTable("Customers"); + tableCustomers.getColumns().add("CustomerID"); + tableCustomers.getColumns().add("CustomerName"); + tableCustomers.getRows().add(new Object[]{1, "John Doe"}); + tableCustomers.getRows().add(new Object[]{2, "Jane Doe"}); + + // Create the orders table. + DataTable tableOrders = new DataTable("Orders"); + tableOrders.getColumns().add("CustomerID"); + tableOrders.getColumns().add("ItemName"); + tableOrders.getColumns().add("Quantity"); + tableOrders.getRows().add(new Object[]{1, "Hawaiian", 2}); + tableOrders.getRows().add(new Object[]{2, "Pepperoni", 1}); + tableOrders.getRows().add(new Object[]{2, "Chicago", 1}); + + // Add both tables to a data set. + DataSet dataSet = new DataSet(); + dataSet.getTables().add(tableCustomers); + dataSet.getTables().add(tableOrders); + + // The "CustomerID" column, also the primary key of the customers table is the foreign key for the Orders table. + dataSet.getRelations().add(tableCustomers.getColumns().get("CustomerID"), tableOrders.getColumns().get("CustomerID")); + + return dataSet; + } + //ExEnd:CreateDataSet + + @Test + public void getRegionsByName() throws Exception { + //ExStart:GetRegionsByName + //GistId:b4bab1bf22437a86d8062e91cf154494 + Document doc = new Document(getMyDir() + "Mail merge regions.docx"); + + //ExStart:GetRegionsHierarchy + //GistId:b4bab1bf22437a86d8062e91cf154494 + MailMergeRegionInfo regionInfo = doc.getMailMerge().getRegionsHierarchy(); + //ExEnd:GetRegionsHierarchy + + ArrayList regions = doc.getMailMerge().getRegionsByName("Region1"); + Assert.assertEquals(1, doc.getMailMerge().getRegionsByName("Region1").size()); + for (MailMergeRegionInfo region : regions) Assert.assertEquals("Region1", region.getName()); + + regions = doc.getMailMerge().getRegionsByName("Region2"); + Assert.assertEquals(1, doc.getMailMerge().getRegionsByName("Region2").size()); + for (MailMergeRegionInfo region : regions) Assert.assertEquals("Region2", region.getName()); + + regions = doc.getMailMerge().getRegionsByName("NestedRegion1"); + Assert.assertEquals(2, doc.getMailMerge().getRegionsByName("NestedRegion1").size()); + for (MailMergeRegionInfo region : regions) Assert.assertEquals("NestedRegion1", region.getName()); + //ExEnd:GetRegionsByName + } +} + +// Custom data source for Orders. +class OrderDataSource implements com.aspose.words.IMailMergeDataSource { + private ResultSet resultSet; + private String tableName; + private boolean isFirst = true; + + public OrderDataSource(ResultSet rs, String tableName) { + this.resultSet = rs; + this.tableName = tableName; + } + + @Override + public String getTableName() { + return tableName; + } + + @Override + public boolean moveNext() throws Exception { + if (isFirst) { + isFirst = false; + return resultSet.next(); + } + return resultSet.next(); + } + + @Override + public boolean getValue(String fieldName, Ref fieldValue) { + try { + Object value = resultSet.getObject(fieldName); + fieldValue.set(value); + return true; + } catch (SQLException e) { + return false; + } + } + + @Override + public com.aspose.words.IMailMergeDataSource getChildDataSource(String tableName) { + return null; + } +} + +// Custom data source for OrderDetails. +class OrderDetailsDataSource implements IMailMergeDataSource { + private ResultSet resultSet; + private String tableName; + private boolean isFirst = true; + + public OrderDetailsDataSource(ResultSet rs, String tableName) { + this.resultSet = rs; + this.tableName = tableName; + } + + @Override + public String getTableName() { + return tableName; + } + + @Override + public boolean moveNext() throws Exception { + if (isFirst) { + isFirst = false; + return resultSet.next(); + } + return resultSet.next(); + } + + @Override + public boolean getValue(String fieldName, Ref fieldValue) { + try { + Object value = resultSet.getObject(fieldName); + fieldValue.set(value); + return true; + } catch (SQLException e) { + return false; + } + } + + @Override + public com.aspose.words.IMailMergeDataSource getChildDataSource(String tableName) { + return null; + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Mail_Merge_And_Reporting/Complex_examples_and_helpers/ApplyCustomLogicToEmptyRegions.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Mail_Merge_And_Reporting/Complex_examples_and_helpers/ApplyCustomLogicToEmptyRegions.java new file mode 100644 index 00000000..46317f38 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Mail_Merge_And_Reporting/Complex_examples_and_helpers/ApplyCustomLogicToEmptyRegions.java @@ -0,0 +1,289 @@ +package DocsExamples.Mail_Merge_And_Reporting.Complex_examples_and_helpers; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import com.aspose.words.net.System.Data.DataRelation; +import com.aspose.words.net.System.Data.DataSet; +import com.aspose.words.net.System.Data.DataTable; +import org.testng.annotations.Test; + +import java.util.ArrayList; + +@Test +public class ApplyCustomLogicToEmptyRegions extends DocsExamplesBase { + @Test + public void executeWithRegionsNestedCustom() throws Exception { + //ExStart:ApplyCustomLogicToEmptyRegions + Document doc = new Document(getMyDir() + "Mail merge destination - Northwind suppliers.docx"); + + // Create a data source which has some data missing. + // This will result in some regions are merged, and some remain after executing mail merge + DataSet data = getDataSource(); + + // Ensure that we have not set the removal of any unused regions as we will handle them manually. + // We achieve this by removing the RemoveUnusedRegions flag from the cleanup options using the AND and NOT bitwise operators. + doc.getMailMerge().setCleanupOptions(doc.getMailMerge().getCleanupOptions() & ~MailMergeCleanupOptions.REMOVE_UNUSED_REGIONS); + + doc.getMailMerge().executeWithRegions(data); + + // Regions without data and not merged will remain in the document. + Document mergedDoc = doc.deepClone(); //ExSkip + + // Apply logic to each unused region left in the document. + executeCustomLogicOnEmptyRegions(doc, new EmptyRegionsHandler()); + + doc.save(getArtifactsDir() + "MailMerge.ExecuteWithRegionsNestedCustom_1.docx"); + + doc = mergedDoc.deepClone(); + + // Apply different logic to unused regions this time. + executeCustomLogicOnEmptyRegions(doc, new EmptyRegionsHandlerMergeTable()); + + doc.save(getArtifactsDir() + "MailMerge.ExecuteWithRegionsNestedCustom_2.docx"); + //ExEnd:ApplyCustomLogicToEmptyRegions + + doc = mergedDoc.deepClone(); + + //ExStart:ContactDetails + ArrayList regions = new ArrayList(); + regions.add("ContactDetails"); + + // Only handle the ContactDetails region in our handler. + executeCustomLogicOnEmptyRegions(doc, new EmptyRegionsHandler(), regions); + //ExEnd:ContactDetails + + doc.save(getArtifactsDir() + "MailMerge.ExecuteWithRegionsNestedCustom_3.docx"); + } + + //ExStart:CreateDataSourceFromDocumentRegions + /// + /// Returns a DataSet object containing a DataTable for the unmerged regions in the specified document. + /// If regionsList is null all regions found within the document are included. If an List instance is present, + /// the only regions specified in the list found in the document are added. + /// + private DataSet createDataSourceFromDocumentRegions(Document doc, ArrayList regionsList) throws Exception { + final String TABLE_START_MARKER = "TableStart:"; + DataSet dataSet = new DataSet(); + String tableName = null; + + for (String fieldName : doc.getMailMerge().getFieldNames()) { + if (fieldName.contains(TABLE_START_MARKER)) { + tableName = fieldName.substring(TABLE_START_MARKER.length()); + } else if (tableName != null) { + // Add the table name as a new DataTable if it doesn't already exist in the DataSet. + if (dataSet.getTables().get(tableName) == null) { + DataTable table = new DataTable(tableName); + table.getColumns().add(fieldName); + + // We only need to add the first field for the handler to be called for the region's fields. + if (regionsList == null || regionsList.contains(tableName)) { + table.getRows().add("FirstField"); + } + + dataSet.getTables().add(table); + } + + tableName = null; + } + } + + return dataSet; + } + //ExEnd:CreateDataSourceFromDocumentRegions + + //ExStart:ExecuteCustomLogicOnEmptyRegions + /// + /// Applies logic defined in the passed handler class to all unused regions in the document. + /// This allows controlling how unused regions are handled in the document manually. + /// + /// The document containing unused regions. + /// The handler which implements the IFieldMergingCallback interface + /// and defines the logic to be applied to each unmerged region. + private void executeCustomLogicOnEmptyRegions(Document doc, IFieldMergingCallback handler) throws Exception { + // Pass null to handle all regions found in the document. + executeCustomLogicOnEmptyRegions(doc, handler, null); + } + + /// + /// Applies logic defined in the passed handler class to specific unused regions in the document as defined in regionsList. + /// This allows controlling how unused regions are handled in the document manually. + /// + /// The document containing unused regions. + /// The handler which implements the IFieldMergingCallback interface and defines + /// the logic to be applied to each unmerged region. + /// A list of strings corresponding to the region names that are to be handled + /// by the supplied handler class. Other regions encountered will not be handled and are removed automatically. + private void executeCustomLogicOnEmptyRegions(Document doc, IFieldMergingCallback handler, + ArrayList regionsList) throws Exception { + // Certain regions can be skipped from applying logic to by not adding + // the table name inside the CreateEmptyDataSource method. Enable this cleanup option, so any regions + // which are not handled by the user's logic are removed automatically. + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_UNUSED_REGIONS); + + // Set the user's handler, which is called for each unmerged region. + doc.getMailMerge().setFieldMergingCallback(handler); + + // Execute mail merge using the dummy dataset. The dummy data source contains each unmerged region's table names + // in the document (excluding ones that the user may have specified to be skipped). + // This will allow the handler to be called for each field in the unmerged regions. + doc.getMailMerge().executeWithRegions(createDataSourceFromDocumentRegions(doc, regionsList)); + } + //ExEnd:ExecuteCustomLogicOnEmptyRegions + + //ExStart:EmptyRegionsHandler + private static class EmptyRegionsHandler implements IFieldMergingCallback { + /// + /// Called for each field belonging to an unmerged region in the document. + /// + public void fieldMerging(FieldMergingArgs args) { + // Change the text of each field of the ContactDetails region individually. + if ("ContactDetails".equals(args.getTableName())) { + // Set the text of the field based off the field name. + if ("Name".equals(args.getFieldName())) + args.setText("(No details found)"); + else if ("Number".equals(args.getFieldName())) + args.setText("(N/A)"); + } + + // Remove the entire table of the Suppliers region. Also, check if the previous paragraph + // before the table is a heading paragraph and remove that. + if ("Suppliers".equals(args.getTableName())) { + Table table = (Table) args.getField().getStart().getAncestor(NodeType.TABLE); + + // Check if the table has been removed from the document already. + if (table.getParentNode() != null) { + // Try to find the paragraph which precedes the table before the table is removed from the document. + if (table.getPreviousSibling() != null && table.getPreviousSibling().getNodeType() == NodeType.PARAGRAPH) { + Paragraph previousPara = (Paragraph) table.getPreviousSibling(); + if (isHeadingParagraph(previousPara)) + previousPara.remove(); + } + + table.remove(); + } + } + } + + /// + /// Returns true if the paragraph uses any Heading style, e.g., Heading 1 to Heading 9. + /// + private boolean isHeadingParagraph(Paragraph para) { + return para.getParagraphFormat().getStyleIdentifier() >= StyleIdentifier.HEADING_1 && + para.getParagraphFormat().getStyleIdentifier() <= StyleIdentifier.HEADING_9; + } + + public void imageFieldMerging(ImageFieldMergingArgs args) { + // Do nothing. + } + } + //ExEnd:EmptyRegionsHandler + + public static class EmptyRegionsHandlerMergeTable implements IFieldMergingCallback { + /// + /// Called for each field belonging to an unmerged region in the document. + /// + public void fieldMerging(FieldMergingArgs args) throws Exception { + //ExStart:RemoveExtraParagraphs + // Store the parent paragraph of the current field for easy access. + Paragraph parentParagraph = args.getField().getStart().getParentParagraph(); + + // Define the logic to be used when the ContactDetails region is encountered. + // The region is removed and replaced with a single line of text stating that there are no records. + if ("ContactDetails".equals(args.getTableName())) { + // Called for the first field encountered in a region. This can be used to execute logic on the first field + // in the region without needing to hard code the field name. Often the base logic is applied to the first field and + // different logic for other fields. The rest of the fields in the region will have a null FieldValue. + if ("FirstField".equals((String) args.getFieldValue())) { + FindReplaceOptions options = new FindReplaceOptions(); + // Remove the "Name:" tag from the start of the paragraph. + parentParagraph.getRange().replace("Name:", "", options); + // Set the text of the first field to display a message stating that there are no records. + args.setText("No records to display"); + } else { + // We have already inserted our message in the paragraph belonging to the first field. + // The other paragraphs in the region will remain, so we want to remove these. + // A check is added to ensure that the paragraph has not been removed, + // which may happen if more than one field is included in a paragraph. + if (parentParagraph.getParentNode() != null) + parentParagraph.remove(); + } + } + //ExEnd:RemoveExtraParagraphs + + //ExStart:MergeAllCells + // Replace the unused region in the table with a "no records" message and merge all cells into one. + if ("Suppliers".equals(args.getTableName())) { + if ("FirstField".equals((String) args.getFieldValue())) { + // We will use the first paragraph to display our message. Make it centered within the table. + // The other fields in other cells within the table will be merged and won't be displayed, + // so we don't need to do anything else with them. + parentParagraph.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + args.setText("No records to display"); + } + + // Merge the cells of the table. + Cell cell = (Cell) parentParagraph.getAncestor(NodeType.CELL); + if (cell != null) { + cell.getCellFormat().setHorizontalMerge(cell.isFirstCell() ? CellMerge.FIRST : CellMerge.PREVIOUS); + } + } + //ExEnd:MergeAllCells + } + + public void imageFieldMerging(ImageFieldMergingArgs args) { + // Do Nothing + } + } + + /// + /// Returns the data used to merge the document. + /// This dataset purposely contains only rows for the StoreDetails region and only a select few for the child region. + /// + private DataSet getDataSource() { + DataSet data = new DataSet(); + DataTable storeDetails = new DataTable("StoreDetails"); + DataTable contactDetails = new DataTable("ContactDetails"); + + contactDetails.getColumns().add("ID"); + contactDetails.getColumns().add("Name"); + contactDetails.getColumns().add("Number"); + + storeDetails.getColumns().add("ID"); + storeDetails.getColumns().add("Name"); + storeDetails.getColumns().add("Address"); + storeDetails.getColumns().add("City"); + storeDetails.getColumns().add("Country"); + + storeDetails.getRows().add("0", "Hungry Coyote Import Store", "2732 Baker Blvd", "Eugene", "USA"); + storeDetails.getRows().add("1", "Great Lakes Food Market", "City Center Plaza, 516 Main St.", "San Francisco", + "USA"); + + contactDetails.getRows().add("0", "Thomas Hardy", "(206) 555-9857 ext 237"); + contactDetails.getRows().add("0", "Elizabeth Brown", "(206) 555-9857 ext 764"); + + data.getTables().add(storeDetails); + data.getTables().add(contactDetails); + + data.getRelations().add(storeDetails.getColumns().get("ID"), contactDetails.getColumns().get("ID")); + + return data; + } + + private DataTable orderTable = null; + private DataTable itemTable = null; + + private void disableForeignKeyConstraints(DataSet dataSet) { + //ExStart:DisableForeignKeyConstraints + //GistId:c68048adceb3bda6a1511c7d6f5ebf7b + dataSet.getRelations().add(new DataRelation("OrderToItem", orderTable.getColumns().get("Order_Id"), + itemTable.getColumns().get("Order_Id"), false)); + //ExEnd:DisableForeignKeyConstraints + } + + private void createDataRelation(DataSet dataSet) { + //ExStart:CreateDataRelation + dataSet.getRelations().add(new DataRelation("OrderToItem", orderTable.getColumns().get("Order_Id"), + itemTable.getColumns().get("Order_Id"))); + //ExEnd:CreateDataRelation + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Mail_Merge_And_Reporting/Complex_examples_and_helpers/CreateMailMergeTemplate.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Mail_Merge_And_Reporting/Complex_examples_and_helpers/CreateMailMergeTemplate.java new file mode 100644 index 00000000..ef502ba8 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Mail_Merge_And_Reporting/Complex_examples_and_helpers/CreateMailMergeTemplate.java @@ -0,0 +1,61 @@ +package DocsExamples.Mail_Merge_And_Reporting.Complex_examples_and_helpers; + +import com.aspose.words.BreakType; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.TextFormFieldType; +import org.testng.annotations.Test; + +@Test +public class CreateMailMergeTemplate { + + public Document template() throws Exception { + //ExStart:CreateMailMergeTemplate + //GistId:0a1baaa127443b485cc692c8d98ee353 + DocumentBuilder builder = new DocumentBuilder(); + + // Insert a text input field the unique name of this field is "Hello", the other parameters define + // what type of FormField it is, the format of the text, the field result and the maximum text length (0 = no limit). + builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", "Hello", 0); + builder.insertField("MERGEFIELD CustomerFirstName \\* MERGEFORMAT"); + + builder.insertTextInput("TextInput1", TextFormFieldType.REGULAR, "", " ", 0); + builder.insertField("MERGEFIELD CustomerLastName \\* MERGEFORMAT"); + + builder.insertTextInput("TextInput1", TextFormFieldType.REGULAR, "", " , ", 0); + + // Inserts a paragraph break into the document. + builder.insertParagraph(); + + // Insert mail body. + builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", "Thanks for purchasing our ", 0); + builder.insertField("MERGEFIELD ProductName \\* MERGEFORMAT"); + + builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", ", please download your Invoice at ", + 0); + builder.insertField("MERGEFIELD InvoiceURL \\* MERGEFORMAT"); + + builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", + ". If you have any questions please call ", 0); + builder.insertField("MERGEFIELD Supportphone \\* MERGEFORMAT"); + + builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", ", or email us at ", 0); + builder.insertField("MERGEFIELD SupportEmail \\* MERGEFORMAT"); + + builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", ".", 0); + + builder.insertParagraph(); + + // Insert mail ending. + builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", "Best regards,", 0); + builder.insertBreak(BreakType.LINE_BREAK); + builder.insertField("MERGEFIELD EmployeeFullname \\* MERGEFORMAT"); + + builder.insertTextInput("TextInput1", TextFormFieldType.REGULAR, "", " ", 0); + builder.insertField("MERGEFIELD EmployeeDepartment \\* MERGEFORMAT"); + + return builder.getDocument(); + //ExEnd:CreateMailMergeTemplate + } +} + diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Mail_Merge_And_Reporting/Complex_examples_and_helpers/NestedMailMergeCustom.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Mail_Merge_And_Reporting/Complex_examples_and_helpers/NestedMailMergeCustom.java new file mode 100644 index 00000000..13658c68 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Mail_Merge_And_Reporting/Complex_examples_and_helpers/NestedMailMergeCustom.java @@ -0,0 +1,250 @@ +package DocsExamples.Mail_Merge_And_Reporting.Complex_examples_and_helpers; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.IMailMergeDataSource; +import com.aspose.words.ref.Ref; +import org.testng.annotations.Test; + +import java.util.ArrayList; + +@Test +public class NestedMailMergeCustom extends DocsExamplesBase { + @Test + public void customMailMerge() throws Exception { + //ExStart:NestedMailMergeCustom + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertField(" MERGEFIELD TableStart:Customer"); + + builder.write("Full name:\t"); + builder.insertField(" MERGEFIELD FullName "); + builder.write("\nAddress:\t"); + builder.insertField(" MERGEFIELD Address "); + builder.write("\nOrders:\n"); + + builder.insertField(" MERGEFIELD TableStart:Order"); + + builder.write("\tItem name:\t"); + builder.insertField(" MERGEFIELD Name "); + builder.write("\n\tQuantity:\t"); + builder.insertField(" MERGEFIELD Quantity "); + builder.insertParagraph(); + + builder.insertField(" MERGEFIELD TableEnd:Order"); + + builder.insertField(" MERGEFIELD TableEnd:Customer"); + + ArrayList customers = new ArrayList(); + { + customers.add(new Customer("Thomas Hardy", "120 Hanover Sq., London")); + customers.add(new Customer("Paolo Accorti", "Via Monte Bianco 34, Torino")); + } + + customers.get(0).getOrders().add(new Order("Rugby World Cup Cap", 2)); + customers.get(0).getOrders().add(new Order("Rugby World Cup Ball", 1)); + customers.get(1).getOrders().add(new Order("Rugby World Cup Guide", 1)); + + // To be able to mail merge from your data source, + // it must be wrapped into an object that implements the IMailMergeDataSource interface. + CustomerMailMergeDataSource customersDataSource = new CustomerMailMergeDataSource(customers); + + doc.getMailMerge().executeWithRegions(customersDataSource); + + doc.save(getArtifactsDir() + "NestedMailMergeCustom.CustomMailMerge.docx"); + //ExEnd:NestedMailMergeCustom + } + + /// + /// An example of a "data entity" class in your application. + /// + public static class Customer { + public Customer(String aFullName, String anAddress) { + setFullName(aFullName); + setAddress(anAddress); + setOrders(new ArrayList<>()); + } + + public String getFullName() { + return mFullName; + } + + public void setFullName(String value) { + mFullName = value; + } + + public String getAddress() { + return mAddress; + } + + public void setAddress(String value) { + mAddress = value; + } + + public ArrayList getOrders() { + return mOrders; + } + + public void setOrders(ArrayList value) { + mOrders = value; + } + + private ArrayList mOrders; + private String mAddress; + private String mFullName; + } + + /// + /// An example of a child "data entity" class in your application. + /// + public static class Order { + public Order(String oName, int oQuantity) { + setName(oName); + setQuantity(oQuantity); + } + + public String getName() { + return mName; + } + + public void setName(String value) { + mName = value; + } + + public int getQuantity() { + return mQuantity; + } + + public void setQuantity(int value) { + mQuantity = value; + } + + private int mQuantity; + private String mName; + } + + /// + /// A custom mail merge data source that you implement to allow Aspose.Words + /// to mail merge data from your Customer objects into Microsoft Word documents. + /// + public static class CustomerMailMergeDataSource implements IMailMergeDataSource { + public CustomerMailMergeDataSource(ArrayList customers) { + mCustomers = customers; + + // When the data source is initialized, it must be positioned before the first record. + mRecordIndex = -1; + } + + /// + /// Aspose.Words calls this method to get a value for every data field. + /// + public boolean getValue(String fieldName, Ref fieldValue) { + switch (fieldName) { + case "FullName": + fieldValue.set(mCustomers.get(mRecordIndex).getFullName()); + return true; + case "Address": + fieldValue.set(mCustomers.get(mRecordIndex).getAddress()); + return true; + case "Order": + fieldValue.set(mCustomers.get(mRecordIndex).getOrders()); + return true; + default: + fieldValue.set(null); + return false; + } + } + + @Override + public String getTableName() { + return "Customer"; + } + + /// + /// A standard implementation for moving to a next record in a collection. + /// + public boolean moveNext() { + if (!IsEof()) + mRecordIndex++; + + return !IsEof(); + } + + //ExStart:GetChildDataSource + //GistId:c68048adceb3bda6a1511c7d6f5ebf7b + public IMailMergeDataSource getChildDataSource(String tableName) { + switch (tableName) { + // Get the child collection to merge it with the region provided with tableName variable. + case "Order": + return new OrderMailMergeDataSource(mCustomers.get(mRecordIndex).getOrders()); + default: + return null; + } + } + //ExEnd:GetChildDataSource + + private boolean IsEof() { + return mRecordIndex >= mCustomers.size(); + } + + private ArrayList mCustomers; + private int mRecordIndex; + } + + public static class OrderMailMergeDataSource implements IMailMergeDataSource { + public OrderMailMergeDataSource(ArrayList orders) { + mOrders = orders; + + // When the data source is initialized, it must be positioned before the first record. + mRecordIndex = -1; + } + + /// + /// Aspose.Words calls this method to get a value for every data field. + /// + public boolean getValue(String fieldName, /*out*/Ref fieldValue) { + switch (fieldName) { + case "Name": + fieldValue.set(mOrders.get(mRecordIndex).getName()); + return true; + case "Quantity": + fieldValue.set(mOrders.get(mRecordIndex).getQuantity()); + return true; + default: + fieldValue.set(null); + return false; + } + } + + /// + /// The name of the data source. Used by Aspose.Words only when executing mail merge with repeatable regions. + /// + @Override + public String getTableName() { + return "Order"; + } + + /// + /// A standard implementation for moving to a next record in a collection. + /// + public boolean moveNext() { + if (!isEof()) + mRecordIndex++; + + return !isEof(); + } + + public IMailMergeDataSource getChildDataSource(String tableName) { + // Return null because we haven't any child elements for this sort of object. + return null; + } + + private boolean isEof() { + return mRecordIndex >= mOrders.size(); + } + + private ArrayList mOrders; + private int mRecordIndex; + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Mail_Merge_And_Reporting/WorkingWithCleanupOptions.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Mail_Merge_And_Reporting/WorkingWithCleanupOptions.java new file mode 100644 index 00000000..60da73ec --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Mail_Merge_And_Reporting/WorkingWithCleanupOptions.java @@ -0,0 +1,137 @@ +package DocsExamples.Mail_Merge_And_Reporting; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.FieldMergeField; +import com.aspose.words.MailMergeCleanupOptions; +import com.aspose.words.net.System.Data.DataSet; +import org.testng.annotations.Test; + +@Test +public class WorkingWithCleanupOptions extends DocsExamplesBase { + @Test + public void removeRowsFromTable() throws Exception { + //ExStart:RemoveRowsFromTable + Document doc = new Document(getMyDir() + "Mail merge destination - Northwind suppliers.docx"); + + DataSet data = new DataSet(); + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_UNUSED_REGIONS | + MailMergeCleanupOptions.REMOVE_EMPTY_TABLE_ROWS); + + doc.getMailMerge().setMergeDuplicateRegions(true); + doc.getMailMerge().executeWithRegions(data); + + doc.save(getArtifactsDir() + "WorkingWithCleanupOptions.RemoveRowsFromTable.docx"); + //ExEnd:RemoveRowsFromTable + } + + @Test + public void cleanupParagraphsWithPunctuationMarks() throws Exception { + //ExStart:CleanupParagraphsWithPunctuationMarks + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + FieldMergeField mergeFieldOption1 = (FieldMergeField) builder.insertField("MERGEFIELD", "Option_1"); + mergeFieldOption1.setFieldName("Option_1"); + + // Here is the complete list of cleanable punctuation marks: ! , . : ; ? ¡ ¿. + builder.write(" ? "); + + FieldMergeField mergeFieldOption2 = (FieldMergeField) builder.insertField("MERGEFIELD", "Option_2"); + mergeFieldOption2.setFieldName("Option_2"); + + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_EMPTY_PARAGRAPHS); + // The option's default value is true, which means that the behavior was changed to mimic MS Word. + // If you rely on the old behavior can revert it by setting the option to false. + doc.getMailMerge().setCleanupParagraphsWithPunctuationMarks(true); + + doc.getMailMerge().execute(new String[]{"Option_1", "Option_2"}, new Object[]{null, null}); + + doc.save(getArtifactsDir() + "WorkingWithCleanupOptions.CleanupParagraphsWithPunctuationMarks.docx"); + //ExEnd:CleanupParagraphsWithPunctuationMarks + } + + @Test + public void removeUnmergedRegions() throws Exception { + //ExStart:RemoveUnmergedRegions + //GistId:f39874821cb317d245a769c9ce346fea + Document doc = new Document(getMyDir() + "Mail merge destination - Northwind suppliers.docx"); + + DataSet data = new DataSet(); + //ExStart:MailMergeCleanupOptions + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_UNUSED_REGIONS); + // doc.MailMerge.CleanupOptions = MailMergeCleanupOptions.RemoveContainingFields; + // doc.MailMerge.CleanupOptions |= MailMergeCleanupOptions.RemoveStaticFields; + // doc.MailMerge.CleanupOptions |= MailMergeCleanupOptions.RemoveEmptyParagraphs; + // doc.MailMerge.CleanupOptions |= MailMergeCleanupOptions.RemoveUnusedFields; + //ExEnd:MailMergeCleanupOptions + + // Merge the data with the document by executing mail merge which will have no effect as there is no data. + // However the regions found in the document will be removed automatically as they are unused. + doc.getMailMerge().executeWithRegions(data); + + doc.save(getArtifactsDir() + "WorkingWithCleanupOptions.RemoveUnmergedRegions.docx"); + //ExEnd:RemoveUnmergedRegions + } + + @Test + public void removeEmptyParagraphs() throws Exception { + //ExStart:RemoveEmptyParagraphs + //GistId:f39874821cb317d245a769c9ce346fea + Document doc = new Document(getMyDir() + "Table with fields.docx"); + + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_EMPTY_PARAGRAPHS); + + doc.getMailMerge().execute(new String[]{"FullName", "Company", "Address", "Address2", "City"}, + new Object[]{"James Bond", "MI5 Headquarters", "Milbank", "", "London"}); + + doc.save(getArtifactsDir() + "WorkingWithCleanupOptions.RemoveEmptyParagraphs.docx"); + //ExEnd:RemoveEmptyParagraphs + } + + @Test + public void removeUnusedFields() throws Exception { + //ExStart:RemoveUnusedFields + //GistId:f39874821cb317d245a769c9ce346fea + Document doc = new Document(getMyDir() + "Table with fields.docx"); + + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_UNUSED_FIELDS); + + doc.getMailMerge().execute(new String[]{"FullName", "Company", "Address", "Address2", "City"}, + new Object[]{"James Bond", "MI5 Headquarters", "Milbank", "", "London"}); + + doc.save(getArtifactsDir() + "WorkingWithCleanupOptions.RemoveUnusedFields.docx"); + //ExEnd:RemoveUnusedFields + } + + @Test + public void removeContainingFields() throws Exception { + //ExStart:RemoveContainingFields + //GistId:f39874821cb317d245a769c9ce346fea + Document doc = new Document(getMyDir() + "Table with fields.docx"); + + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_CONTAINING_FIELDS); + + doc.getMailMerge().execute(new String[]{"FullName", "Company", "Address", "Address2", "City"}, + new Object[]{"James Bond", "MI5 Headquarters", "Milbank", "", "London"}); + + doc.save(getArtifactsDir() + "WorkingWithCleanupOptions.RemoveContainingFields.docx"); + //ExEnd:RemoveContainingFields + } + + @Test + public void removeEmptyTableRows() throws Exception { + //ExStart:RemoveEmptyTableRows + //GistId:f39874821cb317d245a769c9ce346fea + Document doc = new Document(getMyDir() + "Table with fields.docx"); + + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_EMPTY_TABLE_ROWS); + + doc.getMailMerge().execute(new String[]{"FullName", "Company", "Address", "Address2", "City"}, + new Object[]{"James Bond", "MI5 Headquarters", "Milbank", "", "London"}); + + doc.save(getArtifactsDir() + "WorkingWithCleanupOptions.RemoveEmptyTableRows.docx"); + //ExEnd:RemoveEmptyTableRows + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Mail_Merge_And_Reporting/WorkingWithFields.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Mail_Merge_And_Reporting/WorkingWithFields.java new file mode 100644 index 00000000..bfa7c92c --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Mail_Merge_And_Reporting/WorkingWithFields.java @@ -0,0 +1,393 @@ +package DocsExamples.Mail_Merge_And_Reporting; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Shape; +import com.aspose.words.*; +import com.aspose.words.net.System.Data.DataRow; +import com.aspose.words.net.System.Data.DataTable; +import com.aspose.words.net.System.Data.DataTableReader; +import com.aspose.words.net.System.Data.IDataReader; +import com.aspose.words.ref.Ref; +import org.testng.annotations.Test; + +import java.awt.*; +import java.io.ByteArrayInputStream; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.Statement; +import java.text.MessageFormat; + +@Test +public class WorkingWithFields extends DocsExamplesBase { + @Test + public void mailMergeFormFields() throws Exception { + //ExStart:MailMergeFormFields + //GistId:0a1baaa127443b485cc692c8d98ee353 + Document doc = new Document(getMyDir() + "Mail merge destinations - Fax.docx"); + + // Setup mail merge event handler to do the custom work. + doc.getMailMerge().setFieldMergingCallback(new HandleMergeField()); + // Trim trailing and leading whitespaces mail merge values. + doc.getMailMerge().setTrimWhitespaces(false); + + String[] fieldNames = { + "RecipientName", "SenderName", "FaxNumber", "PhoneNumber", + "Subject", "Body", "Urgent", "ForReview", "PleaseComment" + }; + + Object[] fieldValues = { + "Josh", "Jenny", "123456789", "", "Hello", + "HTML Body Test message 1", true, false, true + }; + + doc.getMailMerge().execute(fieldNames, fieldValues); + + doc.save(getArtifactsDir() + "WorkingWithFields.MailMergeFormFields.docx"); + //ExEnd:MailMergeFormFields + } + + //ExStart:HandleMergeField + //GistId:8a66b5cea0f9f8b862c092c9b93ccb3c + private static class HandleMergeField implements IFieldMergingCallback { + /// + /// This handler is called for every mail merge field found in the document, + /// for every record found in the data source. + /// + public void fieldMerging(FieldMergingArgs e) throws Exception { + if (mBuilder == null) + mBuilder = new DocumentBuilder(e.getDocument()); + + // We decided that we want all boolean values to be output as check box form fields. + if (e.getFieldValue() instanceof /*boolean*/ Boolean) { + // Move the "cursor" to the current merge field. + mBuilder.moveToMergeField(e.getFieldName()); + + String checkBoxName = MessageFormat.format("{0}{1}", e.getFieldName(), e.getRecordIndex()); + + mBuilder.insertCheckBox(checkBoxName, (Boolean) e.getFieldValue(), 0); + + return; + } + + switch (e.getFieldName()) { + case "Body": + mBuilder.moveToMergeField(e.getFieldName()); + mBuilder.insertHtml((String) e.getFieldValue()); + break; + case "Subject": { + mBuilder.moveToMergeField(e.getFieldName()); + String textInputName = MessageFormat.format("{0}{1}", e.getFieldName(), e.getRecordIndex()); + mBuilder.insertTextInput(textInputName, TextFormFieldType.REGULAR, "", (String) e.getFieldValue(), 0); + break; + } + } + } + + //ExStart:ImageFieldMerging + //GistId:0a1baaa127443b485cc692c8d98ee353 + public void imageFieldMerging(ImageFieldMergingArgs args) { + args.setImageFileName("Image.png"); + args.getImageWidth().setValue(200.0); + args.setImageHeight(new MergeFieldImageDimension(200.0, MergeFieldImageDimensionUnit.PERCENT)); + } + //ExEnd:ImageFieldMerging + + private DocumentBuilder mBuilder; + } + //ExEnd:HandleMergeField + + @Test + public void mailMergeImageField() throws Exception { + //ExStart:MailMergeImageField + //GistId:8a66b5cea0f9f8b862c092c9b93ccb3c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("{{#foreach example}}"); + builder.writeln("{{Image(126pt;126pt):stempel}}"); + builder.writeln("{{/foreach example}}"); + + doc.getMailMerge().setUseNonMergeFields(true); + doc.getMailMerge().setTrimWhitespaces(true); + doc.getMailMerge().setUseWholeParagraphAsRegion(false); + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_EMPTY_TABLE_ROWS + | MailMergeCleanupOptions.REMOVE_CONTAINING_FIELDS + | MailMergeCleanupOptions.REMOVE_UNUSED_REGIONS + | MailMergeCleanupOptions.REMOVE_UNUSED_FIELDS); + + doc.getMailMerge().setFieldMergingCallback(new ImageFieldMergingHandler()); + doc.getMailMerge().executeWithRegions(new DataSourceRoot()); + + doc.save(getArtifactsDir() + "WorkingWithFields.MailMergeImageField.docx"); + //ExEnd:MailMergeImageField + } + + //ExStart:ImageFieldMergingHandler + //GistId:8a66b5cea0f9f8b862c092c9b93ccb3c + private static class ImageFieldMergingHandler implements IFieldMergingCallback { + public void fieldMerging(FieldMergingArgs args) { + // Implementation is not required. + } + + public void imageFieldMerging(ImageFieldMergingArgs args) throws Exception { + Shape shape = new Shape(args.getDocument(), ShapeType.IMAGE); + shape.setWidth(126.0); + shape.setHeight(126.0); + shape.setWrapType(WrapType.SQUARE); + + shape.getImageData().setImage(getMyDir() + "Mail merge image.png"); + + args.setShape(shape); + } + } + //ExEnd:ImageFieldMergingHandler + + //ExStart:DataSourceRoot + //GistId:8a66b5cea0f9f8b862c092c9b93ccb3c + public static class DataSourceRoot implements IMailMergeDataSourceRoot { + public IMailMergeDataSource getDataSource(String s) { + return new DataSource(); + } + + private static class DataSource implements IMailMergeDataSource { + private boolean next = true; + + private String tableName() { + return "example"; + } + + @Override + public String getTableName() { + return tableName(); + } + + public boolean moveNext() { + boolean result = next; + next = false; + return result; + } + + public IMailMergeDataSource getChildDataSource(String s) { + return null; + } + + public boolean getValue(String fieldName, Ref fieldValue) { + fieldValue.set(null); + return false; + } + } + } + //ExEnd:DataSourceRoot + + @Test + public void mailMergeAndConditionalField() throws Exception { + //ExStart:MailMergeAndConditionalField + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a MERGEFIELD nested inside an IF field. + // Since the IF field statement is false, the result of the inner MERGEFIELD will not be displayed, + // and the MERGEFIELD will not receive any data during a mail merge. + FieldIf fieldIf = (FieldIf) builder.insertField(" IF 1 = 2 "); + builder.moveTo(fieldIf.getSeparator()); + builder.insertField(" MERGEFIELD FullName "); + + // We can still count MERGEFIELDs inside false-statement IF fields if we set this flag to true. + doc.getMailMerge().setUnconditionalMergeFieldsAndRegions(true); + + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FullName"); + dataTable.getRows().add("James Bond"); + + doc.getMailMerge().execute(dataTable); + + // The result will not be visible in the document because the IF field is false, + // but the inner MERGEFIELD did indeed receive data. + doc.save(getArtifactsDir() + "WorkingWithFields.MailMergeAndConditionalField.docx"); + //ExEnd:MailMergeAndConditionalField + } + + @Test + public void mailMergeImageFromBlob() throws Exception { + //ExStart:MailMergeImageFromBlob + //GistId:8a66b5cea0f9f8b862c092c9b93ccb3c + Document doc = new Document(getMyDir() + "Mail merge destination - Northwind employees.docx"); + + doc.getMailMerge().setFieldMergingCallback(new HandleMergeImageFieldFromBlob()); + + Class.forName("net.ucanaccess.jdbc.UcanaccessDriver"); + String connString = "jdbc:ucanaccess://" + getDatabaseDir() + "Northwind.accdb"; + + Connection connection = DriverManager.getConnection(connString, "Admin", ""); + + Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery("SELECT * FROM Employees"); + + DataTable dataTable = new DataTable(resultSet, "Employees"); + IDataReader dataReader = new DataTableReader(dataTable); + + doc.getMailMerge().executeWithRegions(dataReader, "Employees"); + + connection.close(); + + doc.save(getArtifactsDir() + "WorkingWithFields.MailMergeImageFromBlob.docx"); + //ExEnd:MailMergeImageFromBlob + } + + //ExStart:HandleMergeImageFieldFromBlob + //GistId:8a66b5cea0f9f8b862c092c9b93ccb3c + public static class HandleMergeImageFieldFromBlob implements IFieldMergingCallback { + public void fieldMerging(FieldMergingArgs args) { + // Do nothing. + } + + /// + /// This is called when mail merge engine encounters Image:XXX merge field in the document. + /// You have a chance to return an Image object, file name, or a stream that contains the image. + /// + public void imageFieldMerging(ImageFieldMergingArgs e) throws Exception { + // The field value is a byte array, just cast it and create a stream on it. + ByteArrayInputStream imageStream = new ByteArrayInputStream((byte[]) e.getFieldValue()); + // Now the mail merge engine will retrieve the image from the stream. + e.setImageStream(imageStream); + } + } + //ExEnd:HandleMergeImageFieldFromBlob + + @Test + public void handleMailMergeSwitches() throws Exception { + Document doc = new Document(getMyDir() + "Field sample - MERGEFIELD.docx"); + + doc.getMailMerge().setFieldMergingCallback(new MailMergeSwitches()); + + String html = "" + + "

          Hello world!

          " + + ""; + doc.getMailMerge().execute(new String[]{"htmlField1"}, new Object[]{ html }); + + doc.save(getArtifactsDir() + "WorkingWithFields.HandleMailMergeSwitches.docx"); + } + + //ExStart:HandleMailMergeSwitches + public static class MailMergeSwitches implements IFieldMergingCallback { + public void fieldMerging(FieldMergingArgs e) throws Exception { + if (e.getFieldName().startsWith("HTML")) { + if (e.getField().getFieldCode().contains("\\b")) { + FieldMergeField field = e.getField(); + + DocumentBuilder builder = new DocumentBuilder(e.getDocument()); + builder.moveToMergeField(e.getDocumentFieldName(), true, false); + builder.write(field.getTextBefore()); + builder.insertHtml(e.getFieldValue().toString()); + + e.setText(""); + } + } + } + + public void imageFieldMerging(ImageFieldMergingArgs args) { + } + } + //ExEnd:HandleMailMergeSwitches + + @Test + public void alternatingRows() throws Exception { + //ExStart:MailMergeAlternatingRows + Document doc = new Document(getMyDir() + "Mail merge destination - Northwind suppliers.docx"); + + doc.getMailMerge().setFieldMergingCallback(new HandleMergeFieldAlternatingRows()); + + DataTable dataTable = getSuppliersDataTable(); + doc.getMailMerge().executeWithRegions(dataTable); + + doc.save(getArtifactsDir() + "WorkingWithFields.AlternatingRows.doc"); + //ExEnd:MailMergeAlternatingRows + } + + //ExStart:HandleMergeFieldAlternatingRows + private static class HandleMergeFieldAlternatingRows implements IFieldMergingCallback { + /// + /// Called for every merge field encountered in the document. + /// We can either return some data to the mail merge engine or do something else with the document. + /// In this case we modify cell formatting. + /// + public void fieldMerging(FieldMergingArgs e) { + if (mBuilder == null) + mBuilder = new DocumentBuilder(e.getDocument()); + + if ("CompanyName".equals(e.getFieldName())) { + // Select the color depending on whether the row number is even or odd. + Color rowColor = isOdd(mRowIdx) + ? new Color((213), (227), (235)) + : new Color((242), (242), (242)); + + // There is no way to set cell properties for the whole row at the moment, so we have to iterate over all cells in the row. + for (int colIdx = 0; colIdx < 4; colIdx++) { + mBuilder.moveToCell(0, mRowIdx, colIdx, 0); + mBuilder.getCellFormat().getShading().setBackgroundPatternColor(rowColor); + } + + mRowIdx++; + } + } + + public void imageFieldMerging(ImageFieldMergingArgs args) { + // Do nothing. + } + + private DocumentBuilder mBuilder; + private int mRowIdx; + } + + /// + /// Returns true if the value is odd; false if the value is even. + /// + private static boolean isOdd(int value) { + return (value / 2 * 2) == value; + } + + /// + /// Create DataTable and fill it with data. + /// In real life this DataTable should be filled from a database. + /// + private DataTable getSuppliersDataTable() { + DataTable dataTable = new DataTable("Suppliers"); + + dataTable.getColumns().add("CompanyName"); + dataTable.getColumns().add("ContactName"); + + for (int i = 0; i < 10; i++) { + DataRow datarow = dataTable.newRow(); + + dataTable.getRows().add(datarow); + datarow.set(0, "Company " + i); + datarow.set(1, "Contact " + i); + } + + return dataTable; + } + //ExEnd:HandleMergeFieldAlternatingRows + + @Test + public void fieldNext() throws Exception { + //ExStart:FieldNext + //GistId:b4bab1bf22437a86d8062e91cf154494 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Use NextIf field. A NEXTIF field has the same function as a NEXT field, + // but it skips to the next row only if a statement constructed by the following 3 properties is true. + FieldNextIf fieldNextIf = (FieldNextIf) builder.insertField(FieldType.FIELD_NEXT_IF, true); + + // Or use SkipIf field. + FieldSkipIf fieldSkipIf = (FieldSkipIf) builder.insertField(FieldType.FIELD_SKIP_IF, true); + + fieldNextIf.setLeftExpression("5"); + fieldNextIf.setRightExpression("2 + 3"); + fieldNextIf.setComparisonOperator("="); + + doc.save(getArtifactsDir() + "WorkingWithFields.FieldNext.docx"); + //ExEnd:FieldNext + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Mail_Merge_And_Reporting/WorkingWithXmlData.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Mail_Merge_And_Reporting/WorkingWithXmlData.java new file mode 100644 index 00000000..ef3f153d --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Mail_Merge_And_Reporting/WorkingWithXmlData.java @@ -0,0 +1,387 @@ +package DocsExamples.Mail_Merge_And_Reporting; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Document; +import com.aspose.words.IMailMergeDataSource; +import com.aspose.words.net.System.Data.DataSet; +import com.aspose.words.ref.Ref; +import org.testng.annotations.Test; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +@Test +public class WorkingWithXmlData extends DocsExamplesBase { + @Test + public void xmlMailMerge() throws Exception { + //ExStart:XmlMailMerge + //GistId:0441f68c5209fec25c47d1a0a203fbb0 + DataSet customersDs = new DataSet(); + customersDs.readXml(getMyDir() + "Mail merge data - Customers.xml"); + + Document doc = new Document(getMyDir() + "Mail merge destinations - Registration complete.docx"); + doc.getMailMerge().execute(customersDs.getTables().get("Customer")); + + doc.save(getArtifactsDir() + "WorkingWithXmlData.XmlMailMerge.docx"); + //ExEnd:XmlMailMerge + } + + @Test + public void nestedMailMerge() throws Exception { + //ExStart:NestedMailMerge + //GistId:c68048adceb3bda6a1511c7d6f5ebf7b + // The Datatable.TableNames and the DataSet.Relations are defined implicitly by .NET through ReadXml. + DataSet pizzaDs = new DataSet(); + pizzaDs.readXml(getMyDir() + "Mail merge data - Orders.xml"); + + Document doc = new Document(getMyDir() + "Mail merge destinations - Invoice.docx"); + // Trim trailing and leading whitespaces mail merge values. + doc.getMailMerge().setTrimWhitespaces(false); + doc.getMailMerge().executeWithRegions(pizzaDs); + + doc.save(getArtifactsDir() + "WorkingWithXmlData.NestedMailMerge.docx"); + //ExEnd:NestedMailMerge + } + + @Test + public void mustacheSyntaxUsingDataSet() throws Exception { + //ExStart:MailMergeUsingMustacheSyntax + DataSet ds = new DataSet(); + ds.readXml(getMyDir() + "Mail merge data - Vendors.xml"); + + Document doc = new Document(getMyDir() + "Mail merge destinations - Vendor.docx"); + doc.getMailMerge().setUseNonMergeFields(true); + doc.getMailMerge().executeWithRegions(ds); + + doc.save(getArtifactsDir() + "WorkingWithXmlData.MustacheSyntaxUsingDataSet.docx"); + //ExEnd:MailMergeUsingMustacheSyntax + } + + @Test + public void linqToXmlMailMerge() throws Exception { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + org.w3c.dom.Document xmlDoc = builder.parse(getMyDir() + "Mail merge data - Purchase order.xml"); + + XPath xpath = XPathFactory.newInstance().newXPath(); + + //ExStart:LinqToXmlMailMergeOrderItems + NodeList itemNodes = (NodeList) xpath.compile("//Item").evaluate(xmlDoc, XPathConstants.NODESET); + ArrayList orderItems = new ArrayList(); + + for (int i = 0; i < itemNodes.getLength(); i++) { + Element item = (Element) itemNodes.item(i); + OrderItem orderItem = new OrderItem(); + + orderItem.setPartNumber(item.getAttribute("PartNumber")); + orderItem.setProductName(getElementText(item, "ProductName")); + orderItem.setQuantity(getElementText(item, "Quantity")); + orderItem.setUSPrice(getElementText(item, "USPrice")); + orderItem.setComment(getElementText(item, "Comment")); + orderItem.setShipDate(getElementText(item, "ShipDate")); + + orderItems.add(orderItem); + } + //ExEnd:LinqToXmlMailMergeOrderItems + + //ExStart:LinqToXmlQueryForDeliveryAddress + NodeList addressNodes = (NodeList) xpath.compile("//Address[@Type='Shipping']").evaluate(xmlDoc, XPathConstants.NODESET); + ArrayList deliveryAddresses = new ArrayList(); + + for (int i = 0; i < addressNodes.getLength(); i++) { + Element address = (Element) addressNodes.item(i); + DeliveryAddress deliveryAddress = new DeliveryAddress(); + + deliveryAddress.setName(getElementText(address, "Name")); + deliveryAddress.setCountry(getElementText(address, "Country")); + deliveryAddress.setZip(getElementText(address, "Zip")); + deliveryAddress.setState(getElementText(address, "State")); + deliveryAddress.setCity(getElementText(address, "City")); + deliveryAddress.setStreet(getElementText(address, "Street")); + + deliveryAddresses.add(deliveryAddress); + } + //ExEnd:LinqToXmlQueryForDeliveryAddress + + MyMailMergeDataSource orderItemsDataSource = new MyMailMergeDataSource(orderItems, "Items"); + MyMailMergeDataSource deliveryDataSource = new MyMailMergeDataSource(deliveryAddresses); + + //ExStart:LinqToXmlMailMerge + Document doc = new Document(getMyDir() + "Mail merge destinations - LINQ.docx"); + + // Fill the document with data from our data sources using mail merge regions for populating the order items + // table is required because it allows the region to be repeated in the document for each order item. + doc.getMailMerge().executeWithRegions(orderItemsDataSource); + + doc.getMailMerge().execute(deliveryDataSource); + + doc.save(getArtifactsDir() + "WorkingWithXmlData.LinqToXmlMailMerge.docx"); + //ExEnd:LinqToXmlMailMerge + } + + private String getElementText(Element parent, String tagName) { + NodeList nodeList = parent.getElementsByTagName(tagName); + if (nodeList.getLength() > 0) { + Node node = nodeList.item(0); + return node.getTextContent(); + } + return ""; + } + + public static class OrderItem { + private String partNumber; + private String productName; + private String quantity; + private String usPrice; + private String comment; + private String shipDate; + + public String getPartNumber() { + return partNumber; + } + + public void setPartNumber(String partNumber) { + this.partNumber = partNumber; + } + + public String getProductName() { + return productName; + } + + public void setProductName(String productName) { + this.productName = productName; + } + + public String getQuantity() { + return quantity; + } + + public void setQuantity(String quantity) { + this.quantity = quantity; + } + + public String getUSPrice() { + return usPrice; + } + + public void setUSPrice(String usPrice) { + this.usPrice = usPrice; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + + public String getShipDate() { + return shipDate; + } + + public void setShipDate(String shipDate) { + this.shipDate = shipDate; + } + } + + public static class DeliveryAddress { + private String name; + private String country; + private String zip; + private String state; + private String city; + private String street; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public String getZip() { + return zip; + } + + public void setZip(String zip) { + this.zip = zip; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + } + + /// + /// Aspose.Words do not accept LINQ queries as input for mail merge directly + /// but provide a generic mechanism that allows mail merges from any data source. + /// + /// This class is a simple implementation of the Aspose.Words custom mail merge data source + /// interface that accepts a LINQ query (any IEnumerable object). + /// Aspose.Words call this class during the mail merge to retrieve the data. + /// + //ExStart:MyMailMergeDataSource + public static class MyMailMergeDataSource implements IMailMergeDataSource + //ExEnd:MyMailMergeDataSource + { + private Iterator iterator; + private Object current; + private String tableName; + private ArrayList data; + + /// + /// Creates a new instance of a custom mail merge data source. + /// + /// Data returned from a LINQ query. + //ExStart:MyMailMergeDataSourceConstructor + public MyMailMergeDataSource(Collection data) { + this.data = new ArrayList<>(data); + this.iterator = this.data.iterator(); + this.tableName = ""; + } + //ExEnd:MyMailMergeDataSourceConstructor + + /// + /// Creates a new instance of a custom mail merge data source, for mail merge with regions. + /// + /// Data returned from a LINQ query. + /// The name of the data source is only used when you perform a mail merge with regions. + /// If you prefer to use the simple mail merge, then use the constructor with one parameter. + //ExStart:MyMailMergeDataSourceConstructorWithDataTable + public MyMailMergeDataSource(Collection data, String tableName) { + this.data = new ArrayList<>(data); + this.iterator = this.data.iterator(); + this.tableName = tableName != null ? tableName : ""; + } + //ExEnd:MyMailMergeDataSourceConstructorWithDataTable + + /// + /// Aspose.Words call this method to get a value for every data field. + /// + /// This is a simple "generic" implementation of a data source that can work over any IEnumerable collection. + /// This implementation assumes that the merge field name in the document matches the public property's name + /// on the object in the collection and uses reflection to get the property's value. + /// + //ExStart:MyMailMergeDataSourceGetValue + @Override + public boolean getValue(String fieldName, Ref fieldValue) { + if (current == null) { + fieldValue.set(null); + return false; + } + + try { + Class currentClass = current.getClass(); + + // Try to get property using getter method (Java bean convention) + String getterName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); + Method getter = null; + + try { + getter = currentClass.getMethod(getterName); + } catch (NoSuchMethodException e) { + // Try with "is" prefix for boolean properties + getterName = "is" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); + try { + getter = currentClass.getMethod(getterName); + } catch (NoSuchMethodException e2) { + // Try direct field access + try { + Field field = currentClass.getDeclaredField(fieldName); + field.setAccessible(true); + fieldValue.set(field.get(current)); + return true; + } catch (Exception e3) { + fieldValue.set(null); + return false; + } + } + } + + if (getter != null) { + Object value = getter.invoke(current); + fieldValue.set(value); + return true; + } + + } catch (Exception e) { + fieldValue.set(null); + return false; + } + + fieldValue.set(null); + return false; + } + //ExEnd:MyMailMergeDataSourceGetValue + + /// + /// Moves to the next record in the collection. + /// + //ExStart:MyMailMergeDataSourceMoveNext + @Override + public boolean moveNext() { + if (iterator.hasNext()) { + current = iterator.next(); + return true; + } + return false; + } + //ExEnd:MyMailMergeDataSourceMoveNext + + /// + /// The name of the data source. Used by Aspose.Words only when executing mail merge with repeatable regions. + /// + //ExStart:MyMailMergeDataSourceTableName + @Override + public String getTableName() { + return tableName; + } + //ExEnd:MyMailMergeDataSourceTableName + + @Override + public IMailMergeDataSource getChildDataSource(String tableName) { + return null; + } + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/ExtractContent.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/ExtractContent.java new file mode 100644 index 00000000..054a3c92 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/ExtractContent.java @@ -0,0 +1,393 @@ +package DocsExamples.Programming_with_documents.Contents_management; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collections; + +@Test +public class ExtractContent extends DocsExamplesBase { + @Test + public void extractContentBetweenBlockLevelNodes() throws Exception { + //ExStart:ExtractContentBetweenBlockLevelNodes + //GistId:1975a35426bcd195a2e7c61d20a1580c + Document doc = new Document(getMyDir() + "Extract content.docx"); + + Paragraph startPara = (Paragraph) doc.getLastSection().getChild(NodeType.PARAGRAPH, 2, true); + Table endTable = (Table) doc.getLastSection().getChild(NodeType.TABLE, 0, true); + // Extract the content between these nodes in the document. Include these markers in the extraction. + ArrayList extractedNodes = ExtractContentHelper.extractContent(startPara, endTable, true, false); + + // Let's reverse the array to make inserting the content back into the document easier. + Collections.reverse(extractedNodes); + for (Node extractedNode : extractedNodes) + // Insert the last node from the reversed list. + endTable.getParentNode().insertAfter(extractedNode, endTable); + + doc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenBlockLevelNodes.docx"); + //ExEnd:ExtractContentBetweenBlockLevelNodes + } + + @Test + public void extractContentBetweenBookmark() throws Exception { + //ExStart:ExtractContentBetweenBookmark + //GistId:1975a35426bcd195a2e7c61d20a1580c + Document doc = new Document(getMyDir() + "Extract content.docx"); + + Bookmark bookmark = doc.getRange().getBookmarks().get("Bookmark1"); + BookmarkStart bookmarkStart = bookmark.getBookmarkStart(); + BookmarkEnd bookmarkEnd = bookmark.getBookmarkEnd(); + + // Firstly, extract the content between these nodes, including the bookmark. + ArrayList extractedNodesInclusive = ExtractContentHelper.extractContent(bookmarkStart, bookmarkEnd, true, true); + + Document dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodesInclusive); + dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenBookmark.IncludingBookmark.docx"); + + // Secondly, extract the content between these nodes this time without including the bookmark. + ArrayList extractedNodesExclusive = ExtractContentHelper.extractContent(bookmarkStart, bookmarkEnd, false, true); + + dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodesExclusive); + dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenBookmark.WithoutBookmark.docx"); + //ExEnd:ExtractContentBetweenBookmark + } + + @Test + public void extractContentBetweenCommentRange() throws Exception { + //ExStart:ExtractContentBetweenCommentRange + //GistId:1975a35426bcd195a2e7c61d20a1580c + Document doc = new Document(getMyDir() + "Extract content.docx"); + + CommentRangeStart commentStart = (CommentRangeStart) doc.getChild(NodeType.COMMENT_RANGE_START, 0, true); + CommentRangeEnd commentEnd = (CommentRangeEnd) doc.getChild(NodeType.COMMENT_RANGE_END, 0, true); + + // Firstly, extract the content between these nodes including the comment as well. + ArrayList extractedNodesInclusive = ExtractContentHelper.extractContent(commentStart, commentEnd, true, true); + + Document dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodesInclusive); + dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenCommentRange.IncludingComment.docx"); + + // Secondly, extract the content between these nodes without the comment. + ArrayList extractedNodesExclusive = ExtractContentHelper.extractContent(commentStart, commentEnd, false, true); + + dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodesExclusive); + dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenCommentRange.WithoutComment.docx"); + //ExEnd:ExtractContentBetweenCommentRange + } + + @Test + public void extractContentBetweenParagraphs() throws Exception { + //ExStart:ExtractContentBetweenParagraphs + //GistId:1975a35426bcd195a2e7c61d20a1580c + Document doc = new Document(getMyDir() + "Extract content.docx"); + + Paragraph startPara = (Paragraph) doc.getFirstSection().getBody().getChild(NodeType.PARAGRAPH, 6, true); + Paragraph endPara = (Paragraph) doc.getFirstSection().getBody().getChild(NodeType.PARAGRAPH, 10, true); + // Extract the content between these nodes in the document. Include these markers in the extraction. + ArrayList extractedNodes = ExtractContentHelper.extractContent(startPara, endPara, true, true); + + Document dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodes); + dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenParagraphs.docx"); + //ExEnd:ExtractContentBetweenParagraphs + } + + @Test + public void extractContentBetweenParagraphStyles() throws Exception { + //ExStart:ExtractContentBetweenParagraphStyles + //GistId:1975a35426bcd195a2e7c61d20a1580c + Document doc = new Document(getMyDir() + "Extract content.docx"); + + // Gather a list of the paragraphs using the respective heading styles. + ArrayList parasStyleHeading1 = paragraphsByStyleName(doc, "Heading 1"); + ArrayList parasStyleHeading3 = paragraphsByStyleName(doc, "Heading 3"); + + // Use the first instance of the paragraphs with those styles. + Node startPara = parasStyleHeading1.get(0); + Node endPara = parasStyleHeading3.get(0); + + // Extract the content between these nodes in the document. Don't include these markers in the extraction. + ArrayList extractedNodes = ExtractContentHelper.extractContent(startPara, endPara, false, true); + + Document dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodes); + dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenParagraphStyles.docx"); + //ExEnd:ExtractContentBetweenParagraphStyles + } + + //ExStart:ParagraphsByStyleName + //GistId:1975a35426bcd195a2e7c61d20a1580c + public static ArrayList paragraphsByStyleName(Document doc, String styleName) { + // Create an array to collect paragraphs of the specified style. + ArrayList paragraphsWithStyle = new ArrayList<>(); + + NodeCollection paragraphs = doc.getChildNodes(NodeType.PARAGRAPH, true); + + // Look through all paragraphs to find those with the specified style. + for (Paragraph paragraph : (Iterable) paragraphs) { + if (paragraph.getParagraphFormat().getStyle().getName().equals(styleName)) + paragraphsWithStyle.add(paragraph); + } + + return paragraphsWithStyle; + } + //ExEnd:ParagraphsByStyleName + + @Test + public void extractContentBetweenRuns() throws Exception { + //ExStart:ExtractContentBetweenRuns + //GistId:1975a35426bcd195a2e7c61d20a1580c + Document doc = new Document(getMyDir() + "Extract content.docx"); + + Paragraph para = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 7, true); + Run startRun = para.getRuns().get(1); + Run endRun = para.getRuns().get(4); + + // Extract the content between these nodes in the document. Include these markers in the extraction. + ArrayList extractedNodes = ExtractContentHelper.extractContent(startRun, endRun, true, false); + for (Node extractedNode : extractedNodes) + System.out.println(extractedNode.toString(SaveFormat.TEXT)); + //ExEnd:ExtractContentBetweenRuns + } + + @Test + public void extractContentUsingDocumentVisitor() throws Exception { + //ExStart:ExtractContentUsingDocumentVisitor + //GistId:1975a35426bcd195a2e7c61d20a1580c + Document doc = new Document(getMyDir() + "Extract content.docx"); + + ConvertDocToTxt convertToPlainText = new ConvertDocToTxt(); + // Note that every node in the object model has the accept method so the visiting + // can be executed not only for the whole document, but for any node in the document. + doc.accept(convertToPlainText); + + // Once the visiting is complete, we can retrieve the result of the operation, + // That in this example, has accumulated in the visitor. + System.out.println(convertToPlainText.getText()); + //ExEnd:ExtractContentUsingDocumentVisitor + } + + //ExStart:ConvertDocToTxt + //GistId:1975a35426bcd195a2e7c61d20a1580c + /// + /// Simple implementation of saving a document in the plain text format. Implemented as a Visitor. + /// + static class ConvertDocToTxt extends DocumentVisitor { + public ConvertDocToTxt() { + mIsSkipText = false; + mBuilder = new StringBuilder(); + } + + /// + /// Gets the plain text of the document that was accumulated by the visitor. + /// + public String getText() { + return mBuilder.toString(); + } + + /// + /// Called when a Run node is encountered in the document. + /// + public int visitRun(Run run) { + appendText(run.getText()); + // Let the visitor continue visiting other nodes. + return VisitorAction.CONTINUE; + } + + /// + /// Called when a FieldStart node is encountered in the document. + /// + public int visitFieldStart(FieldStart fieldStart) { + // In Microsoft Word, a field code (such as "MERGEFIELD FieldName") follows + // after a field start character. We want to skip field codes and output field. + // Result only, therefore we use a flag to suspend the output while inside a field code. + // Note this is a very simplistic implementation and will not work very well. + // If you have nested fields in a document. + mIsSkipText = true; + return VisitorAction.CONTINUE; + } + + /// + /// Called when a FieldSeparator node is encountered in the document. + /// + public int visitFieldSeparator(FieldSeparator fieldSeparator) { + // Once reached a field separator node, we enable the output because we are + // now entering the field result nodes. + mIsSkipText = false; + return VisitorAction.CONTINUE; + } + + /// + /// Called when a FieldEnd node is encountered in the document. + /// + public int visitFieldEnd(FieldEnd fieldEnd) { + // Make sure we enable the output when reached a field end because some fields + // do not have field separator and do not have field result. + mIsSkipText = false; + return VisitorAction.CONTINUE; + } + + /// + /// Called when visiting of a Paragraph node is ended in the document. + /// + public int visitParagraphEnd(Paragraph paragraph) { + // When outputting to plain text we output Cr+Lf characters. + appendText(ControlChar.CR_LF); + return VisitorAction.CONTINUE; + } + + public int visitBodyStart(Body body) { + // We can detect beginning and end of all composite nodes such as Section, Body, + // Table, Paragraph etc and provide custom handling for them. + mBuilder.append("*** Body Started ***\r\n"); + return VisitorAction.CONTINUE; + } + + public int visitBodyEnd(Body body) { + mBuilder.append("*** Body Ended ***\r\n"); + return VisitorAction.CONTINUE; + } + + /// + /// Called when a HeaderFooter node is encountered in the document. + /// + public int visitHeaderFooterStart(HeaderFooter headerFooter) { + // Returning this value from a visitor method causes visiting of this + // Node to stop and move on to visiting the next sibling node + // The net effect in this example is that the text of headers and footers + // Is not included in the resulting output + return VisitorAction.SKIP_THIS_NODE; + } + + /// + /// Adds text to the current output. Honors the enabled/disabled output flag. + /// + private void appendText(String text) { + if (!mIsSkipText) + mBuilder.append(text); + } + + private StringBuilder mBuilder; + private boolean mIsSkipText; + } + //ExEnd:ConvertDocToTxt + + @Test + public void extractContentUsingField() throws Exception { + //ExStart:ExtractContentUsingField + //GistId:1975a35426bcd195a2e7c61d20a1580c + Document doc = new Document(getMyDir() + "Extract content.docx"); + DocumentBuilder builder = new DocumentBuilder(doc); + // Pass the first boolean parameter to get the DocumentBuilder to move to the FieldStart of the field. + // We could also get FieldStarts of a field using GetChildNode method as in the other examples. + builder.moveToMergeField("Fullname", false, false); + + // The builder cursor should be positioned at the start of the field. + FieldStart startField = (FieldStart) builder.getCurrentNode(); + Paragraph endPara = (Paragraph) doc.getFirstSection().getChild(NodeType.PARAGRAPH, 5, true); + // Extract the content between these nodes in the document. Don't include these markers in the extraction. + ArrayList extractedNodes = ExtractContentHelper.extractContent(startField, endPara, false, true); + + Document dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodes); + dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentUsingField.docx"); + //ExEnd:ExtractContentUsingField + } + + @Test + public void simpleExtractText() throws Exception { + //ExStart:SimpleExtractText + //GistId:1975a35426bcd195a2e7c61d20a1580c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField("MERGEFIELD Field"); + // When converted to text it will not retrieve fields code or special characters, + // but will still contain some natural formatting characters such as paragraph markers etc. + // This is the same as "viewing" the document as if it was opened in a text editor. + System.out.println("ToString() Result: " + doc.toString(SaveFormat.TEXT)); + //ExEnd:SimpleExtractText + } + + @Test + public void extractPrintText() throws Exception { + //ExStart:ExtractText + //GistId:7855fd2588b90f4640bf0540285b5277 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + // The range text will include control characters such as "\a" for a cell. + // You can call ToString and pass SaveFormat.Text on the desired node to find the plain text content. + System.out.println("Contents of the table: "); + System.out.println(table.getRange().getText()); + //ExEnd:ExtractText + + //ExStart:PrintTextRangeRowAndTable + //GistId:7855fd2588b90f4640bf0540285b5277 + System.out.println("\nContents of the row: "); + System.out.println(table.getRows().get(1).getRange().getText()); + + System.out.println("\nContents of the cell: "); + System.out.println(table.getLastRow().getLastCell().getRange().getText()); + //ExEnd:PrintTextRangeRowAndTable + } + + @Test + public void extractImages() throws Exception { + //ExStart:ExtractImages + //GistId:1975a35426bcd195a2e7c61d20a1580c + Document doc = new Document(getMyDir() + "Images.docx"); + + NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); + int imageIndex = 0; + + for (Shape shape : (Iterable) shapes) { + if (shape.hasImage()) { + String imageFileName = + MessageFormat.format("Image.ExportImages.{0}_{1}", imageIndex, FileFormatUtil.imageTypeToExtension(shape.getImageData().getImageType())); + + // Note, if you have only an image (not a shape with a text and the image), + // you can use shape.getShapeRenderer().save(...) method to save the image. + shape.getImageData().save(getArtifactsDir() + imageFileName); + imageIndex++; + } + } + //ExEnd:ExtractImages + } + + @Test + public void extractContentBasedOnStyles() throws Exception { + //ExStart:ExtractContentBasedOnStyles + //GistId:f1e523d4c5e156a1e42b86f56c70bf53 + Document doc = new Document(getMyDir() + "Styles.docx"); + + ArrayList paragraphs = paragraphsByStyleName(doc, "Heading 1"); + System.out.println("Paragraphs with \"Heading 1\" styles ({paragraphs.Count}):"); + + for (Paragraph paragraph : paragraphs) + System.out.println(paragraph.toString(SaveFormat.TEXT)); + + ArrayList runs = runsByStyleName(doc, "Intense Emphasis"); + System.out.println("\nRuns with \"Intense Emphasis\" styles ({runs.Count}):"); + + for (Run run : runs) + System.out.println(run.getRange().getText()); + //ExEnd:ExtractContentBasedOnStyles + } + + //ExStart:RunsByStyleName + //GistId:f1e523d4c5e156a1e42b86f56c70bf53 + public ArrayList runsByStyleName(Document doc, String styleName) { + ArrayList runsWithStyle = new ArrayList<>(); + NodeCollection runs = doc.getChildNodes(NodeType.RUN, true); + + for (Run run : (Iterable) runs) { + if (run.getFont().getStyle().getName().equals(styleName)) + runsWithStyle.add(run); + } + + return runsWithStyle; + } + //ExEnd:RunsByStyleName +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/ExtractContentHelper.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/ExtractContentHelper.java new file mode 100644 index 00000000..70c8ee88 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/ExtractContentHelper.java @@ -0,0 +1,277 @@ +package DocsExamples.Programming_with_documents.Contents_management; + +import com.aspose.words.*; + +import java.util.ArrayList; + +public class ExtractContentHelper { + public static ArrayList extractContent(Node startNode, Node endNode, boolean isInclusive, boolean copySection) { + // First, check that the nodes passed to this method are valid for use. + verifyParameterNodes(startNode, endNode); + + // Create a list to store the extracted nodes. + ArrayList nodes = new ArrayList<>(); + // If either marker is part of a comment, including the comment itself, we need to move the pointer + // forward to the Comment Node found after the CommentRangeEnd node. + if (endNode.getNodeType() == NodeType.COMMENT_RANGE_END && isInclusive) { + Node node = findNextNode(NodeType.COMMENT, endNode.getNextSibling()); + if (node != null) + endNode = node; + } + + // Keep a record of the original nodes passed to this method to split marker nodes if needed. + Node originalStartNode = startNode; + Node originalEndNode = endNode; + + // Extract content based on block-level nodes (paragraphs and tables). Traverse through parent nodes to find them. + // We will split the first and last nodes' content, depending if the marker nodes are inline. + startNode = getAncestorInBody(startNode); + endNode = getAncestorInBody(endNode); + + boolean isExtracting = true; + boolean isStartingNode = true; + // The current node we are extracting from the document. + Node currNode = startNode; + + // Begin extracting content. Process all block-level nodes and specifically split the first + // and last nodes when needed, so paragraph formatting is retained. + // Method is a little more complicated than a regular extractor as we need to factor + // in extracting using inline nodes, fields, bookmarks, etc. to make it useful. + while (isExtracting) { + if (copySection) { + Node section = currNode.getAncestor(NodeType.SECTION); + boolean sectionExists = false; + for (Node node : nodes) { + if (node.getRange().getText().equals(section.getRange().getText())) { + sectionExists = true; + break; + } + } + if (!sectionExists) { + nodes.add(section.deepClone(true)); + } + } + + // Clone the current node and its children to obtain a copy. + Node cloneNode = currNode.deepClone(true); + boolean isEndingNode = currNode.equals(endNode); + + if (isStartingNode || isEndingNode) { + // We need to process each marker separately, so pass it off to a separate method instead. + // End should be processed at first to keep node indexes. + if (isEndingNode) { + // !isStartingNode: don't add the node twice if the markers are the same node. + processMarker(cloneNode, nodes, originalEndNode, currNode, isInclusive, + false, !isStartingNode, false); + isExtracting = false; + } + + // Conditional needs to be separate as the block level start and end markers, maybe the same node. + if (isStartingNode) { + processMarker(cloneNode, nodes, originalStartNode, currNode, isInclusive, + true, true, false); + isStartingNode = false; + } + } else + // Node is not a start or end marker, simply add the copy to the list. + nodes.add(cloneNode); + + // Move to the next node and extract it. If the next node is null, + // the rest of the content is found in a different section. + if (currNode.getNextSibling() == null && isExtracting) { + // Move to the next section. + Section nextSection = (Section) currNode.getAncestor(NodeType.SECTION).getNextSibling(); + currNode = nextSection.getBody().getFirstChild(); + } else { + // Move to the next node in the body. + currNode = currNode.getNextSibling(); + } + } + + // For compatibility with mode with inline bookmarks, add the next paragraph (empty). + if (isInclusive && originalEndNode == endNode && !originalEndNode.isComposite()) + includeNextParagraph(endNode, nodes); + + // Return the nodes between the node markers. + return nodes; + } + + private static void verifyParameterNodes(Node startNode, Node endNode) { + // The order in which these checks are done is important. + if (startNode == null) + throw new IllegalArgumentException("Start node cannot be null"); + if (endNode == null) + throw new IllegalArgumentException("End node cannot be null"); + + if (!startNode.getDocument().equals(endNode.getDocument())) + throw new IllegalArgumentException("Start node and end node must belong to the same document"); + + if (startNode.getAncestor(NodeType.BODY) == null || endNode.getAncestor(NodeType.BODY) == null) + throw new IllegalArgumentException("Start node and end node must be a child or descendant of a body"); + + // Check the end node is after the start node in the DOM tree. + // First, check if they are in different sections, then if they're not, + // check their position in the body of the same section. + Section startSection = (Section) startNode.getAncestor(NodeType.SECTION); + Section endSection = (Section) endNode.getAncestor(NodeType.SECTION); + + int startIndex = startSection.getParentNode().indexOf(startSection); + int endIndex = endSection.getParentNode().indexOf(endSection); + + if (startIndex == endIndex) { + if (startSection.getBody().indexOf(getAncestorInBody(startNode)) > + endSection.getBody().indexOf(getAncestorInBody(endNode))) + throw new IllegalArgumentException("The end node must be after the start node in the body"); + } else if (startIndex > endIndex) + throw new IllegalArgumentException("The section of end node must be after the section start node"); + } + + private static Node findNextNode(int nodeType, Node fromNode) { + if (fromNode == null || fromNode.getNodeType() == nodeType) + return fromNode; + + if (fromNode.isComposite()) { + Node node = findNextNode(nodeType, ((CompositeNode) fromNode).getFirstChild()); + if (node != null) + return node; + } + + return findNextNode(nodeType, fromNode.getNextSibling()); + } + + private boolean isInline(Node node) { + // Test if the node is a descendant of a Paragraph or Table node and is not a paragraph + // or a table a paragraph inside a comment class that is decent of a paragraph is possible. + return ((node.getAncestor(NodeType.PARAGRAPH) != null || node.getAncestor(NodeType.TABLE) != null) && + !(node.getNodeType() == NodeType.PARAGRAPH || node.getNodeType() == NodeType.TABLE)); + } + + private static void processMarker(Node cloneNode, ArrayList nodes, Node node, Node blockLevelAncestor, + boolean isInclusive, boolean isStartMarker, boolean canAdd, boolean forceAdd) { + // If we are dealing with a block-level node, see if it should be included and add it to the list. + if (node == blockLevelAncestor) { + if (canAdd && isInclusive) + nodes.add(cloneNode); + return; + } + + // cloneNode is a clone of blockLevelNode. If node != blockLevelNode, blockLevelAncestor + // is the node's ancestor that means it is a composite node. + assert cloneNode.isComposite(); + + // If a marker is a FieldStart node check if it's to be included or not. + // We assume for simplicity that the FieldStart and FieldEnd appear in the same paragraph. + if (node.getNodeType() == NodeType.FIELD_START) { + // If the marker is a start node and is not included, skip to the end of the field. + // If the marker is an end node and is to be included, then move to the end field so the field will not be removed. + if (isStartMarker && !isInclusive || !isStartMarker && isInclusive) { + while (node.getNextSibling() != null && node.getNodeType() != NodeType.FIELD_END) + node = node.getNextSibling(); + } + } + + // Support a case if the marker node is on the third level of the document body or lower. + ArrayList nodeBranch = fillSelfAndParents(node, blockLevelAncestor); + + // Process the corresponding node in our cloned node by index. + Node currentCloneNode = cloneNode; + for (int i = nodeBranch.size() - 1; i >= 0; i--) { + Node currentNode = nodeBranch.get(i); + int nodeIndex = currentNode.getParentNode().indexOf(currentNode); + currentCloneNode = ((CompositeNode) currentCloneNode).getChildNodes(NodeType.ANY, false).get(nodeIndex); + + removeNodesOutsideOfRange(currentCloneNode, isInclusive || (i > 0), isStartMarker); + } + + // After processing, the composite node may become empty if it has doesn't include it. + if (canAdd && (forceAdd || ((CompositeNode) cloneNode).hasChildNodes())) + nodes.add(cloneNode); + } + + private static void removeNodesOutsideOfRange(Node markerNode, boolean isInclusive, boolean isStartMarker) { + boolean isProcessing = true; + boolean isRemoving = isStartMarker; + Node nextNode = markerNode.getParentNode().getFirstChild(); + + while (isProcessing && nextNode != null) { + Node currentNode = nextNode; + boolean isSkip = false; + + if (currentNode.equals(markerNode)) { + if (isStartMarker) { + isProcessing = false; + if (isInclusive) + isRemoving = false; + } else { + isRemoving = true; + if (isInclusive) + isSkip = true; + } + } + + nextNode = nextNode.getNextSibling(); + if (isRemoving && !isSkip) + currentNode.remove(); + } + } + + private static ArrayList fillSelfAndParents(Node node, Node tillNode) { + ArrayList list = new ArrayList<>(); + Node currentNode = node; + + while (currentNode != tillNode) { + list.add(currentNode); + currentNode = currentNode.getParentNode(); + } + + return list; + } + + private static void includeNextParagraph(Node node, ArrayList nodes) { + Paragraph paragraph = (Paragraph) findNextNode(NodeType.PARAGRAPH, node.getNextSibling()); + if (paragraph != null) { + // Move to the first child to include paragraphs without content. + Node markerNode = paragraph.hasChildNodes() ? paragraph.getFirstChild() : paragraph; + Node rootNode = getAncestorInBody(paragraph); + + processMarker(rootNode.deepClone(true), nodes, markerNode, rootNode, + markerNode == paragraph, false, true, true); + } + } + + private static Node getAncestorInBody(Node startNode) { + while (startNode.getParentNode().getNodeType() != NodeType.BODY) + startNode = startNode.getParentNode(); + return startNode; + } + + //ExStart:GenerateDocument + //GistId:1975a35426bcd195a2e7c61d20a1580c + public static Document generateDocument(Document srcDoc, ArrayList nodes) throws Exception { + Document dstDoc = new Document(); + // Remove default section in the destination document. + dstDoc.getFirstSection().remove(); + + // Import each node from the list into the new document. Keep the original formatting of the node. + NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + Section importedSection = null; + for (Node node : nodes) { + if (node.getNodeType() == NodeType.SECTION) { + // Import a section from the source document. + Section srcSection = (Section) node; + importedSection = (Section) importer.importNode(srcSection, false); + importedSection.appendChild(importer.importNode(srcSection.getBody(), false)); + for (HeaderFooter hf : srcSection.getHeadersFooters()) + importedSection.getHeadersFooters().add(importer.importNode(hf, true)); + + dstDoc.appendChild(importedSection); + } else { + Node importNode = importer.importNode(node, true); + importedSection.getBody().appendChild(importNode); + } + } + + return dstDoc; + } + //ExEnd:GenerateDocument +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/FindAndReplace.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/FindAndReplace.java new file mode 100644 index 00000000..53dc04a5 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/FindAndReplace.java @@ -0,0 +1,652 @@ +package DocsExamples.Programming_with_documents.Contents_management; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Shape; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.awt.*; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.regex.Pattern; + +@Test +public class FindAndReplace extends DocsExamplesBase { + @Test + public void simpleFindReplace() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello _CustomerName_,"); + System.out.println("Original document text: " + doc.getRange().getText()); + + doc.getRange().replace("_CustomerName_", "James Bond", new FindReplaceOptions(FindReplaceDirection.FORWARD)); + System.out.println("Document text after replace: " + doc.getRange().getText()); + + // Save the modified document + doc.save(getArtifactsDir() + "FindAndReplace.SimpleFindReplace.docx"); + } + + @Test + public void findAndHighlight() throws Exception { + //ExStart:FindAndHighlight + Document doc = new Document(getMyDir() + "Find and highlight.docx"); + + FindReplaceOptions options = new FindReplaceOptions(); + { + options.setReplacingCallback(new ReplaceEvaluatorFindAndHighlight()); + options.setDirection(FindReplaceDirection.BACKWARD); + } + + Pattern regex = Pattern.compile("your document"); + doc.getRange().replace(regex, "", options); + + doc.save(getArtifactsDir() + "FindAndReplace.FindAndHighlight.docx"); + //ExEnd:FindAndHighlight + } + + //ExStart:ReplaceEvaluatorFindAndHighlight + private static class ReplaceEvaluatorFindAndHighlight implements IReplacingCallback { + /// + /// This method is called by the Aspose.Words find and replace engine for each match. + /// This method highlights the match string, even if it spans multiple runs. + /// + public /*ReplaceAction*/int /*IReplacingCallback.*/replacing(ReplacingArgs e) { + // This is a Run node that contains either the beginning or the complete match. + Node currentNode = e.getMatchNode(); + + // The first (and may be the only) run can contain text before the match, + // in this case it is necessary to split the run. + if (e.getMatchOffset() > 0) + currentNode = splitRun((Run) currentNode, e.getMatchOffset()); + + // This array is used to store all nodes of the match for further highlighting. + ArrayList runs = new ArrayList(); + + // Find all runs that contain parts of the match string. + int remainingLength = e.getMatch().group().length(); + while ( + remainingLength > 0 && + currentNode != null && + currentNode.getText().length() <= remainingLength) { + runs.add((Run) currentNode); + remainingLength -= currentNode.getText().length(); + + // Select the next Run node. + // Have to loop because there could be other nodes such as BookmarkStart etc. + do { + currentNode = currentNode.getNextSibling(); + } while (currentNode != null && currentNode.getNodeType() != NodeType.RUN); + } + + // Split the last run that contains the match if there is any text left. + if (currentNode != null && remainingLength > 0) { + splitRun((Run) currentNode, remainingLength); + runs.add((Run) currentNode); + } + + // Now highlight all runs in the sequence. + for (Run run : runs) + run.getFont().setHighlightColor(Color.YELLOW); + + // Signal to the replace engine to do nothing because we have already done all what we wanted. + return ReplaceAction.SKIP; + } + } + //ExEnd:ReplaceEvaluatorFindAndHighlight + + //ExStart:SplitRun + /// + /// Splits text of the specified run into two runs. + /// Inserts the new run just after the specified run. + /// + private static Run splitRun(Run run, int position) { + Run afterRun = (Run) run.deepClone(true); + afterRun.setText(run.getText().substring(position)); + + run.setText(run.getText().substring((0), (0) + (position))); + run.getParentNode().insertAfter(afterRun, run); + + return afterRun; + } + //ExEnd:SplitRun + + @Test + public void metaCharactersInSearchPattern() throws Exception { + /* meta-characters + &p - paragraph break + &b - section break + &m - page break + &l - manual line break + */ + + //ExStart:MetaCharactersInSearchPattern + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("This is Line 1"); + builder.writeln("This is Line 2"); + + doc.getRange().replace("This is Line 1&pThis is Line 2", "This is replaced line"); + + builder.moveToDocumentEnd(); + builder.write("This is Line 1"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("This is Line 2"); + + doc.getRange().replace("This is Line 1&mThis is Line 2", "Page break is replaced with new text."); + + doc.save(getArtifactsDir() + "FindAndReplace.MetaCharactersInSearchPattern.docx"); + //ExEnd:MetaCharactersInSearchPattern + } + + @Test + public void replaceTextContainingMetaCharacters() throws Exception { + //ExStart:ReplaceTextContainingMetaCharacters + //GistId:98f7559b16319b1e49bd27dfbd62d062 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Arial"); + builder.writeln("First section"); + builder.writeln(" 1st paragraph"); + builder.writeln(" 2nd paragraph"); + builder.writeln("{insert-section}"); + builder.writeln("Second section"); + builder.writeln(" 1st paragraph"); + + FindReplaceOptions findReplaceOptions = new FindReplaceOptions(); + findReplaceOptions.getApplyParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + + // Double each paragraph break after word "section", add kind of underline and make it centered. + int count = doc.getRange().replace("section&p", "section&p----------------------&p", findReplaceOptions); + + // Insert section break instead of custom text tag. + count = doc.getRange().replace("{insert-section}", "&b", findReplaceOptions); + + doc.save(getArtifactsDir() + "FindAndReplace.ReplaceTextContainingMetaCharacters.docx"); + //ExEnd:ReplaceTextContainingMetaCharacters + } + + @Test + public void highlightColor() throws Exception { + //ExStart:HighlightColor + //GistId:98f7559b16319b1e49bd27dfbd62d062 + Document doc = new Document(getMyDir() + "Footer.docx"); + + FindReplaceOptions options = new FindReplaceOptions(); + options.getApplyFont().setHighlightColor(Color.orange); + + Pattern regex = Pattern.compile("(header|footer)"); + doc.getRange().replace(regex, "", options); + //ExEnd:HighlightColor + } + + @Test + public void ignoreTextInsideFields() throws Exception { + //ExStart:IgnoreTextInsideFields + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert field with text inside. + builder.insertField("INCLUDETEXT", "Text in field"); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setIgnoreFields(true); + + Pattern regex = Pattern.compile("e"); + doc.getRange().replace(regex, "*", options); + + System.out.println(doc.getText()); + + options.setIgnoreFields(false); + doc.getRange().replace(regex, "*", options); + + System.out.println(doc.getText()); + //ExEnd:IgnoreTextInsideFields + } + + @Test + public void ignoreTextInsideDeleteRevisions() throws Exception { + //ExStart:IgnoreTextInsideDeleteRevisions + //GistId:98f7559b16319b1e49bd27dfbd62d062 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert non-revised text. + builder.writeln("Deleted"); + builder.write("Text"); + + // Remove first paragraph with tracking revisions. + doc.startTrackRevisions("author", new Date()); + doc.getFirstSection().getBody().getFirstParagraph().remove(); + doc.stopTrackRevisions(); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setIgnoreDeleted(true); + + Pattern regex = Pattern.compile("e"); + doc.getRange().replace(regex, "*", options); + + System.out.println(doc.getText()); + + options.setIgnoreDeleted(false); + doc.getRange().replace(regex, "*", options); + + System.out.println(doc.getText()); + //ExEnd:IgnoreTextInsideDeleteRevisions + } + + @Test + public void ignoreTextInsideInsertRevisions() throws Exception { + //ExStart:IgnoreTextInsideInsertRevisions + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert text with tracking revisions. + doc.startTrackRevisions("author", new Date()); + builder.writeln("Inserted"); + doc.stopTrackRevisions(); + + // Insert non-revised text. + builder.write("Text"); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setIgnoreInserted(true); + + Pattern regex = Pattern.compile("e"); + doc.getRange().replace(regex, "*", options); + + System.out.println(doc.getText()); + + options.setIgnoreInserted(false); + doc.getRange().replace(regex, "*", options); + + System.out.println(doc.getText()); + //ExEnd:IgnoreTextInsideInsertRevisions + } + + @Test + public void replaceHtmlTextWithMetaCharacters() throws Exception { + //ExStart:ReplaceHtmlTextWithMetaCharacters + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("{PLACEHOLDER}"); + + FindReplaceOptions findReplaceOptions = new FindReplaceOptions(); + findReplaceOptions.setReplacingCallback(new FindAndInsertHtml()); + + doc.getRange().replace("{PLACEHOLDER}", "

          “Some Text”

          ", findReplaceOptions); + + doc.save(getArtifactsDir() + "FindAndReplace.ReplaceHtmlTextWithMetaCharacters.docx"); + //ExEnd:ReplaceHtmlTextWithMetaCharacters + } + + //ExStart:ReplaceHtmlFindAndInsertHtml + public final static class FindAndInsertHtml implements IReplacingCallback { + public int replacing(ReplacingArgs e) throws Exception { + Node currentNode = e.getMatchNode(); + + DocumentBuilder builder = new DocumentBuilder((Document) e.getMatchNode().getDocument()); + builder.moveTo(currentNode); + builder.insertHtml(e.getReplacement()); + + currentNode.remove(); + + return ReplaceAction.SKIP; + } + } + //ExEnd:ReplaceHtmlFindAndInsertHtml + + @Test + public void replaceTextInFooter() throws Exception { + //ExStart:ReplaceTextInFooter + //GistId:98f7559b16319b1e49bd27dfbd62d062 + Document doc = new Document(getMyDir() + "Footer.docx"); + + HeaderFooterCollection headersFooters = doc.getFirstSection().getHeadersFooters(); + HeaderFooter footer = headersFooters.getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setMatchCase(false); + options.setFindWholeWordsOnly(false); + + footer.getRange().replace("(C) 2006 Aspose Pty Ltd.", "Copyright (C) 2020 by Aspose Pty Ltd.", options); + + doc.save(getArtifactsDir() + "FindAndReplace.ReplaceTextInFooter.docx"); + //ExEnd:ReplaceTextInFooter + } + + @Test + //ExStart:ShowChangesForHeaderAndFooterOrders + public void showChangesForHeaderAndFooterOrders() throws Exception { + ReplaceLog logger = new ReplaceLog(); + + Document doc = new Document(getMyDir() + "Footer.docx"); + Section firstPageSection = doc.getFirstSection(); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setReplacingCallback(logger); + + doc.getRange().replace(Pattern.compile("(header|footer)"), "", options); + + doc.save(getArtifactsDir() + "FindAndReplace.ShowChangesForHeaderAndFooterOrders.docx"); + + logger.clearText(); + + firstPageSection.getPageSetup().setDifferentFirstPageHeaderFooter(false); + + doc.getRange().replace(Pattern.compile("(header|footer)"), "", options); + } + + private static class ReplaceLog implements IReplacingCallback { + public int replacing(ReplacingArgs args) { + mTextBuilder.append(args.getMatchNode().getText()); + return ReplaceAction.SKIP; + } + + void clearText() { + mTextBuilder.setLength(0); + } + + private StringBuilder mTextBuilder = new StringBuilder(); + } + //ExEnd:ShowChangesForHeaderAndFooterOrders + + @Test + public void replaceTextWithField() throws Exception { + Document doc = new Document(getMyDir() + "Replace text with fields.docx"); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setReplacingCallback(new ReplaceTextWithFieldHandler(FieldType.FIELD_MERGE_FIELD)); + + doc.getRange().replace(Pattern.compile("PlaceHolder(\\d+)"), "", options); + + doc.save(getArtifactsDir() + "FindAndReplace.ReplaceTextWithField.docx"); + } + + + public static class ReplaceTextWithFieldHandler implements IReplacingCallback { + public ReplaceTextWithFieldHandler(int type) { + mFieldType = type; + } + + public int replacing(ReplacingArgs args) throws Exception { + ArrayList runs = findAndSplitMatchRuns(args); + + DocumentBuilder builder = new DocumentBuilder((Document) args.getMatchNode().getDocument()); + builder.moveTo(runs.get(runs.size() - 1)); + + // Calculate the field's name from the FieldType enumeration by removing + // the first instance of "Field" from the text. This works for almost all of the field types. + String fieldName = FieldType.toString(mFieldType).toUpperCase().substring(5); + + // Insert the field into the document using the specified field type and the matched text as the field name. + // If the fields you are inserting do not require this extra parameter, it can be removed from the string below. + builder.insertField(MessageFormat.format("{0} {1}", fieldName, args.getMatch().group(0))); + + for (Run run : runs) + run.remove(); + + return ReplaceAction.SKIP; + } + + /// + /// Finds and splits the match runs and returns them in an List. + /// + public ArrayList findAndSplitMatchRuns(ReplacingArgs args) { + // This is a Run node that contains either the beginning or the complete match. + Node currentNode = args.getMatchNode(); + + // The first (and may be the only) run can contain text before the match, + // In this case it is necessary to split the run. + if (args.getMatchOffset() > 0) + currentNode = splitRun((Run) currentNode, args.getMatchOffset()); + + // This array is used to store all nodes of the match for further removing. + ArrayList runs = new ArrayList(); + + // Find all runs that contain parts of the match string. + int remainingLength = args.getMatch().group().length(); + while (remainingLength > 0 && currentNode != null && currentNode.getText().length() <= remainingLength) { + runs.add((Run) currentNode); + remainingLength -= currentNode.getText().length(); + + do { + currentNode = currentNode.getNextSibling(); + } while (currentNode != null && currentNode.getNodeType() != NodeType.RUN); + } + + // Split the last run that contains the match if there is any text left. + if (currentNode != null && remainingLength > 0) { + splitRun((Run) currentNode, remainingLength); + runs.add((Run) currentNode); + } + + return runs; + } + + /// + /// Splits text of the specified run into two runs. + /// Inserts the new run just after the specified run. + /// + private Run splitRun(Run run, int position) { + Run afterRun = (Run) run.deepClone(true); + + afterRun.setText(run.getText().substring(position)); + run.setText(run.getText().substring((0), (0) + (position))); + + run.getParentNode().insertAfter(afterRun, run); + + return afterRun; + } + + private int mFieldType; + } + + @Test + public void replaceWithEvaluator() throws Exception { + //ExStart:ReplaceWithEvaluator + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("sad mad bad"); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setReplacingCallback(new MyReplaceEvaluator()); + + doc.getRange().replace(Pattern.compile("[s|m]ad"), "", options); + + doc.save(getArtifactsDir() + "FindAndReplace.ReplaceWithEvaluator.docx"); + //ExEnd:ReplaceWithEvaluator + } + + //ExStart:MyReplaceEvaluator + private static class MyReplaceEvaluator implements IReplacingCallback { + /// + /// This is called during a replace operation each time a match is found. + /// This method appends a number to the match string and returns it as a replacement string. + /// + public int replacing(ReplacingArgs e) { + e.setReplacement(e.getMatch() + Integer.toString(mMatchNumber)); + mMatchNumber++; + + return ReplaceAction.REPLACE; + } + + private int mMatchNumber; + } + //ExEnd:MyReplaceEvaluator + + @Test + //ExStart:ReplaceWithHtml + //GistId:98f7559b16319b1e49bd27dfbd62d062 + public void replaceWithHtml() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello ,"); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setReplacingCallback(new ReplaceWithHtmlEvaluator(options)); + + doc.getRange().replace(Pattern.compile(" ,"), "", options); + + doc.save(getArtifactsDir() + "FindAndReplace.ReplaceWithHtml.docx"); + } + + private static class ReplaceWithHtmlEvaluator implements IReplacingCallback { + ReplaceWithHtmlEvaluator(FindReplaceOptions options) { + mOptions = options; + } + + /// + /// NOTE: This is a simplistic method that will only work well when the match + /// starts at the beginning of a run. + /// + public int replacing(ReplacingArgs args) throws Exception { + DocumentBuilder builder = new DocumentBuilder((Document) args.getMatchNode().getDocument()); + builder.moveTo(args.getMatchNode()); + + // Replace '' text with a red bold name. + builder.insertHtml("James Bond, "); + args.setReplacement(""); + + return ReplaceAction.REPLACE; + } + + private FindReplaceOptions mOptions; + } + //ExEnd:ReplaceWithHtml + + @Test + public void replaceWithRegex() throws Exception { + //ExStart:ReplaceWithRegex + //GistId:98f7559b16319b1e49bd27dfbd62d062 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("sad mad bad"); + + FindReplaceOptions options = new FindReplaceOptions(); + + doc.getRange().replace(Pattern.compile("[s|m]ad"), "bad", options); + + doc.save(getArtifactsDir() + "FindAndReplace.ReplaceWithRegex.docx"); + //ExEnd:ReplaceWithRegex + } + + @Test + public void recognizeAndSubstitutionsWithinReplacementPatterns() throws Exception { + //ExStart:RecognizeAndSubstitutionsWithinReplacementPatterns + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Jason give money to Paul."); + + Pattern regex = Pattern.compile("([A-z]+) give money to ([A-z]+)"); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setUseSubstitutions(true); + + doc.getRange().replace(regex, "$2 take money from $1", options); + //ExEnd:RecognizeAndSubstitutionsWithinReplacementPatterns + } + + @Test + public void replaceWithString() throws Exception { + //ExStart:ReplaceWithString + //GistId:98f7559b16319b1e49bd27dfbd62d062 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello _CustomerName_,"); + + doc.getRange().replace("_CustomerName_", "James Bond", new FindReplaceOptions(FindReplaceDirection.FORWARD)); + + doc.save(getArtifactsDir() + "FindAndReplace.ReplaceWithString.docx"); + //ExEnd:ReplaceWithString + } + + @Test + //ExStart:UsingLegacyOrder + public void usingLegacyOrder() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("[tag 1]"); + Shape textBox = builder.insertShape(ShapeType.TEXT_BOX, 100.0, 50.0); + builder.writeln("[tag 3]"); + + builder.moveTo(textBox.getFirstParagraph()); + builder.write("[tag 2]"); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setReplacingCallback(new ReplacingCallback()); + options.setUseLegacyOrder(true); + + doc.getRange().replace(Pattern.compile("\\[(.*?)\\]"), "", options); + + doc.save(getArtifactsDir() + "FindAndReplace.UsingLegacyOrder.docx"); + } + + private static class ReplacingCallback implements IReplacingCallback { + public int replacing(ReplacingArgs e) { + System.out.println(e.getMatch().group()); + return ReplaceAction.REPLACE; + } + } + //ExEnd:UsingLegacyOrder + + @Test + public void replaceTextInTable() throws Exception { + //ExStart:ReplaceText + //GistId:7855fd2588b90f4640bf0540285b5277 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + table.getRange().replace("Carrots", "Eggs", new FindReplaceOptions(FindReplaceDirection.FORWARD)); + table.getLastRow().getLastCell().getRange().replace("50", "20", new FindReplaceOptions(FindReplaceDirection.FORWARD)); + + doc.save(getArtifactsDir() + "FindAndReplace.ReplaceTextInTable.docx"); + //ExEnd:ReplaceText + } + + //ExStart:LineCounter + //GistId:98f7559b16319b1e49bd27dfbd62d062 + @Test //ExSkip + public void lineCounter() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("This is first line"); + builder.writeln("Second line"); + builder.writeln("And last line"); + + // Prepend each line with line number. + FindReplaceOptions options = new FindReplaceOptions(); + options.setReplacingCallback(new LineCounterCallback()); + + Pattern regex = Pattern.compile("[^&p]*&p"); + doc.getRange().replace(regex, "", options); + + doc.save(getArtifactsDir() + "FindAndReplace.LineCounter.docx"); + } + + static class LineCounterCallback implements IReplacingCallback { + public int replacing(ReplacingArgs args) { + String value = args.getMatch().group(0); + System.out.println(value); + + args.setReplacement(MessageFormat.format("{0} {1}", mCounter++, value)); + return ReplaceAction.REPLACE; + } + + private int mCounter = 1; + } + //ExEnd:LineCounter +} + diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/RemoveContent.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/RemoveContent.java new file mode 100644 index 00000000..b3a4e181 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/RemoveContent.java @@ -0,0 +1,136 @@ +package DocsExamples.Programming_with_documents.Contents_management; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.util.ArrayList; + +@Test +public class RemoveContent extends DocsExamplesBase { + @Test + public void removePageBreaks() throws Exception { + //ExStart:OpenDocument + //GistId:ae20848f6cefd3f85ab9bcbbdda340c7 + Document doc = new Document(getMyDir() + "Document.docx"); + //ExEnd:OpenDocument + + // In Aspose.Words section breaks are represented as separate Section nodes in the document. + // To remove these separate sections, the sections are combined. + removePageBreaks(doc); + removeSectionBreaks(doc); + + doc.save(getArtifactsDir() + "RemoveContent.RemovePageBreaks.docx"); + } + + //ExStart:RemovePageBreaks + private void removePageBreaks(Document doc) { + NodeCollection paragraphs = doc.getChildNodes(NodeType.PARAGRAPH, true); + + for (Paragraph para : (Iterable) paragraphs) { + // If the paragraph has a page break before the set, then clear it. + if (para.getParagraphFormat().getPageBreakBefore()) + para.getParagraphFormat().setPageBreakBefore(false); + + // Check all runs in the paragraph for page breaks and remove them. + for (Run run : para.getRuns()) { + if (run.getText().contains(ControlChar.PAGE_BREAK)) + run.setText(run.getText().replace(ControlChar.PAGE_BREAK, "")); + } + } + } + //ExEnd:RemovePageBreaks + + //ExStart:RemoveSectionBreaks + //GistId:7c0668453e53ed7a57d3ea3a05520f21 + private void removeSectionBreaks(Document doc) { + // Loop through all sections starting from the section that precedes the last one and moving to the first section. + for (int i = doc.getSections().getCount() - 2; i >= 0; i--) { + // Copy the content of the current section to the beginning of the last section. + doc.getLastSection().prependContent(doc.getSections().get(i)); + // Remove the copied section. + doc.getSections().get(i).remove(); + } + } + //ExEnd:RemoveSectionBreaks + + @Test + public void removeFooters() throws Exception { + //ExStart:RemoveFooters + //GistId:58431f54e34e5597f8cbaf97481d5321 + Document doc = new Document(getMyDir() + "Header and footer types.docx"); + + for (Section section : doc.getSections()) { + // Up to three different footers are possible in a section (for first, even and odd pages) + // we check and delete all of them. + HeaderFooter footer = section.getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_FIRST); + footer.remove(); + + // Primary footer is the footer used for odd pages. + footer = section.getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY); + footer.remove(); + + footer = section.getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_EVEN); + footer.remove(); + } + + doc.save(getArtifactsDir() + "RemoveContent.RemoveFooters.docx"); + //ExEnd:RemoveFooters + } + + @Test + //ExStart:RemoveToc + //GistId:5d939fbdab0ac77c575636f79013ffb1 + public void removeToc() throws Exception { + Document doc = new Document(getMyDir() + "Table of contents.docx"); + + // Remove the first table of contents from the document. + removeTableOfContents(doc, 0); + + doc.save(getArtifactsDir() + "RemoveContent.RemoveToc.doc"); + } + + /// + /// Removes the specified table of contents field from the document. + /// + /// The document to remove the field from. + /// The zero-based index of the TOC to remove. + private void removeTableOfContents(Document doc, int index) { + // Store the FieldStart nodes of TOC fields in the document for quick access. + ArrayList fieldStarts = new ArrayList<>(); + // This is a list to store the nodes found inside the specified TOC. They will be removed at the end of this method. + ArrayList nodeList = new ArrayList<>(); + + for (FieldStart start : (Iterable) doc.getChildNodes(NodeType.FIELD_START, true)) { + if (start.getFieldType() == FieldType.FIELD_TOC) { + fieldStarts.add(start); + } + } + + // Ensure the TOC specified by the passed index exists. + if (index > fieldStarts.size() - 1) + throw new IllegalArgumentException("Specified argument was out of the range of valid values.\r\nParameter name: " + "TOC index is out of range"); + + boolean isRemoving = true; + + Node currentNode = fieldStarts.get(index); + while (isRemoving) { + // It is safer to store these nodes and delete them all at once later. + nodeList.add(currentNode); + currentNode = currentNode.nextPreOrder(doc); + + // Once we encounter a FieldEnd node of type FieldTOC, + // we know we are at the end of the current TOC and stop here. + if (currentNode.getNodeType() == NodeType.FIELD_END) { + FieldEnd fieldEnd = (FieldEnd) currentNode; + if (fieldEnd.getFieldType() == FieldType.FIELD_TOC) + isRemoving = false; + } + } + + for (Node node : nodeList) { + node.remove(); + } + } + //ExEnd:RemoveToc +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/WorkingWithBookmarks.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/WorkingWithBookmarks.java new file mode 100644 index 00000000..479021d3 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/WorkingWithBookmarks.java @@ -0,0 +1,231 @@ +package DocsExamples.Programming_with_documents.Contents_management; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.text.MessageFormat; + +@Test +public class WorkingWithBookmarks extends DocsExamplesBase { + @Test + public void accessBookmarks() throws Exception { + //ExStart:AccessBookmarks + //GistId:ac2265ee10ddb4f0649f31ab8d219a94 + Document doc = new Document(getMyDir() + "Bookmarks.docx"); + // By index: + Bookmark bookmark1 = doc.getRange().getBookmarks().get(0); + // By name: + Bookmark bookmark2 = doc.getRange().getBookmarks().get("MyBookmark3"); + //ExEnd:AccessBookmarks + } + + @Test + public void updateBookmarkData() throws Exception { + //ExStart:UpdateBookmarkData + //GistId:ac2265ee10ddb4f0649f31ab8d219a94 + Document doc = new Document(getMyDir() + "Bookmarks.docx"); + + Bookmark bookmark = doc.getRange().getBookmarks().get("MyBookmark1"); + + String name = bookmark.getName(); + String text = bookmark.getText(); + + bookmark.setName("RenamedBookmark"); + bookmark.setText("This is a new bookmarked text."); + //ExEnd:UpdateBookmarkData + } + + @Test + public void bookmarkTableColumns() throws Exception { + //ExStart:BookmarkTable + //GistId:ac2265ee10ddb4f0649f31ab8d219a94 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startTable(); + + builder.insertCell(); + + builder.startBookmark("MyBookmark"); + + builder.write("This is row 1 cell 1"); + + builder.insertCell(); + builder.write("This is row 1 cell 2"); + + builder.endRow(); + + builder.insertCell(); + builder.writeln("This is row 2 cell 1"); + + builder.insertCell(); + builder.writeln("This is row 2 cell 2"); + + builder.endRow(); + builder.endTable(); + + builder.endBookmark("MyBookmark"); + //ExEnd:BookmarkTable + + //ExStart:BookmarkTableColumns + //GistId:ac2265ee10ddb4f0649f31ab8d219a94 + for (Bookmark bookmark : doc.getRange().getBookmarks()) { + System.out.println(MessageFormat.format("Bookmark: {0}{1}", bookmark.getName(), bookmark.isColumn() ? " (Column)" : "")); + + if (bookmark.isColumn()) { + if (Row.class.isInstance(bookmark.getBookmarkStart().getAncestor(NodeType.ROW))) { + Row row = (Row) bookmark.getBookmarkStart().getAncestor(NodeType.ROW); + if (bookmark.getFirstColumn() < row.getCells().toArray().length) { + System.out.println(row.getCells().get(bookmark.getFirstColumn()).getText().trim()); + } + } + } + } + //ExEnd:BookmarkTableColumns + } + + @Test + public void copyBookmarkedText() throws Exception { + Document srcDoc = new Document(getMyDir() + "Bookmarks.docx"); + + // This is the bookmark whose content we want to copy. + Bookmark srcBookmark = srcDoc.getRange().getBookmarks().get("MyBookmark1"); + + // We will be adding to this document. + Document dstDoc = new Document(); + // Let's say we will be appended to the end of the body of the last section. + CompositeNode dstNode = dstDoc.getLastSection().getBody(); + // If you import multiple times without a single context, it will result in many styles created. + NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + appendBookmarkedText(importer, srcBookmark, dstNode); + + dstDoc.save(getArtifactsDir() + "WorkingWithBookmarks.CopyBookmarkedText.docx"); + } + + /// + /// Copies content of the bookmark and adds it to the end of the specified node. + /// The destination node can be in a different document. + /// + /// Maintains the import context. + /// The input bookmark. + /// Must be a node that can contain paragraphs (such as a Story). + private void appendBookmarkedText(NodeImporter importer, Bookmark srcBookmark, CompositeNode dstNode) throws Exception { + // This is the paragraph that contains the beginning of the bookmark. + Paragraph startPara = (Paragraph) srcBookmark.getBookmarkStart().getParentNode(); + + // This is the paragraph that contains the end of the bookmark. + Paragraph endPara = (Paragraph) srcBookmark.getBookmarkEnd().getParentNode(); + + if (startPara == null || endPara == null) + throw new IllegalStateException( + "Parent of the bookmark start or end is not a paragraph, cannot handle this scenario yet."); + + // Limit ourselves to a reasonably simple scenario. + if (startPara.getParentNode() != endPara.getParentNode()) + throw new IllegalStateException( + "Start and end paragraphs have different parents, cannot handle this scenario yet."); + + // We want to copy all paragraphs from the start paragraph up to (and including) the end paragraph, + // therefore the node at which we stop is one after the end paragraph. + Node endNode = endPara.getNextSibling(); + + for (Node curNode = startPara; curNode != endNode; curNode = curNode.getNextSibling()) { + // This creates a copy of the current node and imports it (makes it valid) in the context + // of the destination document. Importing means adjusting styles and list identifiers correctly. + Node newNode = importer.importNode(curNode, true); + + dstNode.appendChild(newNode); + } + } + + @Test + public void createBookmark() throws Exception { + //ExStart:CreateBookmark + //GistId:ac2265ee10ddb4f0649f31ab8d219a94 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startBookmark("My Bookmark"); + builder.writeln("Text inside a bookmark."); + + builder.startBookmark("Nested Bookmark"); + builder.writeln("Text inside a NestedBookmark."); + builder.endBookmark("Nested Bookmark"); + + builder.writeln("Text after Nested Bookmark."); + builder.endBookmark("My Bookmark"); + + PdfSaveOptions options = new PdfSaveOptions(); + options.getOutlineOptions().getBookmarksOutlineLevels().add("My Bookmark", 1); + options.getOutlineOptions().getBookmarksOutlineLevels().add("Nested Bookmark", 2); + + doc.save(getArtifactsDir() + "WorkingWithBookmarks.CreateBookmark.docx", options); + //ExEnd:CreateBookmark + } + + @Test + public void showHideBookmarks() throws Exception { + //ExStart:ShowHideBookmarks + //GistId:ac2265ee10ddb4f0649f31ab8d219a94 + Document doc = new Document(getMyDir() + "Bookmarks.docx"); + + showHideBookmarkedContent(doc, "MyBookmark1", true); + + doc.save(getArtifactsDir() + "WorkingWithBookmarks.ShowHideBookmarks.docx"); + //ExEnd:ShowHideBookmarks + } + + //ExStart:ShowHideBookmarkedContent + //GistId:ac2265ee10ddb4f0649f31ab8d219a94 + private static void showHideBookmarkedContent(Document doc, String bookmarkName, boolean isHidden) { + Bookmark bm = doc.getRange().getBookmarks().get(bookmarkName); + + Node currentNode = bm.getBookmarkStart(); + while (currentNode != null && currentNode.getNodeType() != NodeType.BOOKMARK_END) { + if (currentNode.getNodeType() == NodeType.RUN) { + Run run = (Run) currentNode; + run.getFont().setHidden(isHidden); + } + currentNode = currentNode.getNextSibling(); + } + } + //ExEnd:ShowHideBookmarkedContent + + @Test + public void untangleRowBookmarks() throws Exception { + Document doc = new Document(getMyDir() + "Table column bookmarks.docx"); + + // This performs the custom task of putting the row bookmark ends into the same row with the bookmark starts. + untangle(doc); + // Now we can easily delete rows by a bookmark without damaging any other row's bookmarks. + deleteRowByBookmark(doc, "ROW2"); + // This is just to check that the other bookmark was not damaged. + if (doc.getRange().getBookmarks().get("ROW1").getBookmarkEnd() == null) + throw new Exception("Wrong, the end of the bookmark was deleted."); + + doc.save(getArtifactsDir() + "WorkingWithBookmarks.UntangleRowBookmarks.docx"); + } + + private void untangle(Document doc) throws Exception { + for (Bookmark bookmark : doc.getRange().getBookmarks()) { + // Get the parent row of both the bookmark and bookmark end node. + Row row1 = (Row) bookmark.getBookmarkStart().getAncestor(Row.class); + Row row2 = (Row) bookmark.getBookmarkEnd().getAncestor(Row.class); + + // If both rows are found okay, and the bookmark start and end are contained in adjacent rows, + // move the bookmark end node to the end of the last paragraph in the top row's last cell. + if (row1 != null && row2 != null && row1.getNextSibling() == row2) + row1.getLastCell().getLastParagraph().appendChild(bookmark.getBookmarkEnd()); + } + } + + private void deleteRowByBookmark(Document doc, String bookmarkName) { + Bookmark bookmark = doc.getRange().getBookmarks().get(bookmarkName); + + Row row = (Row) bookmark.getBookmarkStart().getAncestor(Row.class); + row.remove(); + } +} + diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/WorkingWithRanges.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/WorkingWithRanges.java new file mode 100644 index 00000000..9ddeb325 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/WorkingWithRanges.java @@ -0,0 +1,26 @@ +package DocsExamples.Programming_with_documents.Contents_management; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Document; +import org.testng.annotations.Test; + +@Test +public class WorkingWithRanges extends DocsExamplesBase { + @Test + public void rangesDeleteText() throws Exception { + //ExStart:RangesDeleteText + //GistId:f3b385f86a13b93093c214b1e7a981bf + Document doc = new Document(getMyDir() + "Document.docx"); + doc.getSections().get(0).getRange().delete(); + //ExEnd:RangesDeleteText + } + + @Test + public void rangesGetText() throws Exception { + //ExStart:RangesGetText + //GistId:f3b385f86a13b93093c214b1e7a981bf + Document doc = new Document(getMyDir() + "Document.docx"); + String text = doc.getRange().getText(); + //ExEnd:RangesGetText + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/WorkingWithSdt.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/WorkingWithSdt.java new file mode 100644 index 00000000..919a95fe --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/WorkingWithSdt.java @@ -0,0 +1,257 @@ +package DocsExamples.Programming_with_documents.Contents_management; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Shape; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.awt.*; +import java.nio.charset.StandardCharsets; +import java.util.UUID; + +@Test +public class WorkingWithSdt extends DocsExamplesBase { + @Test + public void sdtCheckBox() throws Exception { + //ExStart:SdtCheckBox + //GistId:e21394fa5fe859b6608b088a91bc7a7c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + StructuredDocumentTag sdtCheckBox = new StructuredDocumentTag(doc, SdtType.CHECKBOX, MarkupLevel.INLINE); + builder.insertNode(sdtCheckBox); + + doc.save(getArtifactsDir() + "WorkingWithSdt.SdtCheckBox.docx", SaveFormat.DOCX); + //ExEnd:SdtCheckBox + } + + @Test + public void currentStateOfCheckBox() throws Exception { + //ExStart:CurrentStateOfCheckBox + //GistId:e21394fa5fe859b6608b088a91bc7a7c + Document doc = new Document(getMyDir() + "Structured document tags.docx"); + + // Get the first content control from the document. + StructuredDocumentTag sdtCheckBox = + (StructuredDocumentTag) doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + + if (sdtCheckBox.getSdtType() == SdtType.CHECKBOX) + sdtCheckBox.setChecked(true); + + doc.save(getArtifactsDir() + "WorkingWithSdt.CurrentStateOfCheckBox.docx"); + //ExEnd:CurrentStateOfCheckBox + } + + @Test + public void modifySdt() throws Exception { + //ExStart:ModifySdt + //GistId:e21394fa5fe859b6608b088a91bc7a7c + Document doc = new Document(getMyDir() + "Structured document tags.docx"); + + for (StructuredDocumentTag sdt : (Iterable) doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG, true)) { + switch (sdt.getSdtType()) { + case SdtType.PLAIN_TEXT: { + sdt.removeAllChildren(); + Paragraph para = sdt.appendChild(new Paragraph(doc)); + Run run = new Run(doc, "new text goes here"); + para.appendChild(run); + break; + } + case SdtType.DROP_DOWN_LIST: { + SdtListItem secondItem = sdt.getListItems().get(2); + sdt.getListItems().setSelectedValue(secondItem); + break; + } + case SdtType.PICTURE: { + Shape shape = (Shape) sdt.getChild(NodeType.SHAPE, 0, true); + if (shape.hasImage()) { + shape.getImageData().setImage(getImagesDir() + "Watermark.png"); + } + + break; + } + } + } + + doc.save(getArtifactsDir() + "WorkingWithSdt.ModifySdt.docx"); + //ExEnd:ModifySdt + } + + @Test + public void sdtComboBox() throws Exception { + //ExStart:SdtComboBox + //GistId:e21394fa5fe859b6608b088a91bc7a7c + Document doc = new Document(); + + StructuredDocumentTag sdt = new StructuredDocumentTag(doc, SdtType.COMBO_BOX, MarkupLevel.BLOCK); + sdt.getListItems().add(new SdtListItem("Choose an item", "-1")); + sdt.getListItems().add(new SdtListItem("Item 1", "1")); + sdt.getListItems().add(new SdtListItem("Item 2", "2")); + doc.getFirstSection().getBody().appendChild(sdt); + + doc.save(getArtifactsDir() + "WorkingWithSdt.SdtComboBox.docx"); + //ExEnd:SdtComboBox + } + + @Test + public void sdtRichTextBox() throws Exception { + //ExStart:SdtRichTextBox + //GistId:e21394fa5fe859b6608b088a91bc7a7c + Document doc = new Document(); + + StructuredDocumentTag sdtRichText = new StructuredDocumentTag(doc, SdtType.RICH_TEXT, MarkupLevel.BLOCK); + + Paragraph para = new Paragraph(doc); + Run run = new Run(doc); + run.setText("Hello World"); + run.getFont().setColor(Color.GREEN); + para.getRuns().add(run); + sdtRichText.getChildNodes(NodeType.ANY, false).add(para); + doc.getFirstSection().getBody().appendChild(sdtRichText); + + doc.save(getArtifactsDir() + "WorkingWithSdt.SdtRichTextBox.docx"); + //ExEnd:SdtRichTextBox + } + + @Test + public void sdtColor() throws Exception { + //ExStart:SdtColor + //GistId:e21394fa5fe859b6608b088a91bc7a7c + Document doc = new Document(getMyDir() + "Structured document tags.docx"); + + StructuredDocumentTag sdt = (StructuredDocumentTag) doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + sdt.setColor(Color.RED); + + doc.save(getArtifactsDir() + "WorkingWithSdt.SdtColor.docx"); + //ExEnd:SdtColor + } + + @Test + public void clearSdt() throws Exception { + //ExStart:ClearSdt + //GistId:e21394fa5fe859b6608b088a91bc7a7c + Document doc = new Document(getMyDir() + "Structured document tags.docx"); + + StructuredDocumentTag sdt = (StructuredDocumentTag) doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + sdt.clear(); + + doc.save(getArtifactsDir() + "WorkingWithSdt.ClearSdt.doc"); + //ExEnd:ClearSdt + } + + @Test + public void bindSdtToCustomXmlPart() throws Exception { + //ExStart:BindSdtToCustomXmlPart + //GistId:e21394fa5fe859b6608b088a91bc7a7c + Document doc = new Document(); + CustomXmlPart xmlPart = + doc.getCustomXmlParts().add(UUID.randomUUID().toString(), "Hello, World!"); + + StructuredDocumentTag sdt = new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.BLOCK); + doc.getFirstSection().getBody().appendChild(sdt); + + sdt.getXmlMapping().setMapping(xmlPart, "/root[1]/text[1]", ""); + + doc.save(getArtifactsDir() + "WorkingWithSdt.BindSdtToCustomXmlPart.doc"); + //ExEnd:BindSdtToCustomXmlPart + } + + @Test + public void sdtStyle() throws Exception { + //ExStart:SdtStyle + //GistId:e21394fa5fe859b6608b088a91bc7a7c + Document doc = new Document(getMyDir() + "Structured document tags.docx"); + + StructuredDocumentTag sdt = (StructuredDocumentTag) doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + Style style = doc.getStyles().getByStyleIdentifier(StyleIdentifier.QUOTE); + sdt.setStyle(style); + + doc.save(getArtifactsDir() + "WorkingWithSdt.SdtStyle.docx"); + //ExEnd:SdtStyle + } + + @Test + public void repeatingSectionMappedToCustomXmlPart() throws Exception { + //ExStart:RepeatingSectionMappedToCustomXmlPart + //GistId:e21394fa5fe859b6608b088a91bc7a7c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + CustomXmlPart xmlPart = doc.getCustomXmlParts().add("Books", + "Everyday ItalianGiada De Laurentiis" + + "Harry PotterJ K. Rowling" + + "Learning XMLErik T. Ray"); + + Table table = builder.startTable(); + + builder.insertCell(); + builder.write("Title"); + + builder.insertCell(); + builder.write("Author"); + + builder.endRow(); + builder.endTable(); + + StructuredDocumentTag repeatingSectionSdt = + new StructuredDocumentTag(doc, SdtType.REPEATING_SECTION, MarkupLevel.ROW); + repeatingSectionSdt.getXmlMapping().setMapping(xmlPart, "/books[1]/book", ""); + table.appendChild(repeatingSectionSdt); + + StructuredDocumentTag repeatingSectionItemSdt = + new StructuredDocumentTag(doc, SdtType.REPEATING_SECTION_ITEM, MarkupLevel.ROW); + repeatingSectionSdt.appendChild(repeatingSectionItemSdt); + + Row row = new Row(doc); + repeatingSectionItemSdt.appendChild(row); + + StructuredDocumentTag titleSdt = + new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.CELL); + titleSdt.getXmlMapping().setMapping(xmlPart, "/books[1]/book[1]/title[1]", ""); + row.appendChild(titleSdt); + + StructuredDocumentTag authorSdt = + new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.CELL); + authorSdt.getXmlMapping().setMapping(xmlPart, "/books[1]/book[1]/author[1]", ""); + row.appendChild(authorSdt); + + doc.save(getArtifactsDir() + "WorkingWithSdt.RepeatingSectionMappedToCustomXmlPart.docx"); + //ExEnd:RepeatingSectionMappedToCustomXmlPart + } + + @Test + public void multiSection() throws Exception { + //ExStart:MultiSectionSDT + Document doc = new Document(getMyDir() + "Multi-section structured document tags.docx"); + + NodeCollection tags = doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_START, true); + + for (StructuredDocumentTagRangeStart tag : (Iterable) tags) + System.out.println(tag.getTitle()); + //ExEnd:MultiSectionSDT + } + + @Test + public void sdtRangeStartXmlMapping() throws Exception { + //ExStart:SdtRangeStartXmlMapping + //GistId:e21394fa5fe859b6608b088a91bc7a7c + Document doc = new Document(getMyDir() + "Multi-section structured document tags.docx"); + + // Construct an XML part that contains data and add it to the document's CustomXmlPart collection. + String xmlPartId = UUID.randomUUID().toString(); + String xmlPartContent = "Text element #1Text element #2"; + CustomXmlPart xmlPart = doc.getCustomXmlParts().add(xmlPartId, xmlPartContent); + System.out.println(new String(xmlPart.getData(), StandardCharsets.US_ASCII)); + + // Create a StructuredDocumentTag that will display the contents of our CustomXmlPart in the document. + StructuredDocumentTagRangeStart sdtRangeStart = (StructuredDocumentTagRangeStart) doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_START, 0, true); + + // If we set a mapping for our StructuredDocumentTag, + // it will only display a part of the CustomXmlPart that the XPath points to. + // This XPath will point to the contents second "" element of the first "" element of our CustomXmlPart. + sdtRangeStart.getXmlMapping().setMapping(xmlPart, "/root[1]/text[2]", null); + + doc.save(getArtifactsDir() + "WorkingWithSdt.SdtRangeStartXmlMapping.docx"); + //ExEnd:SdtRangeStartXmlMapping + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/WorkingWithStylesAndThemes.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/WorkingWithStylesAndThemes.java new file mode 100644 index 00000000..df6ebd07 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/WorkingWithStylesAndThemes.java @@ -0,0 +1,117 @@ +package DocsExamples.Programming_with_documents.Contents_management; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.awt.*; + +@Test +public class WorkingWithStylesAndThemes extends DocsExamplesBase { + @Test + public void accessStyles() throws Exception { + //ExStart:AccessStyles + //GistId:f1e523d4c5e156a1e42b86f56c70bf53 + Document doc = new Document(); + + String styleName = ""; + + // Get styles collection from the document. + StyleCollection styles = doc.getStyles(); + for (Style style : styles) { + if ("".equals(styleName)) { + styleName = style.getName(); + System.out.println(styleName); + } else { + styleName = styleName + ", " + style.getName(); + System.out.println(styleName); + } + } + //ExEnd:AccessStyles + } + + @Test + public void copyStyles() throws Exception { + //ExStart:CopyStyles + //GistId:f1e523d4c5e156a1e42b86f56c70bf53 + Document doc = new Document(); + Document target = new Document(getMyDir() + "Rendering.docx"); + + target.copyStylesFromTemplate(doc); + + doc.save(getArtifactsDir() + "WorkingWithStylesAndThemes.CopyStyles.docx"); + //ExEnd:CopyStyles + } + + @Test + public void getThemeProperties() throws Exception { + //ExStart:GetThemeProperties + //GistId:f1e523d4c5e156a1e42b86f56c70bf53 + Document doc = new Document(); + + Theme theme = doc.getTheme(); + + System.out.println(theme.getMajorFonts().getLatin()); + System.out.println(theme.getMinorFonts().getEastAsian()); + System.out.println(theme.getColors().getAccent1()); + //ExEnd:GetThemeProperties + } + + @Test + public void setThemeProperties() throws Exception { + //ExStart:SetThemeProperties + //GistId:f1e523d4c5e156a1e42b86f56c70bf53 + Document doc = new Document(); + + Theme theme = doc.getTheme(); + theme.getMinorFonts().setLatin("Times New Roman"); + theme.getColors().setHyperlink(Color.ORANGE); + //ExEnd:SetThemeProperties + } + + @Test + public void insertStyleSeparator() throws Exception { + //ExStart:InsertStyleSeparator + //GistId:75080b633887e95c397bce7d14d7cbf1 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Style paraStyle = builder.getDocument().getStyles().add(StyleType.PARAGRAPH, "MyParaStyle"); + paraStyle.getFont().setBold(false); + paraStyle.getFont().setSize(8.0); + paraStyle.getFont().setName("Arial"); + + // Append text with "Heading 1" style. + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + builder.write("Heading 1"); + builder.insertStyleSeparator(); + + // Append text with another style. + builder.getParagraphFormat().setStyleName(paraStyle.getName()); + builder.write("This is text with some other formatting "); + + doc.save(getArtifactsDir() + "WorkingWithStylesAndThemes.InsertStyleSeparator.docx"); + //ExEnd:InsertStyleSeparator + } + + @Test + public void copyStyleDifferentDocument() throws Exception { + //ExStart:CopyStyleDifferentDocument + //GistId:f1d06175603c48e6dabf5a2eea01207c + Document srcDoc = new Document(); + + // Create a custom style for the source document. + Style srcStyle = srcDoc.getStyles().add(StyleType.PARAGRAPH, "MyStyle"); + srcStyle.getFont().setColor(Color.RED); + + // Import the source document's custom style into the destination document. + Document dstDoc = new Document(); + Style newStyle = dstDoc.getStyles().addCopy(srcStyle); + + // The imported style has an appearance identical to its source style. + Assert.assertEquals("MyStyle", newStyle.getName()); + Assert.assertEquals(Color.RED.getRGB(), newStyle.getFont().getColor().getRGB()); + //ExEnd:CopyStyleDifferentDocument + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/WorkingWithTableOfContent.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/WorkingWithTableOfContent.java new file mode 100644 index 00000000..ae54e769 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Contents_management/WorkingWithTableOfContent.java @@ -0,0 +1,69 @@ +package DocsExamples.Programming_with_documents.Contents_management; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +@Test +public class WorkingWithTableOfContent extends DocsExamplesBase { + @Test + public void changeStyleOfTocLevel() throws Exception { + //ExStart:ChangeStyleOfTocLevel + //GistId:5d939fbdab0ac77c575636f79013ffb1 + Document doc = new Document(); + // Retrieve the style used for the first level of the TOC and change the formatting of the style. + doc.getStyles().getByStyleIdentifier(StyleIdentifier.TOC_1).getFont().setBold(true); + //ExEnd:ChangeStyleOfTocLevel + } + + @Test + public void changeTocTabStops() throws Exception { + //ExStart:ChangeTocTabStops + //GistId:5d939fbdab0ac77c575636f79013ffb1 + Document doc = new Document(getMyDir() + "Table of contents.docx"); + + for (Paragraph para : (Iterable) doc.getChildNodes(NodeType.PARAGRAPH, true)) { + // Check if this paragraph is formatted using the TOC result based styles. + // This is any style between TOC and TOC9. + if (para.getParagraphFormat().getStyle().getStyleIdentifier() >= StyleIdentifier.TOC_1 && + para.getParagraphFormat().getStyle().getStyleIdentifier() <= StyleIdentifier.TOC_9) { + // Get the first tab used in this paragraph, this should be the tab used to align the page numbers. + TabStop tab = para.getParagraphFormat().getTabStops().get(0); + + // Remove the old tab from the collection. + para.getParagraphFormat().getTabStops().removeByPosition(tab.getPosition()); + + // Insert a new tab using the same properties but at a modified position. + // We could also change the separators used (dots) by passing a different Leader type. + para.getParagraphFormat().getTabStops().add(tab.getPosition() - 50.0, tab.getAlignment(), tab.getLeader()); + } + } + + doc.save(getArtifactsDir() + "WorkingWithTableOfContent.ChangeTocTabStops.docx"); + //ExEnd:ChangeTocTabStops + } + + @Test + public void extractToc() throws Exception { + //ExStart:ExtractToc + //GistId:5d939fbdab0ac77c575636f79013ffb1 + Document doc = new Document(getMyDir() + "Table of contents.docx"); + + for (Field field : doc.getRange().getFields()) { + if (((field.getType()) == (FieldType.FIELD_HYPERLINK))) { + FieldHyperlink hyperlink = (FieldHyperlink) field; + if (hyperlink.getSubAddress() != null && hyperlink.getSubAddress().startsWith("_Toc")) { + Paragraph tocItem = (Paragraph) field.getStart().getAncestor(NodeType.PARAGRAPH); + System.out.println(tocItem.toString(SaveFormat.TEXT).trim()); + System.out.println("------------------"); + if (tocItem != null) { + Bookmark bm = doc.getRange().getBookmarks().get(hyperlink.getSubAddress()); + Paragraph pointer = (Paragraph) bm.getBookmarkStart().getAncestor(NodeType.PARAGRAPH); + System.out.println(pointer.toString(SaveFormat.TEXT)); + } + } + } + } + //ExEnd:ExtractToc + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/EnableOpenTypeFeatures.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/EnableOpenTypeFeatures.java new file mode 100644 index 00000000..ac1a00a1 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/EnableOpenTypeFeatures.java @@ -0,0 +1,22 @@ +package DocsExamples.Programming_with_documents; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Document; +import com.aspose.words.shaping.harfbuzz.HarfBuzzTextShaperFactory; +import org.testng.annotations.Test; + +class EnableOpenTypeFeatures extends DocsExamplesBase { + @Test + public void openTypeFeatures() throws Exception { + //ExStart:OpenTypeFeatures + //GistId:7840fae2297fa05bba1ca0608cb81bf1 + Document doc = new Document(getMyDir() + "OpenType text shaping.docx"); + + // When we set the text shaper factory, the layout starts to use OpenType features. + // An Instance property returns BasicTextShaperCache object wrapping HarfBuzzTextShaperFactory. + doc.getLayoutOptions().setTextShaperFactory(HarfBuzzTextShaperFactory.getInstance()); + + doc.save(getArtifactsDir() + "WorkingWithHarfBuzz.OpenTypeFeatures.pdf"); + //ExEnd:OpenTypeFeatures + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Protect_or_encrypt_document/DocumentProtection.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Protect_or_encrypt_document/DocumentProtection.java new file mode 100644 index 00000000..1fc97c9a --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Protect_or_encrypt_document/DocumentProtection.java @@ -0,0 +1,157 @@ +package DocsExamples.Programming_with_documents.Protect_or_encrypt_document; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +@Test +public class DocumentProtection extends DocsExamplesBase { + @Test + public void passwordProtection() throws Exception { + //ExStart:PasswordProtection + //GistId:856ba85fa704fa728b0ec20aafddd16b + Document doc = new Document(); + + // Apply document protection. + doc.protect(ProtectionType.NO_PROTECTION, "password"); + + doc.save(getArtifactsDir() + "DocumentProtection.PasswordProtection.docx"); + //ExEnd:PasswordProtection + } + + @Test + public void allowOnlyFormFieldsProtect() throws Exception { + //ExStart:AllowOnlyFormFieldsProtect + //GistId:856ba85fa704fa728b0ec20aafddd16b + // Insert two sections with some text. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Text added to a document."); + + // A document protection only works when document protection is turned and only editing in form fields is allowed. + doc.protect(ProtectionType.ALLOW_ONLY_FORM_FIELDS, "password"); + + // Save the protected document. + doc.save(getArtifactsDir() + "DocumentProtection.AllowOnlyFormFieldsProtect.docx"); + //ExEnd:AllowOnlyFormFieldsProtect + } + + @Test + public void removeDocumentProtection() throws Exception { + //ExStart:RemoveDocumentProtection + //GistId:856ba85fa704fa728b0ec20aafddd16b + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Text added to a document."); + + // Documents can have protection removed either with no password, or with the correct password. + doc.unprotect(); + doc.protect(ProtectionType.READ_ONLY, "newPassword"); + doc.unprotect("newPassword"); + + doc.save(getArtifactsDir() + "DocumentProtection.RemoveDocumentProtection.docx"); + //ExEnd:RemoveDocumentProtection + } + + @Test + public void unrestrictedEditableRegions() throws Exception { + //ExStart:UnrestrictedEditableRegions + //GistId:856ba85fa704fa728b0ec20aafddd16b + // Upload a document and make it as read-only. + Document doc = new Document(getMyDir() + "Document.docx"); + DocumentBuilder builder = new DocumentBuilder(doc); + + doc.protect(ProtectionType.READ_ONLY, "MyPassword"); + + builder.writeln("Hello world! Since we have set the document's protection level to read-only, " + "we cannot edit this paragraph without the password."); + + // Start an editable range. + EditableRangeStart edRangeStart = builder.startEditableRange(); + // An EditableRange object is created for the EditableRangeStart that we just made. + EditableRange editableRange = edRangeStart.getEditableRange(); + + // Put something inside the editable range. + builder.writeln("Paragraph inside first editable range"); + + // An editable range is well-formed if it has a start and an end. + EditableRangeEnd edRangeEnd = builder.endEditableRange(); + + builder.writeln("This paragraph is outside any editable ranges, and cannot be edited."); + + doc.save(getArtifactsDir() + "DocumentProtection.UnrestrictedEditableRegions.docx"); + //ExEnd:UnrestrictedEditableRegions + } + + @Test + public void unrestrictedSection() throws Exception { + //ExStart:UnrestrictedSection + //GistId:856ba85fa704fa728b0ec20aafddd16b + // Insert two sections with some text. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Section 1. Unprotected."); + builder.insertBreak(BreakType.SECTION_BREAK_CONTINUOUS); + builder.writeln("Section 2. Protected."); + + // Section protection only works when document protection is turned and only editing in form fields is allowed. + doc.protect(ProtectionType.ALLOW_ONLY_FORM_FIELDS, "password"); + + // By default, all sections are protected, but we can selectively turn protection off. + doc.getSections().get(0).setProtectedForForms(false); + doc.save(getArtifactsDir() + "DocumentProtection.UnrestrictedSection.docx"); + + doc = new Document(getArtifactsDir() + "DocumentProtection.UnrestrictedSection.docx"); + Assert.assertFalse(doc.getSections().get(0).getProtectedForForms()); + Assert.assertTrue(doc.getSections().get(1).getProtectedForForms()); + //ExEnd:UnrestrictedSection + } + + @Test + public void getProtectionType() throws Exception { + //ExStart:GetProtectionType + Document doc = new Document(getMyDir() + "Document.docx"); + int protectionType = doc.getProtectionType(); + //ExEnd:GetProtectionType + } + + @Test + public void readOnlyProtection() throws Exception { + //ExStart:ReadOnlyProtection + //GistId:7cf6735e83804ba8942663695b22ee42 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Open document as read-only"); + + // Enter a password that's up to 15 characters long. + doc.getWriteProtection().setPassword("MyPassword"); + + // Make the document as read-only. + doc.getWriteProtection().setReadOnlyRecommended(true); + + // Apply write protection as read-only. + doc.protect(ProtectionType.READ_ONLY); + doc.save(getArtifactsDir() + "DocumentProtection.ReadOnlyProtection.docx"); + //ExEnd:ReadOnlyProtection + } + + @Test + public void removeReadOnlyRestriction() throws Exception { + //ExStart:RemoveReadOnlyRestriction + //GistId:7cf6735e83804ba8942663695b22ee42 + Document doc = new Document(); + + // Enter a password that's up to 15 characters long. + doc.getWriteProtection().setPassword("MyPassword"); + // Remove the read-only option. + doc.getWriteProtection().setReadOnlyRecommended(false); + + // Apply write protection without any protection. + doc.protect(ProtectionType.NO_PROTECTION); + doc.save(getArtifactsDir() + "DocumentProtection.RemoveReadOnlyRestriction.docx"); + //ExEnd:RemoveReadOnlyRestriction + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Protect_or_encrypt_document/WorkingWithDigitalSinatures.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Protect_or_encrypt_document/WorkingWithDigitalSinatures.java new file mode 100644 index 00000000..d18d45c1 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Protect_or_encrypt_document/WorkingWithDigitalSinatures.java @@ -0,0 +1,191 @@ +package DocsExamples.Programming_with_documents.Protect_or_encrypt_document; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.apache.commons.collections4.IterableUtils; +import org.apache.commons.io.FileUtils; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.Base64; +import java.util.Date; +import java.util.UUID; + +@Test +public class WorkingWithDigitalSinatures extends DocsExamplesBase { + @Test + public void signDocument() throws Exception { + //ExStart:SignDocument + //GistId:39ea49b7754e472caf41179f8b5970a0 + CertificateHolder certHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + + DigitalSignatureUtil.sign(getMyDir() + "Digitally signed.docx", getArtifactsDir() + "Document.Signed.docx", + certHolder); + //ExEnd:SignDocument + } + + @Test + public void signingEncryptedDocument() throws Exception { + //ExStart:SigningEncryptedDocument + SignOptions signOptions = new SignOptions(); + signOptions.setDecryptionPassword("decryptionPassword"); + + CertificateHolder certHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + + DigitalSignatureUtil.sign(getMyDir() + "Digitally signed.docx", getArtifactsDir() + "Document.EncryptedDocument.docx", + certHolder, signOptions); + //ExEnd:SigningEncryptedDocument + } + + @Test + public void creatingAndSigningNewSignatureLine() throws Exception { + //ExStart:CreatingAndSigningNewSignatureLine + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + SignatureLine signatureLine = builder.insertSignatureLine(new SignatureLineOptions()).getSignatureLine(); + + doc.save(getArtifactsDir() + "SignDocuments.SignatureLine.docx"); + + SignOptions signOptions = new SignOptions(); + signOptions.setSignatureLineId(signatureLine.getId()); + signOptions.setSignatureLineImage(FileUtils.readFileToByteArray(new File(getImagesDir() + "Enhanced Windows MetaFile.emf"))); + + CertificateHolder certHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + + DigitalSignatureUtil.sign(getArtifactsDir() + "SignDocuments.SignatureLine.docx", + getArtifactsDir() + "SignDocuments.NewSignatureLine.docx", certHolder, signOptions); + //ExEnd:CreatingAndSigningNewSignatureLine + } + + @Test + public void signingExistingSignatureLine() throws Exception { + //ExStart:SigningExistingSignatureLine + Document doc = new Document(getMyDir() + "Signature line.docx"); + + SignatureLine signatureLine = + ((Shape) doc.getFirstSection().getBody().getChild(NodeType.SHAPE, 0, true)).getSignatureLine(); + + SignOptions signOptions = new SignOptions(); + signOptions.setSignatureLineId(signatureLine.getId()); + signOptions.setSignatureLineImage(FileUtils.readFileToByteArray(new File(getImagesDir() + "Enhanced Windows MetaFile.emf"))); + + CertificateHolder certHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + + DigitalSignatureUtil.sign(getMyDir() + "Digitally signed.docx", + getArtifactsDir() + "SignDocuments.SigningExistingSignatureLine.docx", certHolder, signOptions); + //ExEnd:SigningExistingSignatureLine + } + + @Test + public void setSignatureProviderId() throws Exception { + //ExStart:SetSignatureProviderID + Document doc = new Document(getMyDir() + "Signature line.docx"); + + SignatureLine signatureLine = + ((Shape) doc.getFirstSection().getBody().getChild(NodeType.SHAPE, 0, true)).getSignatureLine(); + + SignOptions signOptions = new SignOptions(); + signOptions.setProviderId(signatureLine.getProviderId()); + signOptions.setSignatureLineId(signatureLine.getId()); + + CertificateHolder certHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + + DigitalSignatureUtil.sign(getMyDir() + "Digitally signed.docx", + getArtifactsDir() + "SignDocuments.SetSignatureProviderId.docx", certHolder, signOptions); + //ExEnd:SetSignatureProviderID + } + + @Test + public void createNewSignatureLineAndSetProviderId() throws Exception { + //ExStart:CreateNewSignatureLineAndSetProviderId + //GistId:39ea49b7754e472caf41179f8b5970a0 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + SignatureLineOptions signatureLineOptions = new SignatureLineOptions(); + signatureLineOptions.setSigner("yourname"); + signatureLineOptions.setSignerTitle("Worker"); + signatureLineOptions.setEmail("yourname@aspose.com"); + signatureLineOptions.setShowDate(true); + signatureLineOptions.setDefaultInstructions(false); + signatureLineOptions.setInstructions("Please sign here."); + signatureLineOptions.setAllowComments(true); + + SignatureLine signatureLine = builder.insertSignatureLine(signatureLineOptions).getSignatureLine(); + signatureLine.setProviderId(UUID.fromString("CF5A7BB4-8F3C-4756-9DF6-BEF7F13259A2")); + + doc.save(getArtifactsDir() + "SignDocuments.SignatureLineProviderId.docx"); + + SignOptions signOptions = new SignOptions(); + signOptions.setSignatureLineId(signatureLine.getId()); + signOptions.setProviderId(signatureLine.getProviderId()); + signOptions.setComments("Document was signed by Aspose"); + signOptions.setSignTime(new Date()); + + CertificateHolder certHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + + DigitalSignatureUtil.sign(getArtifactsDir() + "SignDocuments.SignatureLineProviderId.docx", + getArtifactsDir() + "SignDocuments.CreateNewSignatureLineAndSetProviderId.docx", certHolder, signOptions); + //ExEnd:CreateNewSignatureLineAndSetProviderId + } + + @Test + public void accessAndVerifySignature() throws Exception { + //ExStart:AccessAndVerifySignature + Document doc = new Document(getMyDir() + "Digitally signed.docx"); + + for (DigitalSignature signature : doc.getDigitalSignatures()) { + System.out.println("*** Signature Found ***"); + System.out.println("Is valid: " + signature.isValid()); + // This property is available in MS Word documents only. + System.out.println("Reason for signing: " + signature.getComments()); + System.out.println("Time of signing: " + signature.getSignTime()); + System.out.println("Subject name: " + signature.getSubjectName()); + System.out.println("Issuer name: " + signature.getIssuerName()); + System.out.println(); + } + //ExEnd:AccessAndVerifySignature + } + + @Test + public void RemoveSignatures() throws Exception { + //ExStart:RemoveSignatures + //GistId:39ea49b7754e472caf41179f8b5970a0 + // There are two ways of using the DigitalSignatureUtil class to remove digital signatures + // from a signed document by saving an unsigned copy of it somewhere else in the local file system. + // 1 - Determine the locations of both the signed document and the unsigned copy by filename strings: + DigitalSignatureUtil.removeAllSignatures(getMyDir() + "Digitally signed.docx", + getArtifactsDir() + "DigitalSignatureUtil.LoadAndRemove.FromString.docx"); + + // 2 - Determine the locations of both the signed document and the unsigned copy by file streams: + try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Digitally signed.docx")) { + try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "DigitalSignatureUtil.LoadAndRemove.FromStream.docx")) { + DigitalSignatureUtil.removeAllSignatures(streamIn, streamOut); + } + } + + // Verify that both our output documents have no digital signatures. + Assert.assertEquals(IterableUtils.size(DigitalSignatureUtil.loadSignatures(getArtifactsDir() + "DigitalSignatureUtil.LoadAndRemove.FromString.docx")), 0); + Assert.assertEquals(IterableUtils.size(DigitalSignatureUtil.loadSignatures(getArtifactsDir() + "DigitalSignatureUtil.LoadAndRemove.FromStream.docx")), 0); + //ExEnd:RemoveSignatures + } + + @Test + public void signatureValue() throws Exception { + //ExStart:SignatureValue + //GistId:39ea49b7754e472caf41179f8b5970a0 + Document doc = new Document(getMyDir() + "Digitally signed.docx"); + + for (DigitalSignature digitalSignature : doc.getDigitalSignatures()) { + String signatureValue = Base64.getEncoder().encodeToString(digitalSignature.getSignatureValue()); + Assert.assertEquals("K1cVLLg2kbJRAzT5WK+m++G8eEO+l7S+5ENdjMxxTXkFzGUfvwxREuJdSFj9AbD" + + "MhnGvDURv9KEhC25DDF1al8NRVR71TF3CjHVZXpYu7edQS5/yLw/k5CiFZzCp1+MmhOdYPcVO+Fm" + + "+9fKr2iNLeyYB+fgEeZHfTqTFM2WwAqo=", signatureValue); + } + //ExEnd:SignatureValue + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Split_documents/PageSplitter.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Split_documents/PageSplitter.java new file mode 100644 index 00000000..132a21e2 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Split_documents/PageSplitter.java @@ -0,0 +1,663 @@ +package DocsExamples.Programming_with_documents.Split_documents; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.StringUtils; +import org.testng.annotations.Test; + +import java.io.File; +import java.text.MessageFormat; +import java.util.*; +import java.util.regex.Pattern; + +@Test +public class PageSplitter extends DocsExamplesBase { + @Test + public void splitDocuments() throws Exception { + splitAllDocumentsToPages(getMyDir()); + } + + private void splitDocumentToPages(String docName) throws Exception { + String fileName = FilenameUtils.getBaseName(docName); + String extensionName = FilenameUtils.getExtension(docName); + + System.out.println("Processing document: " + fileName + "." + extensionName); + + Document doc = new Document(docName); + // Split nodes in the document into separate pages. + DocumentPageSplitter splitter = new DocumentPageSplitter(doc); + + // Save each page to the disk as a separate document. + for (int page = 1; page <= doc.getPageCount(); page++) { + Document pageDoc = splitter.getDocumentOfPage(page); + pageDoc.save(getArtifactsDir() + MessageFormat.format("{0} - page{1}.{2}", fileName, page, extensionName)); + } + } + + private void splitAllDocumentsToPages(String folderName) throws Exception { + ArrayList fileNames = directoryGetFiles(folderName, "*.doc"); + + for (String fileName : fileNames) { + splitDocumentToPages(fileName); + } + } + + static ArrayList directoryGetFiles(final String dirname, final String filenamePattern) { + File dirFile = new File(dirname); + Pattern re = Pattern.compile(filenamePattern.replace("*", ".*").replace("?", ".?")); + ArrayList dirFiles = new ArrayList<>(); + for (File file : dirFile.listFiles()) { + if (file.isDirectory()) { + dirFiles.addAll(directoryGetFiles(file.getPath(), filenamePattern)); + } else { + if (re.matcher(file.getName()).matches()) { + dirFiles.add(file.getPath()); + } + } + } + return dirFiles; + } +} + +/// +/// Splits a document into multiple documents, one per page. +/// +class DocumentPageSplitter { + private PageNumberFinder pageNumberFinder; + + /// + /// Initializes a new instance of the class. + /// This method splits the document into sections so that each page begins and ends at a section boundary. + /// It is recommended not to modify the document afterwards. + /// + /// Source document + public DocumentPageSplitter(Document source) throws Exception { + pageNumberFinder = PageNumberFinderFactory.create(source); + } + + private Document getDocument() { + return pageNumberFinder.getDocument(); + } + + /// + /// Gets the document of a page. + /// + /// + /// 1-based index of a page. + /// + /// + /// The . + /// + public Document getDocumentOfPage(int pageIndex) throws Exception { + return getDocumentOfPageRange(pageIndex, pageIndex); + } + + /// + /// Gets the document of a page range. + /// + /// + /// 1-based index of the start page. + /// + /// + /// 1-based index of the end page. + /// + /// + /// The . + /// + public Document getDocumentOfPageRange(int startIndex, int endIndex) throws Exception { + Document result = (Document) getDocument().deepClone(false); + for (Node section : pageNumberFinder.retrieveAllNodesOnPages(startIndex, endIndex, NodeType.SECTION)) { + result.appendChild(result.importNode(section, true)); + } + + return result; + } +} + +/// +/// Provides methods for extracting nodes of a document which are rendered on a specified pages. +/// +class PageNumberFinder { + // Maps node to a start/end page numbers. + // This is used to override baseline page numbers provided by the collector when the document is split. + private Map nodeStartPageLookup = new HashMap<>(); + private Map nodeEndPageLookup = new HashMap<>(); + private LayoutCollector collector; + + // Maps page number to a list of nodes found on that page. + private Map> reversePageLookup; + + /// + /// Initializes a new instance of the class. + /// + /// A collector instance that has layout model records for the document. + public PageNumberFinder(LayoutCollector collector) { + this.collector = collector; + } + + public Document getDocument() { + return collector.getDocument(); + } + + /// + /// Retrieves 1-based index of a page that the node begins on. + /// + /// + /// The node. + /// + /// + /// Page index. + /// + public int getPage(Node node) throws Exception { + return nodeStartPageLookup.containsKey(node) + ? nodeStartPageLookup.get(node) + : collector.getStartPageIndex(node); + } + + /// + /// Retrieves 1-based index of a page that the node ends on. + /// + /// + /// The node. + /// + /// + /// Page index. + /// + public int getPageEnd(Node node) throws Exception { + return nodeEndPageLookup.containsKey(node) + ? nodeEndPageLookup.get(node) + : collector.getEndPageIndex(node); + } + + /// + /// Returns how many pages the specified node spans over. Returns 1 if the node is contained within one page. + /// + /// + /// The node. + /// + /// + /// Page index. + /// + public int pageSpan(Node node) throws Exception { + return getPageEnd(node) - getPage(node) + 1; + } + + /// + /// Returns a list of nodes that are contained anywhere on the specified page or pages which match the specified node type. + /// + /// + /// The start Page. + /// + /// + /// The end Page. + /// + /// + /// The node Type. + /// + /// + /// The . + /// + public ArrayList retrieveAllNodesOnPages(int startPage, int endPage, /*NodeType*/int nodeType) throws Exception { + if (startPage < 1 || startPage > collector.getDocument().getPageCount()) { + throw new IllegalStateException("'startPage' is out of range"); + } + + if (endPage < 1 || endPage > collector.getDocument().getPageCount() || endPage < startPage) { + throw new IllegalStateException("'endPage' is out of range"); + } + + checkPageListsPopulated(); + + ArrayList pageNodes = new ArrayList<>(); + for (int page = startPage; page <= endPage; page++) { + // Some pages can be empty. + if (!reversePageLookup.containsKey(page)) { + continue; + } + + for (Node node : reversePageLookup.get(page)) { + if (node.getParentNode() != null + && (nodeType == NodeType.ANY || node.getNodeType() == nodeType) + && !pageNodes.contains(node)) { + pageNodes.add(node); + } + } + } + + return pageNodes; + } + + /// + /// Splits nodes that appear over two or more pages into separate nodes so that they still appear in the same way + /// but no longer appear across a page. + /// + public void splitNodesAcrossPages() throws Exception { + for (Paragraph paragraph : (Iterable) collector.getDocument().getChildNodes(NodeType.PARAGRAPH, true)) { + if (getPage(paragraph) != getPageEnd(paragraph)) { + splitRunsByWords(paragraph); + } + } + + clearCollector(); + + // Visit any composites which are possibly split across pages and split them into separate nodes. + collector.getDocument().accept(new SectionSplitter(this)); + } + + /// + /// This is called by to update page numbers of split nodes. + /// + /// + /// The node. + /// + /// + /// The start Page. + /// + /// + /// The end Page. + /// + void addPageNumbersForNode(Node node, int startPage, int endPage) { + if (startPage > 0) { + nodeStartPageLookup.put(node, startPage); + } + + if (endPage > 0) { + nodeEndPageLookup.put(node, endPage); + } + } + + private boolean isHeaderFooterType(Node node) { + return node.getNodeType() == NodeType.HEADER_FOOTER || node.getAncestor(NodeType.HEADER_FOOTER) != null; + } + + private void checkPageListsPopulated() throws Exception { + if (reversePageLookup != null) { + return; + } + + reversePageLookup = new HashMap<>(); + + // Add each node to a list that represent the nodes found on each page. + for (Node node : (Iterable) collector.getDocument().getChildNodes(NodeType.ANY, true)) { + // Headers/Footers follow sections and are not split by themselves. + if (isHeaderFooterType(node)) { + continue; + } + + int startPage = getPage(node); + int endPage = getPageEnd(node); + for (int page = startPage; page <= endPage; page++) { + if (!reversePageLookup.containsKey(page)) { + reversePageLookup.put(page, new ArrayList()); + } + + reversePageLookup.get(page).add(node); + } + } + } + + private void splitRunsByWords(Paragraph paragraph) throws Exception { + for (Run run : paragraph.getRuns()) { + if (getPage(run) == getPageEnd(run)) { + continue; + } + + splitRunByWords(run); + } + } + + private void splitRunByWords(Run run) { + String[] words = reverseWord(run.getText()); + + for (String word : words) { + int pos = run.getText().length() - word.length() - 1; + if (pos > 1) { + splitRun(run, run.getText().length() - word.length() - 1); + } + } + } + + private static String[] reverseWord(String str) { + String words[] = str.split(" "); + String reverseWord = ""; + + for (String w : words) { + StringBuilder sb = new StringBuilder(w); + sb.reverse(); + reverseWord += sb.toString() + " "; + } + + return reverseWord.split(" "); + } + + /// + /// Splits text of the specified run into two runs. + /// Inserts the new run just after the specified run. + /// + private void splitRun(Run run, int position) { + Run afterRun = (Run) run.deepClone(true); + afterRun.setText(run.getText().substring(position)); + run.setText(run.getText().substring((0), (0) + (position))); + run.getParentNode().insertAfter(afterRun, run); + } + + private void clearCollector() throws Exception { + collector.clear(); + collector.getDocument().updatePageLayout(); + + nodeStartPageLookup.clear(); + nodeEndPageLookup.clear(); + } +} + +class PageNumberFinderFactory { + public static PageNumberFinder create(Document document) throws Exception { + LayoutCollector layoutCollector = new LayoutCollector(document); + document.updatePageLayout(); + PageNumberFinder pageNumberFinder = new PageNumberFinder(layoutCollector); + pageNumberFinder.splitNodesAcrossPages(); + return pageNumberFinder; + } +} + +/// +/// Splits a document into multiple sections so that each page begins and ends at a section boundary. +/// +class SectionSplitter extends DocumentVisitor { + private PageNumberFinder pageNumberFinder; + + public SectionSplitter(PageNumberFinder pageNumberFinder) { + this.pageNumberFinder = pageNumberFinder; + } + + public int visitParagraphStart(Paragraph paragraph) throws Exception { + return continueIfCompositeAcrossPageElseSkip(paragraph); + } + + public int visitTableStart(Table table) throws Exception { + return continueIfCompositeAcrossPageElseSkip(table); + } + + public int visitRowStart(Row row) throws Exception { + return continueIfCompositeAcrossPageElseSkip(row); + } + + public int visitCellStart(Cell cell) throws Exception { + return continueIfCompositeAcrossPageElseSkip(cell); + } + + public int visitStructuredDocumentTagStart(StructuredDocumentTag sdt) throws Exception { + return continueIfCompositeAcrossPageElseSkip(sdt); + } + + public int visitSmartTagStart(SmartTag smartTag) throws Exception { + return continueIfCompositeAcrossPageElseSkip(smartTag); + } + + public int visitSectionStart(Section section) throws Exception { + Section previousSection = (Section) section.getPreviousSibling(); + + // If there is a previous section, attempt to copy any linked header footers. + // Otherwise, they will not appear in an extracted document if the previous section is missing. + if (previousSection != null) { + HeaderFooterCollection previousHeaderFooters = previousSection.getHeadersFooters(); + if (!section.getPageSetup().getRestartPageNumbering()) { + section.getPageSetup().setRestartPageNumbering(true); + section.getPageSetup().setPageStartingNumber(previousSection.getPageSetup().getPageStartingNumber() + + pageNumberFinder.pageSpan(previousSection)); + } + + for (HeaderFooter previousHeaderFooter : (Iterable) previousHeaderFooters) { + if (section.getHeadersFooters().getByHeaderFooterType(previousHeaderFooter.getHeaderFooterType()) == null) { + HeaderFooter newHeaderFooter = + (HeaderFooter) previousHeaderFooters.getByHeaderFooterType(previousHeaderFooter.getHeaderFooterType()).deepClone(true); + section.getHeadersFooters().add(newHeaderFooter); + } + } + } + + return continueIfCompositeAcrossPageElseSkip(section); + } + + public int visitSmartTagEnd(SmartTag smartTag) throws Exception { + splitComposite(smartTag); + return VisitorAction.CONTINUE; + } + + public int visitStructuredDocumentTagEnd(StructuredDocumentTag sdt) throws Exception { + splitComposite(sdt); + return VisitorAction.CONTINUE; + } + + public int visitCellEnd(Cell cell) throws Exception { + splitComposite(cell); + return VisitorAction.CONTINUE; + } + + public int visitRowEnd(Row row) throws Exception { + splitComposite(row); + return VisitorAction.CONTINUE; + } + + public int visitTableEnd(Table table) throws Exception { + splitComposite(table); + return VisitorAction.CONTINUE; + } + + public int visitParagraphEnd(Paragraph paragraph) throws Exception { + // If the paragraph contains only section break, add fake run into. + if (paragraph.isEndOfSection() && paragraph.getChildNodes(NodeType.ANY, false).getCount() == 1 && + "\f".equals(paragraph.getChildNodes(NodeType.ANY, false).get(0).getText())) { + Run run = new Run(paragraph.getDocument()); + paragraph.appendChild(run); + int currentEndPageNum = pageNumberFinder.getPageEnd(paragraph); + pageNumberFinder.addPageNumbersForNode(run, currentEndPageNum, currentEndPageNum); + } + + for (Node cloneNode : splitComposite(paragraph)) { + Paragraph clonePara = (Paragraph) cloneNode; + // Remove list numbering from the cloned paragraph but leave the indent the same + // as the paragraph is supposed to be part of the item before. + if (paragraph.isListItem()) { + double textPosition = clonePara.getListFormat().getListLevel().getTextPosition(); + clonePara.getListFormat().removeNumbers(); + clonePara.getParagraphFormat().setLeftIndent(textPosition); + } + + // Reset spacing of split paragraphs in tables as additional spacing may cause them to look different. + if (paragraph.isInCell()) { + clonePara.getParagraphFormat().setSpaceBefore(0.0); + paragraph.getParagraphFormat().setSpaceAfter(0.0); + } + } + + return VisitorAction.CONTINUE; + } + + public int visitSectionEnd(Section section) throws Exception { + for (Node cloneNode : splitComposite(section)) { + Section cloneSection = (Section) cloneNode; + + cloneSection.getPageSetup().setSectionStart(SectionStart.NEW_PAGE); + cloneSection.getPageSetup().setRestartPageNumbering(true); + cloneSection.getPageSetup().setPageStartingNumber(section.getPageSetup().getPageStartingNumber() + + (section.getDocument().indexOf(cloneSection) - + section.getDocument().indexOf(section))); + cloneSection.getPageSetup().setDifferentFirstPageHeaderFooter(false); + + // Corrects page break at the end of the section. + SplitPageBreakCorrector.processSection(cloneSection); + } + + SplitPageBreakCorrector.processSection(section); + + // Add new page numbering for the body of the section as well. + pageNumberFinder.addPageNumbersForNode(section.getBody(), pageNumberFinder.getPage(section), + pageNumberFinder.getPageEnd(section)); + return VisitorAction.CONTINUE; + } + + private int continueIfCompositeAcrossPageElseSkip(CompositeNode composite) throws Exception { + return pageNumberFinder.pageSpan(composite) > 1 + ? VisitorAction.CONTINUE + : VisitorAction.SKIP_THIS_NODE; + } + + private ArrayList splitComposite(CompositeNode composite) throws Exception { + ArrayList splitNodes = new ArrayList<>(); + for (Node splitNode : findChildSplitPositions(composite)) { + splitNodes.add(splitCompositeAtNode(composite, splitNode)); + } + + return splitNodes; + } + + private Iterable findChildSplitPositions(CompositeNode node) throws Exception { + // A node may span across multiple pages, so a list of split positions is returned. + // The split node is the first node on the next page. + ArrayList splitList = new ArrayList(); + + int startingPage = pageNumberFinder.getPage(node); + + Node[] childNodes = node.getNodeType() == NodeType.SECTION + ? ((Section) node).getBody().getChildNodes(NodeType.ANY, false).toArray() + : node.getChildNodes(NodeType.ANY, false).toArray(); + for (Node childNode : childNodes) { + int pageNum = pageNumberFinder.getPage(childNode); + + if (childNode instanceof Run) { + pageNum = pageNumberFinder.getPageEnd(childNode); + } + + // If the page of the child node has changed, then this is the split position. + // Add this to the list. + if (pageNum > startingPage) { + splitList.add(childNode); + startingPage = pageNum; + } + + if (pageNumberFinder.pageSpan(childNode) > 1) { + pageNumberFinder.addPageNumbersForNode(childNode, pageNum, pageNum); + } + } + + // Split composites backward, so the cloned nodes are inserted in the right order. + Collections.reverse(splitList); + return splitList; + } + + private CompositeNode splitCompositeAtNode(CompositeNode baseNode, Node targetNode) throws Exception { + CompositeNode cloneNode = (CompositeNode) baseNode.deepClone(false); + Node node = targetNode; + int currentPageNum = pageNumberFinder.getPage(baseNode); + + // Move all nodes found on the next page into the copied node. Handle row nodes separately. + if (baseNode.getNodeType() != NodeType.ROW) { + CompositeNode composite = cloneNode; + if (baseNode.getNodeType() == NodeType.SECTION) { + cloneNode = (CompositeNode) baseNode.deepClone(true); + Section section = (Section) cloneNode; + section.getBody().removeAllChildren(); + composite = section.getBody(); + } + + while (node != null) { + Node nextNode = node.getNextSibling(); + composite.appendChild(node); + node = nextNode; + } + } else { + // If we are dealing with a row, we need to add dummy cells for the cloned row. + int targetPageNum = pageNumberFinder.getPage(targetNode); + + Node[] childNodes = baseNode.getChildNodes(NodeType.ANY, false).toArray(); + for (Node childNode : childNodes) { + int pageNum = pageNumberFinder.getPage(childNode); + if (pageNum == targetPageNum) { + if (cloneNode.getNodeType() == NodeType.ROW) + ((Row) cloneNode).ensureMinimum(); + + if (cloneNode.getNodeType() == NodeType.CELL) + ((Cell) cloneNode).ensureMinimum(); + + cloneNode.getLastChild().remove(); + cloneNode.appendChild(childNode); + } else if (pageNum == currentPageNum) { + cloneNode.appendChild(childNode.deepClone(false)); + if (cloneNode.getLastChild().getNodeType() != NodeType.CELL) { + ((CompositeNode) cloneNode.getLastChild()).appendChild( + ((CompositeNode) childNode).getFirstChild().deepClone(false)); + } + } + } + } + + // Insert the split node after the original. + baseNode.getParentNode().insertAfter(cloneNode, baseNode); + + // Update the new page numbers of the base node and the cloned node, including its descendants. + // This will only be a single page as the cloned composite is split to be on one page. + int currentEndPageNum = pageNumberFinder.getPageEnd(baseNode); + pageNumberFinder.addPageNumbersForNode(baseNode, currentPageNum, currentEndPageNum - 1); + pageNumberFinder.addPageNumbersForNode(cloneNode, currentEndPageNum, currentEndPageNum); + for (Node childNode : (Iterable) cloneNode.getChildNodes(NodeType.ANY, true)) { + pageNumberFinder.addPageNumbersForNode(childNode, currentEndPageNum, currentEndPageNum); + } + + return cloneNode; + } +} + +class SplitPageBreakCorrector { + private static final String PAGE_BREAK_STR = "\f"; + private static final char PAGE_BREAK = '\f'; + + public static void processSection(Section section) { + if (section.getChildNodes(NodeType.ANY, false).getCount() == 0) { + return; + } + + Body lastBody = (Body) Arrays.stream(new Iterator[]{section.getChildNodes(NodeType.ANY, false).iterator()}).reduce((first, second) -> second) + .orElse(null); + + RunCollection runs = (RunCollection) lastBody.getChildNodes(NodeType.RUN, true).iterator(); + Run run = Arrays.stream(runs.toArray()).filter(p -> p.getText().endsWith(PAGE_BREAK_STR)).findFirst().get(); + + if (run != null) { + removePageBreak(run); + } + } + + public void removePageBreakFromParagraph(Paragraph paragraph) { + Run run = (Run) paragraph.getFirstChild(); + if (PAGE_BREAK_STR.equals(run.getText())) { + paragraph.removeChild(run); + } + } + + private void processLastParagraph(Paragraph paragraph) { + Node lastNode = paragraph.getChildNodes(NodeType.ANY, false).get(paragraph.getChildNodes(NodeType.ANY, false).getCount() - 1); + if (lastNode.getNodeType() != NodeType.RUN) { + return; + } + + Run run = (Run) lastNode; + removePageBreak(run); + } + + private static void removePageBreak(Run run) { + Paragraph paragraph = run.getParentParagraph(); + + if (PAGE_BREAK_STR.equals(run.getText())) { + paragraph.removeChild(run); + } else if (run.getText().endsWith(PAGE_BREAK_STR)) { + run.setText(StringUtils.stripEnd(run.getText(), String.valueOf(PAGE_BREAK))); + } + + if (paragraph.getChildNodes(NodeType.ANY, false).getCount() == 0) { + CompositeNode parent = paragraph.getParentNode(); + parent.removeChild(paragraph); + } + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Split_documents/SplitDocument.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Split_documents/SplitDocument.java new file mode 100644 index 00000000..97a52e6c --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Split_documents/SplitDocument.java @@ -0,0 +1,124 @@ +package DocsExamples.Programming_with_documents.Split_documents; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.filefilter.WildcardFileFilter; +import org.testng.annotations.Test; + +import java.io.File; +import java.text.MessageFormat; +import java.util.Collection; + +@Test +public class SplitDocument extends DocsExamplesBase { + @Test + public void byHeadings() throws Exception { + //ExStart:SplitDocumentByHeadings + //GistId:c2ec8aa36ef37670eceec8da5c612b86 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlSaveOptions options = new HtmlSaveOptions(); + // Split a document into smaller parts, in this instance split by heading. + options.setDocumentSplitCriteria(DocumentSplitCriteria.HEADING_PARAGRAPH); + + doc.save(getArtifactsDir() + "SplitDocument.ByHeadings.epub", options); + //ExEnd:SplitDocumentByHeadings + } + + @Test + public void bySectionsHtml() throws Exception { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + //ExStart:SplitDocumentBySectionsHtml + //GistId:961539231ee8e8975461be3947e750f6 + HtmlSaveOptions options = new HtmlSaveOptions(); + options.setDocumentSplitCriteria(DocumentSplitCriteria.SECTION_BREAK); + //ExEnd:SplitDocumentBySectionsHtml + + doc.save(getArtifactsDir() + "SplitDocument.BySections.html", options); + } + + @Test + public void bySections() throws Exception { + //ExStart:SplitDocumentBySections + //GistId:961539231ee8e8975461be3947e750f6 + Document doc = new Document(getMyDir() + "Big document.docx"); + + for (int i = 0; i < doc.getSections().getCount(); i++) { + // Split a document into smaller parts, in this instance, split by section. + Section section = doc.getSections().get(i).deepClone(); + + Document newDoc = new Document(); + newDoc.getSections().clear(); + + Section newSection = (Section) newDoc.importNode(section, true); + newDoc.getSections().add(newSection); + + // Save each section as a separate document. + newDoc.save(getArtifactsDir() + MessageFormat.format("SplitDocument.BySections_{0}.docx", i)); + } + //ExEnd:SplitDocumentBySections + } + + @Test + public void pageByPage() throws Exception { + //ExStart:SplitDocumentPageByPage + //GistId:961539231ee8e8975461be3947e750f6 + Document doc = new Document(getMyDir() + "Big document.docx"); + + int pageCount = doc.getPageCount(); + + for (int page = 0; page < pageCount; page++) { + // Save each page as a separate document. + Document extractedPage = doc.extractPages(page, 1); + extractedPage.save(getArtifactsDir() + MessageFormat.format("SplitDocument.PageByPage_{0}.docx", page + 1)); + } + //ExEnd:SplitDocumentPageByPage + + mergeDocuments(); + } + + //ExStart:MergeSplitDocuments + //GistId:961539231ee8e8975461be3947e750f6 + private void mergeDocuments() throws Exception { + // Find documents using for merge. + File directory = new File(getArtifactsDir()); + Collection documentPaths = FileUtils.listFiles(directory, new WildcardFileFilter("SplitDocument.PageByPage_*.docx"), null); + + String sourceDocumentPath = + FileUtils.getFile(getArtifactsDir(), "SplitDocument.PageByPage_1.docx").getPath(); + + // Open the first part of the resulting document. + Document sourceDoc = new Document(sourceDocumentPath); + + // Create a new resulting document. + Document mergedDoc = new Document(); + DocumentBuilder mergedDocBuilder = new DocumentBuilder(mergedDoc); + + // Merge document parts one by one. + for (File documentPath : documentPaths) { + if (documentPath.getName().equals(sourceDocumentPath)) + continue; + + mergedDocBuilder.moveToDocumentEnd(); + mergedDocBuilder.insertDocument(sourceDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + sourceDoc = new Document(documentPath.getPath()); + } + + mergedDoc.save(getArtifactsDir() + "SplitDocument.MergeDocuments.docx"); + } + //ExEnd:MergeSplitDocuments + + @Test + public void byPageRange() throws Exception { + //ExStart:SplitDocumentByPageRange + //GistId:961539231ee8e8975461be3947e750f6 + Document doc = new Document(getMyDir() + "Big document.docx"); + + // Get part of the document. + Document extractedPages = doc.extractPages(3, 6); + extractedPages.save(getArtifactsDir() + "SplitDocument.ByPageRange.docx"); + //ExEnd:SplitDocumentByPageRange + } +} \ No newline at end of file diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Split_documents/SplitIntoHtmlPages.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Split_documents/SplitIntoHtmlPages.java new file mode 100644 index 00000000..39d7ac2f --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Split_documents/SplitIntoHtmlPages.java @@ -0,0 +1,255 @@ +package DocsExamples.Programming_with_documents.Split_documents; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import com.aspose.words.ref.Ref; +import org.testng.annotations.Test; + +import java.io.File; +import java.util.ArrayList; + +@Test +public class SplitIntoHtmlPages extends DocsExamplesBase { + @Test + public void htmlPages() throws Exception { + String srcFileName = getMyDir() + "Footnotes and endnotes.docx"; + String tocTemplate = getMyDir() + "Table of content template.docx"; + + String outDir = getArtifactsDir() + "HtmlPages"; + new File(outDir).mkdir(); + + WordToHtmlConverter w = new WordToHtmlConverter(); + w.execute(srcFileName, tocTemplate, outDir); + } +} + +class WordToHtmlConverter { + /// + /// Performs the Word to HTML conversion. + /// + /// The MS Word file to convert. + /// An MS Word file that is used as a template to build a table of contents. + /// This file needs to have a mail merge region called "TOC" defined and one mail merge field called "TocEntry". + /// The output directory where to write HTML files. + void execute(String srcFileName, String tocTemplate, String dstDir) throws Exception { + mDoc = new Document(srcFileName); + mTocTemplate = tocTemplate; + mDstDir = dstDir; + + ArrayList topicStartParas = selectTopicStarts(); + insertSectionBreaks(topicStartParas); + ArrayList topics = saveHtmlTopics(); + saveTableOfContents(topics); + } + + /// + /// Selects heading paragraphs that must become topic starts. + /// We can't modify them in this loop, so we need to remember them in an array first. + /// + private ArrayList selectTopicStarts() { + NodeCollection paras = mDoc.getChildNodes(NodeType.PARAGRAPH, true); + ArrayList topicStartParas = new ArrayList(); + + for (Paragraph para : (Iterable) paras) { + int style = para.getParagraphFormat().getStyleIdentifier(); + if (style == StyleIdentifier.HEADING_1) + topicStartParas.add(para); + } + + return topicStartParas; + } + + //ExStart:InsertSectionBreaks + //GistId:7c0668453e53ed7a57d3ea3a05520f21 + /// + /// Insert section breaks before the specified paragraphs. + /// + private void insertSectionBreaks(ArrayList topicStartParas) { + DocumentBuilder builder = new DocumentBuilder(mDoc); + for (Paragraph para : topicStartParas) { + Section section = para.getParentSection(); + + // Insert section break if the paragraph is not at the beginning of a section already. + if (para != section.getBody().getFirstParagraph()) { + builder.moveTo(para.getFirstChild()); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + + // This is the paragraph that was inserted at the end of the now old section. + // We don't really need the extra paragraph, we just needed the section. + section.getBody().getLastParagraph().remove(); + } + } + } + //ExEnd:InsertSectionBreaks + + /// + /// Splits the current document into one topic per section and saves each topic + /// as an HTML file. Returns a collection of Topic objects. + /// + private ArrayList saveHtmlTopics() throws Exception { + ArrayList topics = new ArrayList(); + for (int sectionIdx = 0; sectionIdx < mDoc.getSections().getCount(); sectionIdx++) { + Section section = mDoc.getSections().get(sectionIdx); + + String paraText = section.getBody().getFirstParagraph().getText(); + + // Use the text of the heading paragraph to generate the HTML file name. + String fileName = makeTopicFileName(paraText); + if ("".equals(fileName)) + fileName = "UNTITLED SECTION " + sectionIdx; + + fileName = mDstDir + fileName + ".html"; + + // Use the text of the heading paragraph to generate the title for the TOC. + String title = makeTopicTitle(paraText); + if ("".equals(title)) + title = "UNTITLED SECTION " + sectionIdx; + + Topic topic = new Topic(title, fileName); + topics.add(topic); + + saveHtmlTopic(section, topic); + } + + return topics; + } + + /// + /// Leaves alphanumeric characters, replaces white space with underscore + /// And removes all other characters from a string. + /// + private String makeTopicFileName(String paraText) { + StringBuilder b = new StringBuilder(); + for (int i = 0; i < paraText.length(); i++) { + char c = paraText.charAt(i); + if (Character.isLetterOrDigit(c)) + b.append(c); + else if (c == ' ') + b.append('_'); + } + + return b.toString(); + } + + /// + /// Removes the last character (which is a paragraph break character from the given string). + /// + private String makeTopicTitle(String paraText) { + return paraText.substring((0), (0) + (paraText.length() - 1)); + } + + /// + /// Saves one section of a document as an HTML file. + /// Any embedded images are saved as separate files in the same folder as the HTML file. + /// + private void saveHtmlTopic(Section section, Topic topic) throws Exception { + Document dummyDoc = new Document(); + dummyDoc.removeAllChildren(); + dummyDoc.appendChild(dummyDoc.importNode(section, true, ImportFormatMode.KEEP_SOURCE_FORMATTING)); + + dummyDoc.getBuiltInDocumentProperties().setTitle(topic.getTitle()); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + saveOptions.setPrettyFormat(true); + saveOptions.setAllowNegativeIndent(true); // This is to allow headings to appear to the left of the main text. + saveOptions.setExportHeadersFootersMode(ExportHeadersFootersMode.NONE); + + dummyDoc.save(topic.getFileName(), saveOptions); + } + + /// + /// Generates a table of contents for the topics and saves to contents .html. + /// + private void saveTableOfContents(ArrayList topics) throws Exception { + Document tocDoc = new Document(mTocTemplate); + + // We use a custom mail merge event handler defined below, + // and a custom mail merge data source based on collecting the topics we created. + tocDoc.getMailMerge().setFieldMergingCallback(new HandleTocMergeField()); + tocDoc.getMailMerge().executeWithRegions(new TocMailMergeDataSource(topics)); + + tocDoc.save(mDstDir + "contents.html"); + } + + private static class HandleTocMergeField implements IFieldMergingCallback { + public void fieldMerging(FieldMergingArgs e) throws Exception { + if (mBuilder == null) + mBuilder = new DocumentBuilder(e.getDocument()); + + // Our custom data source returns topic objects. + Topic topic = (Topic) e.getFieldValue(); + + mBuilder.moveToMergeField(e.getFieldName()); + mBuilder.insertHyperlink(topic.getTitle(), topic.getFileName(), false); + + // Signal to the mail merge engine that it does not need to insert text into the field. + e.setText(""); + } + + public void imageFieldMerging(ImageFieldMergingArgs args) { + // Do nothing. + } + + private DocumentBuilder mBuilder; + } + + private Document mDoc; + private String mTocTemplate; + private String mDstDir; +} + +class Topic { + Topic(String title, String fileName) { + mTitle = title; + mFileName = fileName; + } + + String getTitle() { + return mTitle; + } + private String mTitle; + + String getFileName() { + return mFileName; + } + private String mFileName; +} + +class TocMailMergeDataSource implements IMailMergeDataSource { + TocMailMergeDataSource(ArrayList topics) { + mTopics = topics; + mIndex = -1; + } + + @Override + public String getTableName() { + return "TOC"; + } + + public boolean moveNext() { + if (mIndex < mTopics.size() - 1) { + mIndex++; + return true; + } + + return false; + } + + public boolean getValue(String fieldName, /*out*/Ref fieldValue) { + if ("TocEntry".equals(fieldName)) { + // The template document is supposed to have only one field called "TocEntry". + fieldValue.set(mTopics.get(mIndex)); + return true; + } + + fieldValue.set(null); + return false; + } + + public IMailMergeDataSource getChildDataSource(String tableName) { + return null; + } + + private ArrayList mTopics; + private int mIndex; +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithComments.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithComments.java new file mode 100644 index 00000000..628d4ad8 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithComments.java @@ -0,0 +1,211 @@ +package DocsExamples.Programming_with_documents; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +@Test +public class WorkingWithComments extends DocsExamplesBase { + @Test + public void addComments() throws Exception { + //ExStart:AddComments + //GistId:70902b20df8b1f6b0459f676e21623bb + //ExStart:CreateSimpleDocumentUsingDocumentBuilder + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Some text is added."); + //ExEnd:CreateSimpleDocumentUsingDocumentBuilder + + Comment comment = new Comment(doc, "Awais Hafeez", "AH", new Date()); + comment.setText("Comment text."); + + builder.getCurrentParagraph().appendChild(comment); + + doc.save(getArtifactsDir() + "WorkingWithComments.AddComments.docx"); + //ExEnd:AddComments + } + + @Test + public void anchorComment() throws Exception { + //ExStart:AnchorComment + //GistId:70902b20df8b1f6b0459f676e21623bb + Document doc = new Document(); + + Paragraph para1 = new Paragraph(doc); + Run run1 = new Run(doc, "Some "); + Run run2 = new Run(doc, "text "); + para1.appendChild(run1); + para1.appendChild(run2); + doc.getFirstSection().getBody().appendChild(para1); + + Paragraph para2 = new Paragraph(doc); + Run run3 = new Run(doc, "is "); + Run run4 = new Run(doc, "added "); + para2.appendChild(run3); + para2.appendChild(run4); + doc.getFirstSection().getBody().appendChild(para2); + + Comment comment = new Comment(doc, "Awais Hafeez", "AH", new Date()); + comment.getParagraphs().add(new Paragraph(doc)); + comment.getFirstParagraph().getRuns().add(new Run(doc, "Comment text.")); + + CommentRangeStart commentRangeStart = new CommentRangeStart(doc, comment.getId()); + CommentRangeEnd commentRangeEnd = new CommentRangeEnd(doc, comment.getId()); + + run1.getParentNode().insertAfter(commentRangeStart, run1); + run3.getParentNode().insertAfter(commentRangeEnd, run3); + commentRangeEnd.getParentNode().insertAfter(comment, commentRangeEnd); + + doc.save(getArtifactsDir() + "WorkingWithComments.AnchorComment.doc"); + //ExEnd:AnchorComment + } + + @Test + public void addRemoveCommentReply() throws Exception { + //ExStart:AddRemoveCommentReply + //GistId:70902b20df8b1f6b0459f676e21623bb + Document doc = new Document(getMyDir() + "Comments.docx"); + + Comment comment = (Comment) doc.getChild(NodeType.COMMENT, 0, true); + comment.removeReply(comment.getReplies().get(0)); + + Calendar calendar = new GregorianCalendar(2017, Calendar.SEPTEMBER, 25); + calendar.set(Calendar.HOUR, 12); + calendar.set(Calendar.MINUTE, 15); + calendar.set(Calendar.SECOND, 0); + + comment.addReply("John Doe", "JD", calendar.getTime(), "New reply"); + + doc.save(getArtifactsDir() + "WorkingWithComments.AddRemoveCommentReply.docx"); + //ExEnd:AddRemoveCommentReply + } + + @Test + public void processComments() throws Exception { + //ExStart:ProcessComments + //GistId:70902b20df8b1f6b0459f676e21623bb + Document doc = new Document(getMyDir() + "Comments.docx"); + + // Extract the information about the comments of all the authors. + for (String comment : extractComments(doc)) + System.out.println(comment); + + // Remove comments by the "pm" author. + removeComments(doc, "pm"); + System.out.println("Comments from \"pm\" are removed!"); + + // Extract the information about the comments of the "ks" author. + for (String comment : extractComments(doc, "ks")) + System.out.println(comment); + + // Read the comment's reply and resolve them. + commentResolvedAndReplies(doc); + + // Remove all comments. + removeComments(doc); + System.out.println("All comments are removed!"); + + doc.save(getArtifactsDir() + "WorkingWithComments.ProcessComments.docx"); + //ExEnd:ProcessComments + } + + //ExStart:ExtractComments + //GistId:70902b20df8b1f6b0459f676e21623bb + private ArrayList extractComments(Document doc) throws Exception { + ArrayList collectedComments = new ArrayList(); + NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true); + + for (Comment comment : (Iterable) comments) { + collectedComments.add(comment.getAuthor() + " " + comment.getDateTime() + " " + + comment.toString(SaveFormat.TEXT)); + } + + return collectedComments; + } + //ExEnd:ExtractComments + + //ExStart:ExtractCommentsByAuthor + //GistId:70902b20df8b1f6b0459f676e21623bb + private ArrayList extractComments(Document doc, String authorName) throws Exception { + ArrayList collectedComments = new ArrayList(); + NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true); + + for (Comment comment : (Iterable) comments) { + if (comment.getAuthor().equals(authorName)) + collectedComments.add(comment.getAuthor() + " " + comment.getDateTime() + " " + + comment.toString(SaveFormat.TEXT)); + } + + return collectedComments; + } + //ExEnd:ExtractCommentsByAuthor + + //ExStart:RemoveComments + //GistId:70902b20df8b1f6b0459f676e21623bb + private void removeComments(Document doc) { + NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true); + comments.clear(); + } + //ExEnd:RemoveComments + + //ExStart:RemoveCommentsByAuthor + //GistId:70902b20df8b1f6b0459f676e21623bb + private void removeComments(Document doc, String authorName) { + NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true); + + // Look through all comments and remove those written by the authorName. + for (int i = comments.getCount() - 1; i >= 0; i--) { + Comment comment = (Comment) comments.get(i); + if (comment.getAuthor().equals(authorName)) + comment.remove(); + } + } + //ExEnd:RemoveCommentsByAuthor + + //ExStart:CommentResolvedAndReplies + //GistId:70902b20df8b1f6b0459f676e21623bb + private void commentResolvedAndReplies(Document doc) { + NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true); + + Comment parentComment = (Comment) comments.get(0); + for (Comment childComment : parentComment.getReplies()) { + // Get comment parent and status. + System.out.println(childComment.getAncestor().getId()); + System.out.println(childComment.getDone()); + + // And update comment Done mark. + childComment.setDone(true); + } + } + //ExEnd:CommentResolvedAndReplies + + @Test + public void removeRangeText() throws Exception { + //ExStart:RemoveRangeText + //GistId:70902b20df8b1f6b0459f676e21623bb + Document doc = new Document(getMyDir() + "Comments.docx"); + + CommentRangeStart commentStart = (CommentRangeStart) doc.getChild(NodeType.COMMENT_RANGE_START, 0, true); + Node currentNode = commentStart; + + boolean isRemoving = true; + while (currentNode != null && isRemoving) { + if (currentNode.getNodeType() == NodeType.COMMENT_RANGE_END) + isRemoving = false; + + Node nextNode = currentNode.nextPreOrder(doc); + currentNode.remove(); + currentNode = nextNode; + } + + doc.save(getArtifactsDir() + "WorkingWithComments.RemoveRangeText.docx"); + //ExEnd:RemoveRangeText + } +} + diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithFields.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithFields.java new file mode 100644 index 00000000..642e6c98 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithFields.java @@ -0,0 +1,768 @@ +package DocsExamples.Programming_with_documents; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import com.aspose.words.net.System.Globalization.CultureInfo; +import com.aspose.words.net.System.Globalization.DateTimeFormatInfo; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.time.LocalDate; +import java.time.Month; +import java.util.ArrayList; +import java.util.Date; +import java.util.Locale; + +@Test +public class WorkingWithFields extends DocsExamplesBase { + @Test + public void fieldCode() throws Exception { + //ExStart:FieldCode + //GistId:7c2b7b650a88375b1d438746f78f0d64 + Document doc = new Document(getMyDir() + "Hyperlinks.docx"); + + for (Field field : doc.getRange().getFields()) { + String fieldCode = field.getFieldCode(); + String fieldResult = field.getResult(); + } + //ExEnd:FieldCode + } + + @Test + public void changeFieldUpdateCultureSource() throws Exception { + //ExStart:ChangeFieldUpdateCultureSource + //GistId:9e90defe4a7bcafb004f73a2ef236986 + //ExStart:DocumentBuilderInsertField + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert content with German locale. + builder.getFont().setLocaleId(1031); + builder.insertField("MERGEFIELD Date1 \\@ \"dddd, d MMMM yyyy\""); + builder.write(" - "); + builder.insertField("MERGEFIELD Date2 \\@ \"dddd, d MMMM yyyy\""); + //ExEnd:DocumentBuilderInsertField + + // Shows how to specify where the culture used for date formatting during field update and mail merge is chosen from + // set the culture used during field update to the culture used by the field. + doc.getFieldOptions().setFieldUpdateCultureSource(FieldUpdateCultureSource.FIELD_CODE); + doc.getMailMerge().execute(new String[]{"Date2"}, new Object[]{LocalDate.of(2011, Month.JANUARY, 1)}); + + doc.save(getArtifactsDir() + "WorkingWithFields.ChangeFieldUpdateCultureSource.docx"); + //ExEnd:ChangeFieldUpdateCultureSource + } + + @Test + public void specifyLocaleAtFieldLevel() throws Exception { + //ExStart:SpecifyLocaleAtFieldLevel + //GistId:1cf07762df56f15067d6aef90b14b3db + DocumentBuilder builder = new DocumentBuilder(); + + Field field = builder.insertField(FieldType.FIELD_DATE, true); + field.setLocaleId(1049); + + builder.getDocument().save(getArtifactsDir() + "WorkingWithFields.SpecifyLocaleAtFieldLevel.docx"); + //ExEnd:SpecifyLocaleAtFieldLevel + } + + @Test + public void replaceHyperlinks() throws Exception { + //ExStart:ReplaceHyperlinks + //GistId:0213851d47551e83af42233f4d075cf6 + Document doc = new Document(getMyDir() + "Hyperlinks.docx"); + + for (Field field : doc.getRange().getFields()) { + if (field.getType() == FieldType.FIELD_HYPERLINK) { + FieldHyperlink hyperlink = (FieldHyperlink) field; + + // Some hyperlinks can be local (links to bookmarks inside the document), ignore these. + if (hyperlink.getSubAddress() != null) + continue; + + hyperlink.setAddress("http://www.aspose.com"); + hyperlink.setResult("Aspose - The .NET & Java Component Publisher"); + } + } + + doc.save(getArtifactsDir() + "WorkingWithFields.ReplaceHyperlinks.docx"); + //ExEnd:ReplaceHyperlinks + } + + @Test + public void renameMergeFields() throws Exception { + //ExStart:RenameMergeFields + //GistId:bf0f8a6b40b69a5274ab3553315e147f + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField("MERGEFIELD MyMergeField1 \\* MERGEFORMAT"); + builder.insertField("MERGEFIELD MyMergeField2 \\* MERGEFORMAT"); + + for (Field f : doc.getRange().getFields()) { + if (f.getType() == FieldType.FIELD_MERGE_FIELD) { + FieldMergeField mergeField = (FieldMergeField) f; + mergeField.setFieldName(mergeField.getFieldName() + "_Renamed"); + mergeField.update(); + } + } + + doc.save(getArtifactsDir() + "WorkingWithFields.RenameMergeFields.docx"); + //ExEnd:RenameMergeFields + } + + @Test + public void removeField() throws Exception { + //ExStart:RemoveField + //GistId:8c604665c1b97795df7a1e665f6b44ce + Document doc = new Document(getMyDir() + "Various fields.docx"); + + Field field = doc.getRange().getFields().get(0); + field.remove(); + //ExEnd:RemoveField + } + + @Test + public void unlinkFields() throws Exception { + //ExStart:UnlinkFields + //GistId:f3592014d179ecb43905e37b2a68bc92 + Document doc = new Document(getMyDir() + "Various fields.docx"); + doc.unlinkFields(); + //ExEnd:UnlinkFields + } + + @Test + public void insertToaFieldWithoutDocumentBuilder() throws Exception { + //ExStart:InsertToaFieldWithoutDocumentBuilder + //GistId:1cf07762df56f15067d6aef90b14b3db + Document doc = new Document(); + Paragraph para = new Paragraph(doc); + + // We want to insert TA and TOA fields like this: + // { TA \c 1 \l "Value 0" } + // { TOA \c 1 } + + FieldTA fieldTA = (FieldTA) para.appendField(FieldType.FIELD_TOA_ENTRY, false); + fieldTA.setEntryCategory("1"); + fieldTA.setLongCitation("Value 0"); + + doc.getFirstSection().getBody().appendChild(para); + + para = new Paragraph(doc); + + FieldToa fieldToa = (FieldToa) para.appendField(FieldType.FIELD_TOA, false); + fieldToa.setEntryCategory("1"); + doc.getFirstSection().getBody().appendChild(para); + + fieldToa.update(); + + doc.save(getArtifactsDir() + "WorkingWithFields.InsertToaFieldWithoutDocumentBuilder.docx"); + //ExEnd:InsertToaFieldWithoutDocumentBuilder + } + + @Test + public void insertNestedFields() throws Exception { + //ExStart:InsertNestedFields + //GistId:1cf07762df56f15067d6aef90b14b3db + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + for (int i = 0; i < 5; i++) + builder.insertBreak(BreakType.PAGE_BREAK); + + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + + // We want to insert a field like this: + // { IF {PAGE} <> {NUMPAGES} "See Next Page" "Last Page" } + Field field = builder.insertField("IF "); + builder.moveTo(field.getSeparator()); + builder.insertField("PAGE"); + builder.write(" <> "); + builder.insertField("NUMPAGES"); + builder.write(" \"See Next Page\" \"Last Page\" "); + + field.update(); + + doc.save(getArtifactsDir() + "WorkingWithFields.InsertNestedFields.docx"); + //ExEnd:InsertNestedFields + } + + @Test + public void insertMergeFieldUsingDom() throws Exception { + //ExStart:InsertMergeFieldUsingDom + //GistId:1cf07762df56f15067d6aef90b14b3db + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Paragraph para = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 0, true); + builder.moveTo(para); + + // We want to insert a merge field like this: + // { " MERGEFIELD Test1 \\b Test2 \\f Test3 \\m \\v" } + FieldMergeField field = (FieldMergeField) builder.insertField(FieldType.FIELD_MERGE_FIELD, false); + // { " MERGEFIELD Test1" } + field.setFieldName("Test1"); + // { " MERGEFIELD Test1 \\b Test2" } + field.setTextBefore("Test2"); + // { " MERGEFIELD Test1 \\b Test2 \\f Test3 } + field.setTextAfter("Test3"); + // { " MERGEFIELD Test1 \\b Test2 \\f Test3 \\m" } + field.isMapped(true); + // { " MERGEFIELD Test1 \\b Test2 \\f Test3 \\m \\v" } + field.isVerticalFormatting(true); + + field.update(); + + doc.save(getArtifactsDir() + "WorkingWithFields.InsertMergeFieldUsingDom.docx"); + //ExEnd:InsertMergeFieldUsingDom + } + + @Test + public void insertAddressBlockFieldUsingDom() throws Exception { + //ExStart:InsertAddressBlockFieldUsingDom + //GistId:1cf07762df56f15067d6aef90b14b3db + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Paragraph para = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 0, true); + builder.moveTo(para); + + // We want to insert a mail merge address block like this: + // { ADDRESSBLOCK \\c 1 \\d \\e Test2 \\f Test3 \\l \"Test 4\" } + FieldAddressBlock field = (FieldAddressBlock) builder.insertField(FieldType.FIELD_ADDRESS_BLOCK, false); + // { ADDRESSBLOCK \\c 1" } + field.setIncludeCountryOrRegionName("1"); + // { ADDRESSBLOCK \\c 1 \\d" } + field.setFormatAddressOnCountryOrRegion(true); + // { ADDRESSBLOCK \\c 1 \\d \\e Test2 } + field.setExcludedCountryOrRegionName("Test2"); + // { ADDRESSBLOCK \\c 1 \\d \\e Test2 \\f Test3 } + field.setNameAndAddressFormat("Test3"); + // { ADDRESSBLOCK \\c 1 \\d \\e Test2 \\f Test3 \\l \"Test 4\" } + field.setLanguageId("Test 4"); + + field.update(); + + doc.save(getArtifactsDir() + "WorkingWithFields.InsertAddressBlockFieldUsingDom.docx"); + //ExEnd:InsertAddressBlockFieldUsingDom + } + + @Test + public void insertFieldIncludeTextWithoutDocumentBuilder() throws Exception { + //ExStart:InsertFieldIncludeTextWithoutDocumentBuilder + //GistId:1cf07762df56f15067d6aef90b14b3db + Document doc = new Document(); + + Paragraph para = new Paragraph(doc); + + // We want to insert an INCLUDETEXT field like this: + // { INCLUDETEXT "file path" } + FieldIncludeText fieldIncludeText = (FieldIncludeText) para.appendField(FieldType.FIELD_INCLUDE_TEXT, false); + fieldIncludeText.setBookmarkName("bookmark"); + fieldIncludeText.setSourceFullName(getMyDir() + "IncludeText.docx"); + + doc.getFirstSection().getBody().appendChild(para); + + fieldIncludeText.update(); + + doc.save(getArtifactsDir() + "WorkingWithFields.InsertIncludeFieldWithoutDocumentBuilder.docx"); + //ExEnd:InsertFieldIncludeTextWithoutDocumentBuilder + } + + @Test + public void insertFieldNone() throws Exception { + //ExStart:InsertFieldNone + //GistId:1cf07762df56f15067d6aef90b14b3db + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + FieldUnknown field = (FieldUnknown) builder.insertField(FieldType.FIELD_NONE, false); + + doc.save(getArtifactsDir() + "WorkingWithFields.InsertFieldNone.docx"); + //ExEnd:InsertFieldNone + } + + @Test + public void insertField() throws Exception { + //ExStart:InsertField + //GistId:1cf07762df56f15067d6aef90b14b3db + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField("MERGEFIELD MyFieldName \\* MERGEFORMAT"); + + doc.save(getArtifactsDir() + "WorkingWithFields.InsertField.docx"); + //ExEnd:InsertField + } + + @Test + public void insertFieldUsingFieldBuilder() throws Exception { + //ExStart:InsertFieldUsingFieldBuilder + //GistId:1cf07762df56f15067d6aef90b14b3db + Document doc = new Document(); + + // Prepare IF field with two nested MERGEFIELD fields: { IF "left expression" = "right expression" "Firstname: { MERGEFIELD firstname }" "Lastname: { MERGEFIELD lastname }"} + FieldBuilder fieldBuilder = new FieldBuilder(FieldType.FIELD_IF) + .addArgument("left expression") + .addArgument("=") + .addArgument("right expression") + .addArgument( + new FieldArgumentBuilder() + .addText("Firstname: ") + .addField(new FieldBuilder(FieldType.FIELD_MERGE_FIELD).addArgument("firstname"))) + .addArgument( + new FieldArgumentBuilder() + .addText("Lastname: ") + .addField(new FieldBuilder(FieldType.FIELD_MERGE_FIELD).addArgument("lastname"))); + + // Insert IF field in exact location + Field field = fieldBuilder.buildAndInsert(doc.getFirstSection().getBody().getFirstParagraph()); + field.update(); + + doc.save(getArtifactsDir() + "Field.InsertFieldUsingFieldBuilder.docx"); + //ExEnd:InsertFieldUsingFieldBuilder + } + + @Test + public void insertAuthorField() throws Exception { + //ExStart:InsertAuthorField + //GistId:1cf07762df56f15067d6aef90b14b3db + Document doc = new Document(); + + Paragraph para = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 0, true); + + // We want to insert an AUTHOR field like this: + // { AUTHOR Test1 } + FieldAuthor field = (FieldAuthor) para.appendField(FieldType.FIELD_AUTHOR, false); + field.setAuthorName("Test1"); + + field.update(); + + doc.save(getArtifactsDir() + "WorkingWithFields.InsertAuthorField.docx"); + //ExEnd:InsertAuthorField + } + + @Test + public void insertAskFieldWithoutDocumentBuilder() throws Exception { + //ExStart:InsertAskFieldWithoutDocumentBuilder + //GistId:1cf07762df56f15067d6aef90b14b3db + Document doc = new Document(); + + Paragraph para = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 0, true); + // We want to insert an Ask field like this: + // { ASK \"Test 1\" Test2 \\d Test3 \\o } + FieldAsk field = (FieldAsk) para.appendField(FieldType.FIELD_ASK, false); + // { ASK \"Test 1\" " } + field.setBookmarkName("Test 1"); + // { ASK \"Test 1\" Test2 } + field.setPromptText("Test2"); + // { ASK \"Test 1\" Test2 \\d Test3 } + field.setDefaultResponse("Test3"); + // { ASK \"Test 1\" Test2 \\d Test3 \\o } + field.setPromptOnceOnMailMerge(true); + + field.update(); + + doc.save(getArtifactsDir() + "WorkingWithFields.InsertAskFieldWithoutDocumentBuilder.docx"); + //ExEnd:InsertAskFieldWithoutDocumentBuilder + } + + @Test + public void insertAdvanceFieldWithoutDocumentBuilder() throws Exception { + //ExStart:InsertAdvanceFieldWithoutDocumentBuilder + //GistId:1cf07762df56f15067d6aef90b14b3db + Document doc = new Document(); + + Paragraph para = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 0, true); + // We want to insert an Advance field like this: + // { ADVANCE \\d 10 \\l 10 \\r -3.3 \\u 0 \\x 100 \\y 100 } + FieldAdvance field = (FieldAdvance) para.appendField(FieldType.FIELD_ADVANCE, false); + // { ADVANCE \\d 10 " } + field.setDownOffset("10"); + // { ADVANCE \\d 10 \\l 10 } + field.setLeftOffset("10"); + // { ADVANCE \\d 10 \\l 10 \\r -3.3 } + field.setRightOffset("-3.3"); + // { ADVANCE \\d 10 \\l 10 \\r -3.3 \\u 0 } + field.setUpOffset("0"); + // { ADVANCE \\d 10 \\l 10 \\r -3.3 \\u 0 \\x 100 } + field.setHorizontalPosition("100"); + // { ADVANCE \\d 10 \\l 10 \\r -3.3 \\u 0 \\x 100 \\y 100 } + field.setVerticalPosition("100"); + + field.update(); + + doc.save(getArtifactsDir() + "WorkingWithFields.InsertAdvanceFieldWithoutDocumentBuilder.docx"); + //ExEnd:InsertAdvanceFieldWithoutDocumentBuilder + } + + @Test + public void getMailMergeFieldNames() throws Exception { + //ExStart:GetFieldNames + //GistId:b4bab1bf22437a86d8062e91cf154494 + Document doc = new Document(); + + String[] fieldNames = doc.getMailMerge().getFieldNames(); + //ExEnd:GetFieldNames + System.out.println("\nDocument have " + fieldNames.length + " fields."); + } + + @Test + public void mappedDataFields() throws Exception { + //ExStart:MappedDataFields + //GistId:b4bab1bf22437a86d8062e91cf154494 + Document doc = new Document(); + + doc.getMailMerge().getMappedDataFields().add("MyFieldName_InDocument", "MyFieldName_InDataSource"); + //ExEnd:MappedDataFields + } + + @Test + public void deleteFields() throws Exception { + //ExStart:DeleteFields + //GistId:f39874821cb317d245a769c9ce346fea + Document doc = new Document(); + + doc.getMailMerge().deleteFields(); + //ExEnd:DeleteFields + } + + @Test + public void fieldUpdateCulture() throws Exception { + //ExStart:FieldUpdateCulture + //GistId:79b46682fbfd7f02f64783b163ed95fc + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField(FieldType.FIELD_TIME, true); + + doc.getFieldOptions().setFieldUpdateCultureSource(FieldUpdateCultureSource.FIELD_CODE); + doc.getFieldOptions().setFieldUpdateCultureProvider(new FieldUpdateCultureProvider()); + + doc.save(getArtifactsDir() + "WorkingWithFields.FieldUpdateCulture.pdf"); + //ExEnd:FieldUpdateCulture + } + + //ExStart:FieldUpdateCultureProvider + //GistId:79b46682fbfd7f02f64783b163ed95fc + private static class FieldUpdateCultureProvider implements IFieldUpdateCultureProvider { + public CultureInfo getCulture(String name, Field field) { + switch (name) { + case "ru-RU": + CultureInfo culture = new CultureInfo(new Locale(name)); + DateTimeFormatInfo format = culture.getDateTimeFormat(); + + format.setMonthNames(new String[] + { + "месяц 1", "месяц 2", "месяц 3", "месяц 4", "месяц 5", "месяц 6", "месяц 7", "месяц 8", + "месяц 9", "месяц 10", "месяц 11", "месяц 12", "" + }); + format.setMonthGenitiveNames(format.getMonthNames()); + format.setAbbreviatedMonthNames(new String[] + { + "мес 1", "мес 2", "мес 3", "мес 4", "мес 5", "мес 6", "мес 7", "мес 8", "мес 9", "мес 10", + "мес 11", "мес 12", "" + }); + format.setAbbreviatedMonthGenitiveNames(format.getAbbreviatedMonthNames()); + + format.setDayNames(new String[] + { + "день недели 7", "день недели 1", "день недели 2", "день недели 3", "день недели 4", + "день недели 5", "день недели 6" + }); + format.setAbbreviatedDayNames(new String[] + {"день 7", "день 1", "день 2", "день 3", "день 4", "день 5", "день 6"}); + format.setShortestDayNames(new String[]{"д7", "д1", "д2", "д3", "д4", "д5", "д6"}); + + format.setAMDesignator("До полудня"); + format.setPMDesignator("После полудня"); + + final String PATTERN = "yyyy MM (MMMM) dd (dddd) hh:mm:ss tt"; + format.setLongDatePattern(PATTERN); + format.setLongTimePattern(PATTERN); + format.setShortDatePattern(PATTERN); + format.setShortTimePattern(PATTERN); + + return culture; + case "en-US": + return new CultureInfo(new Locale(name)); + default: + return null; + } + } + } + //ExEnd:FieldUpdateCultureProvider + + @Test + public void fieldDisplayResults() throws Exception { + //ExStart:FieldDisplayResults + //GistId:bf0f8a6b40b69a5274ab3553315e147f + //ExStart:UpdateDocFields + //GistId:08db64c4d86842c4afd1ecb925ed07c4 + Document doc = new Document(getMyDir() + "Various fields.docx"); + + doc.updateFields(); + //ExEnd:UpdateDocFields + + for (Field field : doc.getRange().getFields()) + System.out.println(field.getDisplayResult()); + //ExEnd:FieldDisplayResults + } + + @Test + public void evaluateIfCondition() throws Exception { + //ExStart:EvaluateIfCondition + //GistId:79b46682fbfd7f02f64783b163ed95fc + DocumentBuilder builder = new DocumentBuilder(); + + FieldIf field = (FieldIf) builder.insertField("IF 1 = 1", null); + int actualResult = field.evaluateCondition(); + + System.out.println(actualResult); + //ExEnd:EvaluateIfCondition + } + + @Test + public void unlinkFieldsInParagraph() throws Exception { + //ExStart:UnlinkFieldsInParagraph + //GistId:f3592014d179ecb43905e37b2a68bc92 + Document doc = new Document(getMyDir() + "Linked fields.docx"); + + // Pass the appropriate parameters to convert all IF fields to text that are encountered only in the last + // paragraph of the document. + for (Field field : doc.getFirstSection().getBody().getLastParagraph().getRange().getFields()) { + if (field.getType() == FieldType.FIELD_IF) { + field.unlink(); + } + } + + doc.save(getArtifactsDir() + "WorkingWithFields.UnlinkFieldsInParagraph.docx"); + //ExEnd:UnlinkFieldsInParagraph + } + + @Test + public void unlinkFieldsInDocument() throws Exception { + //ExStart:UnlinkFieldsInDocument + //GistId:f3592014d179ecb43905e37b2a68bc92 + Document doc = new Document(getMyDir() + "Linked fields.docx"); + + // Pass the appropriate parameters to convert all IF fields encountered in the document (including headers and footers) to text. + for (Field field : doc.getRange().getFields()) { + if (field.getType() == FieldType.FIELD_IF) { + field.unlink(); + } + } + + // Save the document with fields transformed to disk + doc.save(getArtifactsDir() + "WorkingWithFields.UnlinkFieldsInDocument.docx"); + //ExEnd:UnlinkFieldsInDocument + } + + @Test + public void unlinkFieldsInBody() throws Exception { + //ExStart:UnlinkFieldsInBody + //GistId:f3592014d179ecb43905e37b2a68bc92 + Document doc = new Document(getMyDir() + "Linked fields.docx"); + + // Pass the appropriate parameters to convert PAGE fields encountered to text only in the body of the first section. + for (Field field : doc.getRange().getFields()) { + if (field.getType() == FieldType.FIELD_PAGE) { + field.unlink(); + } + } + + doc.save(getArtifactsDir() + "WorkingWithFields.UnlinkFieldsInBody.docx"); + //ExEnd:UnlinkFieldsInBody + } + + @Test + public void changeLocale() throws Exception { + //ExStart:ChangeLocale + //GistId:9e90defe4a7bcafb004f73a2ef236986 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField("MERGEFIELD Date"); + + // Store the current culture so it can be set back once mail merge is complete. + CultureInfo currentCulture = new CultureInfo(""); + // Set to German language so dates and numbers are formatted using this culture during mail merge. + Locale.setDefault(new Locale("de-DE")); + + doc.getMailMerge().execute(new String[]{"Date"}, new Object[]{new Date()}); + + Locale.setDefault(currentCulture.getLocale(currentCulture)); + + doc.save(getArtifactsDir() + "WorkingWithFields.ChangeLocale.docx"); + //ExEnd:ChangeLocale + } + + //ExStart:ConvertFieldsToStaticText + //GistId:f3592014d179ecb43905e37b2a68bc92 + /// + /// Converts any fields of the specified type found in the descendants of the node into static text. + /// + /// The node in which all descendants of the specified FieldType will be converted to static text. + /// The FieldType of the field to convert to static text. + private static void convertFieldsToStaticText(CompositeNode compositeNode, int targetFieldType) throws Exception { + // Get all fields in the composite node's range. + FieldCollection fields = compositeNode.getRange().getFields(); + + // Iterate through the fields and unlink those that match the target field type. + for (Field field : fields) { + if (field.getType() == targetFieldType) { + field.unlink(); + } + } + } + //ExEnd:ConvertFieldsToStaticText + + @Test + public void fieldResultFormatting() throws Exception { + //ExStart:FieldResultFormatting + //GistId:79b46682fbfd7f02f64783b163ed95fc + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + FieldResultFormatter formatter = new FieldResultFormatter("$%d", "Date: %s", "Item # %s:"); + doc.getFieldOptions().setResultFormatter(formatter); + + // Our field result formatter applies a custom format to newly created fields of three types of formats. + // Field result formatters apply new formatting to fields as they are updated, + // which happens as soon as we create them using this InsertField method overload. + // 1 - Numeric: + builder.insertField(" = 2 + 3 \\# $###"); + + Assert.assertEquals("$5", doc.getRange().getFields().get(0).getResult()); + Assert.assertEquals(1, formatter.countFormatInvocations(FieldResultFormatter.FormatInvocationType.NUMERIC)); + + // 2 - Date/time: + builder.insertField("DATE \\@ \"d MMMM yyyy\""); + + Assert.assertTrue(doc.getRange().getFields().get(1).getResult().startsWith("Date: ")); + Assert.assertEquals(1, formatter.countFormatInvocations(FieldResultFormatter.FormatInvocationType.DATE_TIME)); + + // 3 - General: + builder.insertField("QUOTE \"2\" \\* Ordinal"); + + Assert.assertEquals("Item # 2:", doc.getRange().getFields().get(2).getResult()); + Assert.assertEquals(1, formatter.countFormatInvocations(FieldResultFormatter.FormatInvocationType.GENERAL)); + + formatter.printFormatInvocations(); + //ExEnd:FieldResultFormatting + } + + //ExStart:FieldResultFormatter + //GistId:79b46682fbfd7f02f64783b163ed95fc + /// + /// When fields with formatting are updated, this formatter will override their formatting + /// with a custom format, while tracking every invocation. + /// + public static class FieldResultFormatter implements IFieldResultFormatter { + + private final String mNumberFormat; + private final String mDateFormat; + private final String mGeneralFormat; + private final ArrayList formatInvocations = new ArrayList<>(); + + public FieldResultFormatter(String numberFormat, String dateFormat, String generalFormat) { + this.mNumberFormat = numberFormat; + this.mDateFormat = dateFormat; + this.mGeneralFormat = generalFormat; + } + + @Override + public String formatNumeric(double value, String format) { + if (mNumberFormat == null || mNumberFormat.isEmpty()) { + return null; + } + + String newValue = String.format(mNumberFormat, (int) value); + formatInvocations.add(new FormatInvocation(FormatInvocationType.NUMERIC, value, format, newValue)); + return newValue; + } + + @Override + public String formatDateTime(Date value, String format, int calendarType) { + if (mDateFormat == null || mDateFormat.isEmpty()) { + return null; + } + + String newValue = String.format(mDateFormat, value); + formatInvocations.add(new FormatInvocation(FormatInvocationType.DATE_TIME, value + " (" + calendarType + ")", format, newValue)); + return newValue; + } + + @Override + public String format(String value, int format) { + return format((Object) value, format); + } + + @Override + public String format(double value, int format) { + return format((Object) value, format); + } + + private String format(Object value, int format) { + if (mGeneralFormat == null || mGeneralFormat.isEmpty()) { + return null; + } + + double doubleValue = Double.parseDouble(value.toString()); + String newValue = String.format(mGeneralFormat, (int) doubleValue); + formatInvocations.add(new FormatInvocation(FormatInvocationType.GENERAL, value, String.valueOf(format), newValue)); + return newValue; + } + + public int countFormatInvocations(FormatInvocationType formatInvocationType) { + if (formatInvocationType == FormatInvocationType.ALL) { + return formatInvocations.size(); + } + return (int) formatInvocations.stream() + .filter(f -> f.getFormatInvocationType() == formatInvocationType) + .count(); + } + + public void printFormatInvocations() { + for (FormatInvocation f : formatInvocations) { + System.out.println("Invocation type:\t" + f.getFormatInvocationType() + "\n" + + "\tOriginal value:\t\t" + f.getValue() + "\n" + + "\tOriginal format:\t" + f.getOriginalFormat() + "\n" + + "\tNew value:\t\t\t" + f.getNewValue() + "\n"); + } + } + + public static class FormatInvocation { + private final FormatInvocationType formatInvocationType; + private final Object value; + private final String originalFormat; + private final String newValue; + + public FormatInvocation(FormatInvocationType formatInvocationType, Object value, String originalFormat, String newValue) { + this.formatInvocationType = formatInvocationType; + this.value = value; + this.originalFormat = originalFormat; + this.newValue = newValue; + } + + public FormatInvocationType getFormatInvocationType() { + return formatInvocationType; + } + + public Object getValue() { + return value; + } + + public String getOriginalFormat() { + return originalFormat; + } + + public String getNewValue() { + return newValue; + } + } + + public enum FormatInvocationType { + NUMERIC, DATE_TIME, GENERAL, ALL + } + } + //ExEnd:FieldResultFormatter +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithFonts.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithFonts.java new file mode 100644 index 00000000..920e2a61 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithFonts.java @@ -0,0 +1,455 @@ +package DocsExamples.Programming_with_documents; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Font; +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.awt.*; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +@Test +public class WorkingWithFonts extends DocsExamplesBase { + @Test + public void fontFormatting() throws Exception { + //ExStart:WriteAndFont + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Font font = builder.getFont(); + font.setSize(16.0); + font.setBold(true); + font.setColor(Color.BLUE); + font.setName("Arial"); + font.setUnderline(Underline.DASH); + + builder.write("Sample text."); + + doc.save(getArtifactsDir() + "WorkingWithFonts.FontFormatting.docx"); + //ExEnd:WriteAndFont + } + + @Test + public void getFontLineSpacing() throws Exception { + //ExStart:GetFontLineSpacing + //GistId:7cb86f131b74afcbebc153f0039e3947 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Calibri"); + builder.writeln("qText"); + + Font font = builder.getDocument().getFirstSection().getBody().getFirstParagraph().getRuns().get(0).getFont(); + System.out.println("lineSpacing = {font.LineSpacing}"); + //ExEnd:GetFontLineSpacing + } + + @Test + public void checkDMLTextEffect() throws Exception { + //ExStart:CheckDMLTextEffect + Document doc = new Document(getMyDir() + "DrawingML text effects.docx"); + + RunCollection runs = doc.getFirstSection().getBody().getFirstParagraph().getRuns(); + Font runFont = runs.get(0).getFont(); + + // One run might have several Dml text effects applied. + System.out.println(runFont.hasDmlEffect(TextDmlEffect.SHADOW)); + System.out.println(runFont.hasDmlEffect(TextDmlEffect.EFFECT_3_D)); + System.out.println(runFont.hasDmlEffect(TextDmlEffect.REFLECTION)); + System.out.println(runFont.hasDmlEffect(TextDmlEffect.OUTLINE)); + System.out.println(runFont.hasDmlEffect(TextDmlEffect.FILL)); + //ExEnd:CheckDMLTextEffect + } + + @Test + public void setFontFormatting() throws Exception { + //ExStart:SetFontFormatting + //GistId:7cb86f131b74afcbebc153f0039e3947 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Font font = builder.getFont(); + font.setBold(true); + font.setColor(Color.BLUE); + font.setItalic(true); + font.setName("Arial"); + font.setSize(24.0); + font.setSpacing(5.0); + font.setUnderline(Underline.DOUBLE); + + builder.writeln("I'm a very nice formatted string."); + + doc.save(getArtifactsDir() + "WorkingWithFonts.SetFontFormatting.docx"); + //ExEnd:SetFontFormatting + } + + @Test + public void setFontEmphasisMark() throws Exception { + //ExStart:SetFontEmphasisMark + //GistId:7cb86f131b74afcbebc153f0039e3947 + Document document = new Document(); + DocumentBuilder builder = new DocumentBuilder(document); + + builder.getFont().setEmphasisMark(EmphasisMark.UNDER_SOLID_CIRCLE); + + builder.write("Emphasis text"); + builder.writeln(); + builder.getFont().clearFormatting(); + builder.write("Simple text"); + + document.save(getArtifactsDir() + "WorkingWithFonts.SetFontEmphasisMark.docx"); + //ExEnd:SetFontEmphasisMark + } + + @Test + public void enableDisableFontSubstitution() throws Exception { + //ExStart:EnableDisableFontSubstitution + Document doc = new Document(getMyDir() + "Rendering.docx"); + + FontSettings fontSettings = new FontSettings(); + fontSettings.getSubstitutionSettings().getDefaultFontSubstitution().setDefaultFontName("Arial"); + fontSettings.getSubstitutionSettings().getFontInfoSubstitution().setEnabled(false); + + doc.setFontSettings(fontSettings); + + doc.save(getArtifactsDir() + "WorkingWithFonts.EnableDisableFontSubstitution.pdf"); + //ExEnd:EnableDisableFontSubstitution + } + + @Test + public void fontFallbackSettings() throws Exception { + //ExStart:FontFallbackSettings + //GistId:a08698f540d47082b4e2dbb1cb67fc1b + Document doc = new Document(getMyDir() + "Rendering.docx"); + + FontSettings fontSettings = new FontSettings(); + fontSettings.getFallbackSettings().load(getMyDir() + "Font fallback rules.xml"); + + doc.setFontSettings(fontSettings); + + doc.save(getArtifactsDir() + "WorkingWithFonts.FontFallbackSettings.pdf"); + //ExEnd:FontFallbackSettings + } + + @Test + public void notoFallbackSettings() throws Exception { + //ExStart:NotoFallbackSettings + //GistId:a08698f540d47082b4e2dbb1cb67fc1b + Document doc = new Document(getMyDir() + "Rendering.docx"); + + FontSettings fontSettings = new FontSettings(); + fontSettings.getFallbackSettings().loadNotoFallbackSettings(); + + doc.setFontSettings(fontSettings); + + doc.save(getArtifactsDir() + "WorkingWithFonts.NotoFallbackSettings.pdf"); + //ExEnd:NotoFallbackSettings + } + + @Test + public void defaultInstance() throws Exception { + //ExStart:DefaultInstance + //GistId:7e64f6d40825be58a8c12f1307c12964 + FontSettings.getDefaultInstance().setFontsFolder("C:\\MyFonts\\", true); + //ExEnd:DefaultInstance + + Document doc = new Document(getMyDir() + "Rendering.docx"); + doc.save(getArtifactsDir() + "WorkingWithFonts.DefaultInstance.pdf"); + } + + @Test + public void multipleFolders() throws Exception { + //ExStart:MultipleFolders + //GistId:7e64f6d40825be58a8c12f1307c12964 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + FontSettings fontSettings = new FontSettings(); + // Note that this setting will override any default font sources that are being searched by default. Now only these folders will be searched for + // fonts when rendering or embedding fonts. To add an extra font source while keeping system font sources then use both FontSettings.GetFontSources and + // FontSettings.SetFontSources instead. + fontSettings.setFontsFolders(new String[]{"C:\\MyFonts\\", "D:\\Misc\\Fonts\\"}, true); + + doc.setFontSettings(fontSettings); + + doc.save(getArtifactsDir() + "WorkingWithFonts.MultipleFolders.pdf"); + //ExEnd:MultipleFolders + } + + @Test + public void setFontsFoldersSystemAndCustomFolder() throws Exception { + //ExStart:SetFontsFoldersSystemAndCustomFolder + Document doc = new Document(getMyDir() + "Rendering.docx"); + + FontSettings fontSettings = new FontSettings(); + // Retrieve the array of environment-dependent font sources that are searched by default. + // For example this will contain a "Windows\Fonts\" source on a Windows machines. + // We add this array to a new List to make adding or removing font entries much easier. + List fontSources = new ArrayList<>(Arrays.asList(fontSettings.getFontsSources())); + + // Add a new folder source which will instruct Aspose.Words to search the following folder for fonts. + FolderFontSource folderFontSource = new FolderFontSource("C:\\MyFonts\\", true); + + // Add the custom folder which contains our fonts to the list of existing font sources. + fontSources.add(folderFontSource); + + FontSourceBase[] updatedFontSources = fontSources.toArray(new FontSourceBase[0]); + fontSettings.setFontsSources(updatedFontSources); + + doc.setFontSettings(fontSettings); + + doc.save(getArtifactsDir() + "WorkingWithFonts.SetFontsFoldersSystemAndCustomFolder.pdf"); + //ExEnd:SetFontsFoldersSystemAndCustomFolder + } + + @Test + public void fontsFoldersWithPriority() throws Exception { + //ExStart:FontsFoldersWithPriority + //GistId:7e64f6d40825be58a8c12f1307c12964 + FontSettings.getDefaultInstance().setFontsSources(new FontSourceBase[] + { + new SystemFontSource(), new FolderFontSource("C:\\MyFonts\\", true, 1) + }); + //ExEnd:FontsFoldersWithPriority + + Document doc = new Document(getMyDir() + "Rendering.docx"); + doc.save(getArtifactsDir() + "WorkingWithFonts.FontsFoldersWithPriority.pdf"); + } + + @Test + public void trueTypeFontsFolder() throws Exception { + //ExStart:TrueTypeFontsFolder + //GistId:7e64f6d40825be58a8c12f1307c12964 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + FontSettings fontSettings = new FontSettings(); + // Note that this setting will override any default font sources that are being searched by default. Now only these folders will be searched for + // Fonts when rendering or embedding fonts. To add an extra font source while keeping system font sources then use both FontSettings.GetFontSources and + // FontSettings.SetFontSources instead + fontSettings.setFontsFolder("C:\\MyFonts\\", false); + // Set font settings + doc.setFontSettings(fontSettings); + + doc.save(getArtifactsDir() + "WorkingWithFonts.TrueTypeFontsFolder.pdf"); + //ExEnd:TrueTypeFontsFolder + } + + @Test + public void specifyDefaultFontWhenRendering() throws Exception { + //ExStart:SpecifyDefaultFontWhenRendering + Document doc = new Document(getMyDir() + "Rendering.docx"); + + FontSettings fontSettings = new FontSettings(); + // If the default font defined here cannot be found during rendering then + // the closest font on the machine is used instead. + fontSettings.getSubstitutionSettings().getDefaultFontSubstitution().setDefaultFontName("Arial Unicode MS"); + + doc.setFontSettings(fontSettings); + + doc.save(getArtifactsDir() + "WorkingWithFonts.SpecifyDefaultFontWhenRendering.pdf"); + //ExEnd:SpecifyDefaultFontWhenRendering + } + + @Test + public void fontSettingsWithLoadOptions() throws Exception { + //ExStart:FontSettingsWithLoadOptions + FontSettings fontSettings = new FontSettings(); + + TableSubstitutionRule substitutionRule = fontSettings.getSubstitutionSettings().getTableSubstitution(); + // If "UnknownFont1" font family is not available then substitute it by "Comic Sans MS" + substitutionRule.addSubstitutes("UnknownFont1", new String[]{"Comic Sans MS"}); + + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setFontSettings(fontSettings); + + Document doc = new Document(getMyDir() + "Rendering.docx", loadOptions); + //ExEnd:FontSettingsWithLoadOptions + } + + @Test + public void setFontsFolder() throws Exception { + //ExStart:SetFontsFolder + FontSettings fontSettings = new FontSettings(); + fontSettings.setFontsFolder(getMyDir() + "Fonts", false); + + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setFontSettings(fontSettings); + + Document doc = new Document(getMyDir() + "Rendering.docx", loadOptions); + //ExEnd:SetFontsFolder + } + + @Test + public void loadOptionFontSettings() throws Exception { + //ExStart:LoadOptionFontSettings + //GistId:a08698f540d47082b4e2dbb1cb67fc1b + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setFontSettings(new FontSettings()); + + Document doc = new Document(getMyDir() + "Rendering.docx", loadOptions); + //ExEnd:LoadOptionFontSettings + } + + @Test + public void fontSettingsDefaultInstance() throws Exception { + //ExStart:FontsFolders + //GistId:7e64f6d40825be58a8c12f1307c12964 + //ExStart:FontSettingsFontSource + //GistId:a08698f540d47082b4e2dbb1cb67fc1b + //ExStart:FontSettingsDefaultInstance + //GistId:a08698f540d47082b4e2dbb1cb67fc1b + FontSettings fontSettings = FontSettings.getDefaultInstance(); + //ExEnd:FontSettingsDefaultInstance + fontSettings.setFontsSources(new FontSourceBase[] + { + new SystemFontSource(), + new FolderFontSource("C:\\MyFonts\\", true) + }); + //ExEnd:FontSettingsFontSource + + Document doc = new Document(getMyDir() + "Rendering.docx"); + //ExEnd:FontsFolders + } + + @Test + public void availableFonts() { + //ExStart:AvailableFonts + //GistId:7e64f6d40825be58a8c12f1307c12964 + List fontSources = new ArrayList<>(Arrays.asList(FontSettings.getDefaultInstance().getFontsSources())); + + // Add a new folder source which will instruct Aspose.Words to search the following folder for fonts. + FolderFontSource folderFontSource = new FolderFontSource(getMyDir(), true); + // Add the custom folder which contains our fonts to the list of existing font sources. + fontSources.add(folderFontSource); + + FontSourceBase[] updatedFontSources = fontSources.toArray(new FontSourceBase[0]); + + for (PhysicalFontInfo fontInfo : updatedFontSources[0].getAvailableFonts()) { + System.out.println("FontFamilyName : " + fontInfo.getFontFamilyName()); + System.out.println("FullFontName : " + fontInfo.getFullFontName()); + System.out.println("Version : " + fontInfo.getVersion()); + System.out.println("FilePath : " + fontInfo.getFilePath()); + } + //ExEnd:AvailableFonts + } + + @Test + public void receiveNotificationsOfFonts() throws Exception { + //ExStart:ReceiveNotificationsOfFonts + Document doc = new Document(getMyDir() + "Rendering.docx"); + + FontSettings fontSettings = new FontSettings(); + + // We can choose the default font to use in the case of any missing fonts. + fontSettings.getSubstitutionSettings().getDefaultFontSubstitution().setDefaultFontName("Arial"); + // For testing we will set Aspose.Words to look for fonts only in a folder which doesn't exist. Since Aspose.Words won't + // find any fonts in the specified directory, then during rendering the fonts in the document will be subsuited with the default + // font specified under FontSettings.DefaultFontName. We can pick up on this subsuition using our callback. + fontSettings.setFontsFolder("", false); + + // Create a new class implementing IWarningCallback which collect any warnings produced during document save. + HandleDocumentWarnings callback = new HandleDocumentWarnings(); + + doc.setWarningCallback(callback); + doc.setFontSettings(fontSettings); + + doc.save(getArtifactsDir() + "WorkingWithFonts.ReceiveNotificationsOfFonts.pdf"); + //ExEnd:ReceiveNotificationsOfFonts + } + + @Test + public void receiveWarningNotification() throws Exception { + //ExStart:ReceiveWarningNotification + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // When you call UpdatePageLayout the document is rendered in memory. Any warnings that occured during rendering + // are stored until the document save and then sent to the appropriate WarningCallback. + doc.updatePageLayout(); + + HandleDocumentWarnings callback = new HandleDocumentWarnings(); + doc.setWarningCallback(callback); + + // Even though the document was rendered previously, any save warnings are notified to the user during document save. + doc.save(getArtifactsDir() + "WorkingWithFonts.ReceiveWarningNotification.pdf"); + //ExEnd:ReceiveWarningNotification + } + + //ExStart:HandleDocumentWarnings + public static class HandleDocumentWarnings implements IWarningCallback { + /// + /// Our callback only needs to implement the "Warning" method. This method is called whenever there is a + /// Potential issue during document procssing. The callback can be set to listen for warnings generated + /// during document load and/or document save. + /// + public void warning(WarningInfo info) { + // We are only interested in fonts being substituted. + if (info.getWarningType() == WarningType.FONT_SUBSTITUTION) { + System.out.println("Font substitution: " + info.getDescription()); + } + } + } + //ExEnd:HandleDocumentWarnings + + @Test + //ExStart:ResourceSteam + //GistId:7e64f6d40825be58a8c12f1307c12964 + public void resourceSteam() throws Exception { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + FontSettings.getDefaultInstance().setFontsSources(new FontSourceBase[] + {new SystemFontSource(), new ResourceSteamFontSource()}); + + doc.save(getArtifactsDir() + "WorkingWithFonts.ResourceSteam.pdf"); + } + + static class ResourceSteamFontSource extends StreamFontSource { + public InputStream openFontDataStream() throws IOException { + return getClass().getClassLoader().getResource("resourceName").openStream(); + } + } + //ExEnd:ResourceSteam + + @Test + //ExStart:GetSubstitutionWithoutSuffixes + //GistId:a08698f540d47082b4e2dbb1cb67fc1b + public void getSubstitutionWithoutSuffixes() throws Exception { + Document doc = new Document(getMyDir() + "Get substitution without suffixes.docx"); + + DocumentSubstitutionWarnings substitutionWarningHandler = new DocumentSubstitutionWarnings(); + doc.setWarningCallback(substitutionWarningHandler); + + List fontSources = new ArrayList<>(Arrays.asList(FontSettings.getDefaultInstance().getFontsSources())); + + FolderFontSource folderFontSource = new FolderFontSource(getFontsDir(), true); + fontSources.add(folderFontSource); + + FontSourceBase[] updatedFontSources = fontSources.toArray(new FontSourceBase[0]); + FontSettings.getDefaultInstance().setFontsSources(updatedFontSources); + + doc.save(getArtifactsDir() + "WorkingWithFonts.GetSubstitutionWithoutSuffixes.pdf"); + + Assert.assertEquals( + "Font 'DINOT-Regular' has not been found. Using 'DINOT' font instead. Reason: font name substitution.", + substitutionWarningHandler.FontWarnings.get(0).getDescription()); + } + + public static class DocumentSubstitutionWarnings implements IWarningCallback { + /// + /// Our callback only needs to implement the "Warning" method. + /// This method is called whenever there is a potential issue during document processing. + /// The callback can be set to listen for warnings generated during document load and/or document save. + /// + public void warning(WarningInfo info) { + // We are only interested in fonts being substituted. + if (info.getWarningType() == WarningType.FONT_SUBSTITUTION) + FontWarnings.warning(info); + } + + public WarningInfoCollection FontWarnings = new WarningInfoCollection(); + } + //ExEnd:GetSubstitutionWithoutSuffixes +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithFootnoteAndEndnote.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithFootnoteAndEndnote.java new file mode 100644 index 00000000..075f0af8 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithFootnoteAndEndnote.java @@ -0,0 +1,52 @@ +package DocsExamples.Programming_with_documents; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +@Test +public class WorkingWithFootnoteAndEndnote extends DocsExamplesBase { + @Test + public void setFootnoteColumns() throws Exception { + //ExStart:SetFootnoteColumns + //GistId:3b39c2019380ee905e7d9596494916a4 + Document doc = new Document(getMyDir() + "Document.docx"); + + // Specify the number of columns with which the footnotes area is formatted. + doc.getFootnoteOptions().setColumns(3); + + doc.save(getArtifactsDir() + "WorkingWithFootnotes.SetFootnoteColumns.docx"); + //ExEnd:SetFootnoteColumns + } + + @Test + public void setFootnoteAndEndnotePosition() throws Exception { + //ExStart:SetFootnoteAndEndnotePosition + //GistId:3b39c2019380ee905e7d9596494916a4 + Document doc = new Document(getMyDir() + "Document.docx"); + + doc.getFootnoteOptions().setPosition(FootnotePosition.BENEATH_TEXT); + doc.getEndnoteOptions().setPosition(EndnotePosition.END_OF_SECTION); + + doc.save(getArtifactsDir() + "WorkingWithFootnotes.SetFootnoteAndEndnotePosition.docx"); + //ExEnd:SetFootnoteAndEndnotePosition + } + + @Test + public void setEndnoteOptions() throws Exception { + //ExStart:SetEndnoteOptions + //GistId:3b39c2019380ee905e7d9596494916a4 + Document doc = new Document(getMyDir() + "Document.docx"); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Some text"); + builder.insertFootnote(FootnoteType.ENDNOTE, "Footnote text."); + + EndnoteOptions option = doc.getEndnoteOptions(); + option.setRestartRule(FootnoteNumberingRule.RESTART_PAGE); + option.setPosition(EndnotePosition.END_OF_SECTION); + + doc.save(getArtifactsDir() + "WorkingWithFootnotes.SetEndnoteOptions.docx"); + //ExEnd:SetEndnoteOptions + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithFormFields.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithFormFields.java new file mode 100644 index 00000000..29097cf3 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithFormFields.java @@ -0,0 +1,63 @@ +package DocsExamples.Programming_with_documents; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.awt.*; + +@Test +public class WorkingWithFormFields extends DocsExamplesBase { + @Test + public void insertFormFields() throws Exception { + //ExStart:InsertFormFields + //GistId:b09907fef4643433271e4e0e912921b0 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + String[] items = {"One", "Two", "Three"}; + builder.insertComboBox("DropDown", items, 0); + //ExEnd:InsertFormFields + } + + @Test + public void formFieldsWorkWithProperties() throws Exception { + //ExStart:FormFieldsWorkWithProperties + //GistId:b09907fef4643433271e4e0e912921b0 + Document doc = new Document(getMyDir() + "Form fields.docx"); + FormField formField = doc.getRange().getFormFields().get(3); + + if (formField.getType() == FieldType.FIELD_FORM_TEXT_INPUT) + formField.setResult("My name is " + formField.getName()); + //ExEnd:FormFieldsWorkWithProperties + } + + @Test + public void formFieldsGetFormFieldsCollection() throws Exception { + //ExStart:FormFieldsGetFormFieldsCollection + //GistId:b09907fef4643433271e4e0e912921b0 + Document doc = new Document(getMyDir() + "Form fields.docx"); + + FormFieldCollection formFields = doc.getRange().getFormFields(); + //ExEnd:FormFieldsGetFormFieldsCollection + } + + @Test + public void formFieldsGetByName() throws Exception { + //ExStart:FormFieldsFontFormatting + //GistId:b09907fef4643433271e4e0e912921b0 + //ExStart:FormFieldsGetByName + //GistId:b09907fef4643433271e4e0e912921b0 + Document doc = new Document(getMyDir() + "Form fields.docx"); + + FormFieldCollection documentFormFields = doc.getRange().getFormFields(); + + FormField formField1 = documentFormFields.get(3); + FormField formField2 = documentFormFields.get("Text2"); + //ExEnd:FormFieldsGetByName + + formField1.getFont().setSize(20.0); + formField2.getFont().setColor(Color.RED); + //ExEnd:FormFieldsFontFormatting + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithHeadersAndFooters.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithHeadersAndFooters.java new file mode 100644 index 00000000..42f29159 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithHeadersAndFooters.java @@ -0,0 +1,227 @@ +package DocsExamples.Programming_with_documents; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +@Test +public class WorkingWithHeadersAndFooters extends DocsExamplesBase { + @Test + public void CreateHeaderFooter() throws Exception { + //ExStart:CreateHeaderFooter + //GistId:58431f54e34e5597f8cbaf97481d5321 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Use HeaderPrimary and FooterPrimary + // if you want to set header/footer for all document. + // This header/footer type also responsible for odd pages. + //ExStart:HeaderFooterType + //GistId:58431f54e34e5597f8cbaf97481d5321 + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.write("Header for page."); + //ExEnd:HeaderFooterType + + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + builder.write("Footer for page."); + + doc.save(getArtifactsDir() + "WorkingWithHeadersAndFooters.CreateHeaderFooter.docx"); + //ExEnd:CreateHeaderFooter + } + + @Test + public void DifferentFirstPage() throws Exception { + //ExStart:DifferentFirstPage + //GistId:58431f54e34e5597f8cbaf97481d5321 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Specify that we want different headers and footers for first page. + builder.getPageSetup().setDifferentFirstPageHeaderFooter(true); + + builder.moveToHeaderFooter(HeaderFooterType.HEADER_FIRST); + builder.write("Header for the first page."); + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_FIRST); + builder.write("Footer for the first page."); + + builder.moveToSection(0); + builder.writeln("Page 1"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 2"); + + doc.save(getArtifactsDir() + "WorkingWithHeadersAndFooters.DifferentFirstPage.docx"); + //ExEnd:DifferentFirstPage + } + + @Test + public void OddEvenPages() throws Exception { + //ExStart:OddEvenPages + //GistId:58431f54e34e5597f8cbaf97481d5321 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Specify that we want different headers and footers for even and odd pages. + builder.getPageSetup().setOddAndEvenPagesHeaderFooter(true); + + builder.moveToHeaderFooter(HeaderFooterType.HEADER_EVEN); + builder.write("Header for even pages."); + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.write("Header for odd pages."); + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_EVEN); + builder.write("Footer for even pages."); + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + builder.write("Footer for odd pages."); + + builder.moveToSection(0); + builder.writeln("Page 1"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 2"); + + doc.save(getArtifactsDir() + "WorkingWithHeadersAndFooters.OddEvenPages.docx"); + //ExEnd:OddEvenPages + } + + @Test + public void InsertImage() throws Exception { + //ExStart:InsertImage + //GistId:58431f54e34e5597f8cbaf97481d5321 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.insertImage(getImagesDir() + "Logo.jpg", RelativeHorizontalPosition.RIGHT_MARGIN, 10, + RelativeVerticalPosition.PAGE, 10, 50, 50, WrapType.THROUGH); + + doc.save(getArtifactsDir() + "WorkingWithHeadersAndFooters.InsertImage.docx"); + //ExEnd:InsertImage + } + + @Test + public void FontProps() throws Exception { + //ExStart:FontProps + //GistId:58431f54e34e5597f8cbaf97481d5321 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.getFont().setName("Arial"); + builder.getFont().setBold(true); + builder.getFont().setSize(14); + builder.write("Header for page."); + + doc.save(getArtifactsDir() + "WorkingWithHeadersAndFooters.HeaderFooterFontProps.docx"); + //ExEnd:FontProps + } + + @Test + public void PageNumbers() throws Exception { + //ExStart:PageNumbers + //GistId:58431f54e34e5597f8cbaf97481d5321 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.RIGHT); + builder.write("Page "); + builder.insertField("PAGE", ""); + builder.write(" of "); + builder.insertField("NUMPAGES", ""); + + doc.save(getArtifactsDir() + "WorkingWithHeadersAndFooters.PageNumbers.docx"); + //ExEnd:PageNumbers + } + + @Test + public void LinkToPreviousHeaderFooter() throws Exception { + //ExStart:LinkToPreviousHeaderFooter + //GistId:58431f54e34e5597f8cbaf97481d5321 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getPageSetup().setDifferentFirstPageHeaderFooter(true); + + builder.moveToHeaderFooter(HeaderFooterType.HEADER_FIRST); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.getFont().setName("Arial"); + builder.getFont().setBold(true); + builder.getFont().setSize(14); + builder.write("Header for the first page."); + + builder.moveToDocumentEnd(); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + + Section currentSection = builder.getCurrentSection(); + PageSetup pageSetup = currentSection.getPageSetup(); + pageSetup.setOrientation(Orientation.LANDSCAPE); + // This section does not need a different first-page header/footer we need only one title page in the document, + // and the header/footer for this page has already been defined in the previous section. + pageSetup.setDifferentFirstPageHeaderFooter(false); + + // This section displays headers/footers from the previous section + // by default call currentSection.HeadersFooters.LinkToPrevious(false) to cancel this page width + // is different for the new section. + currentSection.getHeadersFooters().linkToPrevious(false); + currentSection.getHeadersFooters().clear(); + + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.getFont().setName("Arial"); + builder.getFont().setSize(12); + builder.write("New Header for the first page."); + + doc.save(getArtifactsDir() + "WorkingWithHeadersAndFooters.LinkToPreviousHeaderFooter.docx"); + //ExEnd:LinkToPreviousHeaderFooter + } + + @Test + public void SectionsWithDifferentHeaders() throws Exception { + //ExStart:SectionsWithDifferentHeaders + //GistId:7c0668453e53ed7a57d3ea3a05520f21 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + PageSetup pageSetup = builder.getCurrentSection().getPageSetup(); + pageSetup.setDifferentFirstPageHeaderFooter(true); + pageSetup.setHeaderDistance(20); + + builder.moveToHeaderFooter(HeaderFooterType.HEADER_FIRST); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.getFont().setName("Arial"); + builder.getFont().setBold(true); + builder.getFont().setSize(14); + builder.write("Header for the first page."); + + builder.moveToDocumentEnd(); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + // Insert a positioned image into the top/left corner of the header. + // Distance from the top/left edges of the page is set to 10 points. + builder.insertImage(getImagesDir() + "Logo.jpg", RelativeHorizontalPosition.PAGE, 10, + RelativeVerticalPosition.PAGE, 10, 50, 50, WrapType.THROUGH); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.RIGHT); + builder.write("Header for odd page."); + + doc.save(getArtifactsDir() + "WorkingWithHeadersAndFooters.SectionsWithDifferentHeaders.docx"); + //ExEnd:SectionsWithDifferentHeaders + } + + //ExStart:CopyHeadersFootersFromPreviousSection + //GistId:58431f54e34e5597f8cbaf97481d5321 + /// + /// Clones and copies headers/footers form the previous section to the specified section. + /// + private void copyHeadersFootersFromPreviousSection(Section section) { + Section previousSection = (Section) section.getPreviousSibling(); + + if (previousSection == null) + return; + + section.getHeadersFooters().clear(); + + for (HeaderFooter headerFooter : previousSection.getHeadersFooters()) + section.getHeadersFooters().add(headerFooter.deepClone(true)); + } + //ExEnd:CopyHeadersFootersFromPreviousSection +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithHyphenation.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithHyphenation.java new file mode 100644 index 00000000..b4543832 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithHyphenation.java @@ -0,0 +1,80 @@ +package DocsExamples.Programming_with_documents; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Document; +import com.aspose.words.Hyphenation; +import com.aspose.words.IHyphenationCallback; +import org.testng.annotations.Test; + +import java.io.FileInputStream; +import java.nio.file.Paths; +import java.text.MessageFormat; + +@Test +public class WorkingWithHyphenation extends DocsExamplesBase { + @Test + public void hyphenateWords() throws Exception { + //ExStart:HyphenateWords + //GistId:a52aacf87a36f7881ba29d25de92fb83 + Document doc = new Document(getMyDir() + "German text.docx"); + + Hyphenation.registerDictionary("en-US", getMyDir() + "hyph_en_US.dic"); + Hyphenation.registerDictionary("de-CH", getMyDir() + "hyph_de_CH.dic"); + + doc.save(getArtifactsDir() + "WorkingWithHyphenation.HyphenateWords.pdf"); + //ExEnd:HyphenateWords + } + + @Test + public void loadHyphenationDictionary() throws Exception { + //ExStart:LoadHyphenationDictionary + //GistId:a52aacf87a36f7881ba29d25de92fb83 + Document doc = new Document(getMyDir() + "German text.docx"); + + FileInputStream stream = new FileInputStream(getMyDir() + "hyph_de_CH.dic"); + Hyphenation.registerDictionary("de-CH", stream); + + doc.save(getArtifactsDir() + "WorkingWithHyphenation.LoadHyphenationDictionary.pdf"); + //ExEnd:LoadHyphenationDictionary + } + + @Test + //ExStart:CustomHyphenation + //GistId:a52aacf87a36f7881ba29d25de92fb83 + public void hyphenationCallback() throws Exception { + try { + // Register hyphenation callback. + Hyphenation.setCallback(new CustomHyphenationCallback()); + + Document document = new Document(getMyDir() + "German text.docx"); + document.save(getArtifactsDir() + "WorkingWithHyphenation.HyphenationCallback.pdf"); + } catch (Exception e) { + if (e.getMessage().startsWith("Missing hyphenation dictionary")) { + System.out.println(e.getMessage()); + } + + } finally { + Hyphenation.setCallback(null); + } + } + + public static class CustomHyphenationCallback implements IHyphenationCallback { + public void requestDictionary(String language) throws Exception { + String dictionaryFolder = getMyDir(); + String dictionaryFullFileName; + switch (language) { + case "en-US": + dictionaryFullFileName = Paths.get(dictionaryFolder, "hyph_en_US.dic").toString(); + break; + case "de-CH": + dictionaryFullFileName = Paths.get(dictionaryFolder, "hyph_de_CH.dic").toString(); + break; + default: + throw new Exception(MessageFormat.format("Missing hyphenation dictionary for {0}.", language)); + } + // Register dictionary for requested language. + Hyphenation.registerDictionary(language, dictionaryFullFileName); + } + } + //ExEnd:CustomHyphenation +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithList.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithList.java new file mode 100644 index 00000000..c73ace9c --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithList.java @@ -0,0 +1,105 @@ +package DocsExamples.Programming_with_documents; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.List; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.awt.*; + +@Test +public class WorkingWithList extends DocsExamplesBase { + @Test + public void restartListAtEachSection() throws Exception { + //ExStart:RestartListAtEachSection + //GistId:a1dfeba1e0480d5b277a61742c8921af + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + doc.getLists().add(ListTemplate.NUMBER_DEFAULT); + + List list = doc.getLists().get(0); + list.isRestartAtEachSection(true); + + // The "IsRestartAtEachSection" property will only be applicable when + // the document's OOXML compliance level is to a standard that is newer than "OoxmlComplianceCore.Ecma376". + OoxmlSaveOptions options = new OoxmlSaveOptions(); + options.setCompliance(OoxmlCompliance.ISO_29500_2008_TRANSITIONAL); + + builder.getListFormat().setList(list); + + builder.writeln("List item 1"); + builder.writeln("List item 2"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.writeln("List item 3"); + builder.writeln("List item 4"); + + doc.save(getArtifactsDir() + "WorkingWithList.RestartListAtEachSection.docx", options); + //ExEnd:RestartListAtEachSection + } + + @Test + public void specifyListLevel() throws Exception { + //ExStart:SpecifyListLevel + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a numbered list based on one of the Microsoft Word list templates + // and apply it to the document builder's current paragraph. + builder.getListFormat().setList(doc.getLists().add(ListTemplate.NUMBER_ARABIC_DOT)); + + // There are nine levels in this list, let's try them all. + for (int i = 0; i < 9; i++) { + builder.getListFormat().setListLevelNumber(i); + builder.writeln("Level " + i); + } + + // Create a bulleted list based on one of the Microsoft Word list templates + // and apply it to the document builder's current paragraph. + builder.getListFormat().setList(doc.getLists().add(ListTemplate.BULLET_DIAMONDS)); + + for (int i = 0; i < 9; i++) { + builder.getListFormat().setListLevelNumber(i); + builder.writeln("Level " + i); + } + + // This is a way to stop list formatting. + builder.getListFormat().setList(null); + + builder.getDocument().save(getArtifactsDir() + "WorkingWithList.SpecifyListLevel.docx"); + //ExEnd:SpecifyListLevel + } + + @Test + public void restartListNumber() throws Exception { + //ExStart:RestartListNumber + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a list based on a template. + List list1 = doc.getLists().add(ListTemplate.NUMBER_ARABIC_PARENTHESIS); + list1.getListLevels().get(0).getFont().setColor(Color.RED); + list1.getListLevels().get(0).setAlignment(ListLevelAlignment.RIGHT); + + builder.writeln("List 1 starts below:"); + builder.getListFormat().setList(list1); + builder.writeln("Item 1"); + builder.writeln("Item 2"); + builder.getListFormat().removeNumbers(); + + // To reuse the first list, we need to restart numbering by creating a copy of the original list formatting. + List list2 = doc.getLists().addCopy(list1); + + // We can modify the new list in any way, including setting a new start number. + list2.getListLevels().get(0).setStartAt(10); + + builder.writeln("List 2 starts below:"); + builder.getListFormat().setList(list2); + builder.writeln("Item 1"); + builder.writeln("Item 2"); + builder.getListFormat().removeNumbers(); + + builder.getDocument().save(getArtifactsDir() + "WorkingWithList.RestartListNumber.docx"); + //ExEnd:RestartListNumber + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithMarkdown.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithMarkdown.java new file mode 100644 index 00000000..5898cc18 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithMarkdown.java @@ -0,0 +1,401 @@ +package DocsExamples.Programming_with_documents; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +@Test +public class WorkingWithMarkdown extends DocsExamplesBase { + @Test + public void boldText() throws Exception { + //ExStart:BoldText + //GistId:4d42109bdf7df29c28ebfe1550c8e259 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + // Make the text Bold. + builder.getFont().setBold(true); + builder.writeln("This text will be Bold"); + //ExEnd:BoldText + } + + @Test + public void italicText() throws Exception { + //ExStart:ItalicText + //GistId:4d42109bdf7df29c28ebfe1550c8e259 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + // Make the text Italic. + builder.getFont().setItalic(true); + builder.writeln("This text will be Italic"); + //ExEnd:ItalicText + } + + @Test + public void strikethrough() throws Exception { + //ExStart:Strikethrough + //GistId:4d42109bdf7df29c28ebfe1550c8e259 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + // Make the text Strikethrough. + builder.getFont().setStrikeThrough(true); + builder.writeln("This text will be StrikeThrough"); + //ExEnd:Strikethrough + } + + @Test + public void inlineCode() throws Exception { + //ExStart:InlineCode + //GistId:642767bbe8d8bec8eab080120b707990 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + // Number of backticks is missed, one backtick will be used by default. + Style inlineCode1BackTicks = builder.getDocument().getStyles().add(StyleType.CHARACTER, "InlineCode"); + builder.getFont().setStyle(inlineCode1BackTicks); + builder.writeln("Text with InlineCode style with 1 backtick"); + + // There will be 3 backticks. + Style inlineCode3BackTicks = builder.getDocument().getStyles().add(StyleType.CHARACTER, "InlineCode.3"); + builder.getFont().setStyle(inlineCode3BackTicks); + builder.writeln("Text with InlineCode style with 3 backtick"); + //ExEnd:InlineCode + } + + @Test + public void autolink() throws Exception { + //ExStart:Autolink + //GistId:4d42109bdf7df29c28ebfe1550c8e259 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + // Insert hyperlink. + builder.insertHyperlink("https://www.aspose.com", "https://www.aspose.com", false); + builder.insertHyperlink("email@aspose.com", "mailto:email@aspose.com", false); + //ExEnd:Autolink + } + + @Test + public void link() throws Exception { + //ExStart:Link + //GistId:4d42109bdf7df29c28ebfe1550c8e259 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + // Insert hyperlink. + builder.insertHyperlink("Aspose", "https://www.aspose.com", false); + //ExEnd:Link + } + + @Test + public void image() throws Exception { + //ExStart:Image + //GistId:4d42109bdf7df29c28ebfe1550c8e259 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + // Insert image. + Shape shape = builder.insertImage(getImagesDir() + "Logo.jpg"); + shape.getImageData().setTitle("title"); + //ExEnd:Image + } + + @Test + public void horizontalRule() throws Exception { + //ExStart:HorizontalRule + //GistId:4d42109bdf7df29c28ebfe1550c8e259 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + // Insert horizontal rule. + builder.insertHorizontalRule(); + //ExEnd:HorizontalRule + } + + @Test + public void heading() throws Exception { + //ExStart:Heading + //GistId:4d42109bdf7df29c28ebfe1550c8e259 + // Use a document builder to add content to the document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // By default Heading styles in Word may have Bold and Italic formatting. + //If we do not want to be emphasized, set these properties explicitly to false. + builder.getFont().setBold(false); + builder.getFont().setItalic(false); + + builder.writeln("The following produces headings:"); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 1")); + builder.writeln("Heading1"); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 2")); + builder.writeln("Heading2"); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 3")); + builder.writeln("Heading3"); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 4")); + builder.writeln("Heading4"); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 5")); + builder.writeln("Heading5"); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 6")); + builder.writeln("Heading6"); + + // Note, emphases are also allowed inside Headings: + builder.getFont().setBold(true); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 1")); + builder.writeln("Bold Heading1"); + + doc.save(getArtifactsDir() + "WorkingWithMarkdown.Heading.md"); + //ExEnd:Heading + } + + @Test + public void setextHeading() throws Exception { + //ExStart:SetextHeading + //GistId:4d42109bdf7df29c28ebfe1550c8e259 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + builder.getParagraphFormat().setStyleName("Heading 1"); + builder.writeln("This is an H1 tag"); + + // Reset styles from the previous paragraph to not combine styles between paragraphs. + builder.getFont().setBold(false); + builder.getFont().setItalic(false); + + Style setexHeading1 = builder.getDocument().getStyles().add(StyleType.PARAGRAPH, "SetextHeading1"); + builder.getParagraphFormat().setStyle(setexHeading1); + builder.getDocument().getStyles().get("SetextHeading1").setBaseStyleName("Heading 1"); + builder.writeln("Setext Heading level 1"); + + builder.getParagraphFormat().setStyle(builder.getDocument().getStyles().get("Heading 3")); + builder.writeln("This is an H3 tag"); + + // Reset styles from the previous paragraph to not combine styles between paragraphs. + builder.getFont().setBold(false); + builder.getFont().setItalic(false); + + Style setexHeading2 = builder.getDocument().getStyles().add(StyleType.PARAGRAPH, "SetextHeading2"); + builder.getParagraphFormat().setStyle(setexHeading2); + builder.getDocument().getStyles().get("SetextHeading2").setBaseStyleName("Heading 3"); + + // Setex heading level will be reset to 2 if the base paragraph has a Heading level greater than 2. + builder.writeln("Setext Heading level 2"); + //ExEnd:SetextHeading + + builder.getDocument().save(getArtifactsDir() + "WorkingWithMarkdown.SetextHeading.md"); + } + + @Test + public void indentedCode() throws Exception { + //ExStart:IndentedCode + //GistId:4d42109bdf7df29c28ebfe1550c8e259 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + Style indentedCode = builder.getDocument().getStyles().add(StyleType.PARAGRAPH, "IndentedCode"); + builder.getParagraphFormat().setStyle(indentedCode); + builder.writeln("This is an indented code"); + //ExEnd:IndentedCode + } + + @Test + public void fencedCode() throws Exception { + //ExStart:FencedCode + //GistId:4d42109bdf7df29c28ebfe1550c8e259 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + Style fencedCode = builder.getDocument().getStyles().add(StyleType.PARAGRAPH, "FencedCode"); + builder.getParagraphFormat().setStyle(fencedCode); + builder.writeln("This is an fenced code"); + + Style fencedCodeWithInfo = builder.getDocument().getStyles().add(StyleType.PARAGRAPH, "FencedCode.C#"); + builder.getParagraphFormat().setStyle(fencedCodeWithInfo); + builder.writeln("This is a fenced code with info string"); + //ExEnd:FencedCode + } + + @Test + public void quote() throws Exception { + //ExStart:Quote + //GistId:4d42109bdf7df29c28ebfe1550c8e259 + // Use a document builder to add content to the document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // By default a document stores blockquote style for the first level. + builder.getParagraphFormat().setStyleName("Quote"); + builder.writeln("Blockquote"); + + // Create styles for nested levels through style inheritance. + Style quoteLevel2 = builder.getDocument().getStyles().add(StyleType.PARAGRAPH, "Quote1"); + builder.getParagraphFormat().setStyle(quoteLevel2); + builder.getDocument().getStyles().get("Quote1").setBaseStyleName("Quote"); + builder.writeln("1. Nested blockquote"); + + doc.save(getArtifactsDir() + "WorkingWithMarkdown.Quote.md"); + //ExEnd:Quote + } + + @Test + public void bulletedList() throws Exception { + //ExStart:BulletedList + //GistId:4d42109bdf7df29c28ebfe1550c8e259 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + builder.getListFormat().applyBulletDefault(); + builder.getListFormat().getList().getListLevels().get(0).setNumberFormat("-"); + + builder.writeln("Item 1"); + builder.writeln("Item 2"); + + builder.getListFormat().listIndent(); + + builder.writeln("Item 2a"); + builder.writeln("Item 2b"); + //ExEnd:BulletedList + } + + @Test + public void orderedList() throws Exception { + //ExStart:OrderedList + //GistId:4d42109bdf7df29c28ebfe1550c8e259 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getListFormat().applyNumberDefault(); + + builder.writeln("Item 1"); + builder.writeln("Item 2"); + + builder.getListFormat().listIndent(); + + builder.writeln("Item 2a"); + builder.writeln("Item 2b"); + //ExEnd:OrderedList + } + + @Test + public void table() throws Exception { + //ExStart:Table + //GistId:4d42109bdf7df29c28ebfe1550c8e259 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + // Add the first row. + builder.insertCell(); + builder.writeln("a"); + builder.insertCell(); + builder.writeln("b"); + + builder.endRow(); + + // Add the second row. + builder.insertCell(); + builder.writeln("c"); + builder.insertCell(); + builder.writeln("d"); + //ExEnd:Table + } + + @Test + public void readMarkdownDocument() throws Exception { + //ExStart:ReadMarkdownDocument + //GistId:50b2b6a8785c07713e7c09d772e9a396 + Document doc = new Document(getMyDir() + "Quotes.md"); + + // Let's remove Heading formatting from a Quote in the very last paragraph. + Paragraph paragraph = doc.getFirstSection().getBody().getLastParagraph(); + paragraph.getParagraphFormat().setStyle(doc.getStyles().get("Quote")); + + doc.save(getArtifactsDir() + "WorkingWithMarkdown.ReadMarkdownDocument.md"); + //ExEnd:ReadMarkdownDocument + } + + @Test + public void emphases() throws Exception { + //ExStart:Emphases + //GistId:50b2b6a8785c07713e7c09d772e9a396 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Markdown treats asterisks (*) and underscores (_) as indicators of emphasis."); + builder.write("You can write "); + + builder.getFont().setBold(true); + builder.write("bold"); + + builder.getFont().setBold(false); + builder.write(" or "); + + builder.getFont().setItalic(true); + builder.write("italic"); + + builder.getFont().setItalic(false); + builder.writeln(" text. "); + + builder.write("You can also write "); + builder.getFont().setBold(true); + + builder.getFont().setItalic(true); + builder.write("BoldItalic"); + + builder.getFont().setBold(false); + builder.getFont().setItalic(false); + builder.write("text."); + + builder.getDocument().save(getArtifactsDir() + "WorkingWithMarkdown.Emphases.md"); + //ExEnd:Emphases + } + + @Test + public void useWarningSource() throws Exception { + //ExStart:UseWarningSourceMarkdown + Document doc = new Document(getMyDir() + "Emphases markdown warning.docx"); + + WarningInfoCollection warnings = new WarningInfoCollection(); + doc.setWarningCallback(warnings); + + doc.save(getArtifactsDir() + "WorkingWithMarkdown.UseWarningSource.md"); + + for (WarningInfo warningInfo : warnings) { + if (warningInfo.getSource() == WarningSource.MARKDOWN) + System.out.println(warningInfo.getDescription()); + } + //ExEnd:UseWarningSourceMarkdown + } + + @Test + public void supportedFeatures() throws Exception { + //ExStart:SupportedFeatures + //GistId:642767bbe8d8bec8eab080120b707990 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Specify the "Heading 1" style for the paragraph. + builder.insertParagraph(); + builder.getParagraphFormat().setStyleName("Heading 1"); + builder.write("Heading 1"); + + // Specify the Italic emphasis for the paragraph. + builder.insertParagraph(); + // Reset styles from the previous paragraph to not combine styles between paragraphs. + builder.getParagraphFormat().setStyleName("Normal"); + builder.getFont().setItalic(true); + builder.write("Italic Text"); + // Reset styles from the previous paragraph to not combine styles between paragraphs. + builder.setItalic(false); + + // Specify a Hyperlink for the desired text. + builder.insertParagraph(); + builder.insertHyperlink("Aspose", "https://www.aspose.com", false); + builder.write("Aspose"); + + // Save your document as a Markdown file. + doc.save(getArtifactsDir() + "WorkingWithMarkdown.SupportedFeatures.md"); + //ExEnd:SupportedFeatures + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithNode.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithNode.java new file mode 100644 index 00000000..c74df448 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithNode.java @@ -0,0 +1,128 @@ +package DocsExamples.Programming_with_documents; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +@Test +public class WorkingWithNode extends DocsExamplesBase { + @Test + public void getNodeType() throws Exception { + //ExStart:GetNodeType + //GistId:3e9d92093b2f5995f984791bfc10c944 + Document doc = new Document(); + int type = doc.getNodeType(); + //ExEnd:GetNodeType + } + + @Test + public void getParentNode() throws Exception { + //ExStart:GetParentNode + //GistId:3e9d92093b2f5995f984791bfc10c944 + Document doc = new Document(); + // The section is the first child node of the document. + Node section = doc.getFirstChild(); + // The section's parent node is the document. + System.out.println("Section parent is the document: " + (doc == section.getParentNode())); + //ExEnd:GetParentNode + } + + @Test + public void ownerDocument() throws Exception { + //ExStart:OwnerDocument + //GistId:3e9d92093b2f5995f984791bfc10c944 + Document doc = new Document(); + + // Creating a new node of any type requires a document passed into the constructor. + Paragraph para = new Paragraph(doc); + // The new paragraph node does not yet have a parent. + System.out.println("Paragraph has no parent node: " + (para.getParentNode() == null)); + // But the paragraph node knows its document. + System.out.println("Both nodes' documents are the same: " + (para.getDocument() == doc)); + // The fact that a node always belongs to a document allows us to access and modify + // properties that reference the document-wide data, such as styles or lists. + para.getParagraphFormat().setStyleName("Heading 1"); + // Now add the paragraph to the main text of the first section. + doc.getFirstSection().getBody().appendChild(para); + + // The paragraph node is now a child of the Body node. + System.out.println("Paragraph has a parent node: " + (para.getParentNode() != null)); + //ExEnd:OwnerDocument + } + + @Test + public void enumerateChildNodes() throws Exception { + //ExStart:EnumerateChildNodes + //GistId:3e9d92093b2f5995f984791bfc10c944 + Document doc = new Document(); + Paragraph paragraph = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 0, true); + + NodeCollection children = paragraph.getChildNodes(NodeType.ANY, false); + for (Node child : (Iterable) children) { + // A paragraph may contain children of various types such as runs, shapes, and others. + if (child.getNodeType() == NodeType.RUN) { + Run run = (Run) child; + System.out.println(run.getText()); + } + } + //ExEnd:EnumerateChildNodes + } + + @Test + //ExStart:RecurseAllNodes + //GistId:3e9d92093b2f5995f984791bfc10c944 + public void recurseAllNodes() throws Exception { + Document doc = new Document(getMyDir() + "Paragraphs.docx"); + // Invoke the recursive function that will walk the tree. + traverseAllNodes(doc); + } + + /// + /// A simple function that will walk through all children of a specified node recursively + /// and print the type of each node to the screen. + /// + private static void traverseAllNodes(CompositeNode parentNode) { + // This is the most efficient way to loop through immediate children of a node. + for (Node childNode = parentNode.getFirstChild(); childNode != null; childNode = childNode.getNextSibling()) { + System.out.println(Node.nodeTypeToString(childNode.getNodeType())); + + // Recurse into the node if it is a composite node. + if (childNode.isComposite()) + traverseAllNodes((CompositeNode) childNode); + } + } + //ExEnd:RecurseAllNodes + + @Test + public void typedAccess() throws Exception { + //ExStart:TypedAccess + //GistId:3e9d92093b2f5995f984791bfc10c944 + Document doc = new Document(); + + Section section = doc.getFirstSection(); + Body body = section.getBody(); + // Quick typed access to all Table child nodes contained in the Body. + TableCollection tables = body.getTables(); + + for (Table table : tables) { + // Quick typed access to the first row of the table. + table.getFirstRow().remove(); + + // Quick typed access to the last row of the table. + table.getLastRow().remove(); + } + //ExEnd:TypedAccess + } + + @Test + public void createAndAddParagraphNode() throws Exception { + //ExStart:CreateAndAddParagraphNode + Document doc = new Document(); + + Paragraph para = new Paragraph(doc); + + Section section = doc.getLastSection(); + section.getBody().appendChild(para); + //ExEnd:CreateAndAddParagraphNode + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithOleObjectsAndActiveX.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithOleObjectsAndActiveX.java new file mode 100644 index 00000000..a767b363 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithOleObjectsAndActiveX.java @@ -0,0 +1,149 @@ +package DocsExamples.Programming_with_documents; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.apache.commons.io.FileUtils; +import org.testng.annotations.Test; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Paths; + +@Test +public class WorkingWithOleObjectsAndActiveX extends DocsExamplesBase { + @Test + public void insertOleObject() throws Exception { + //ExStart:InsertOleObject + //GistId:4996b573cf231d9f66ab0d1f3f981222 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertOleObject("http://www.aspose.com", "htmlfile", true, true, null); + + doc.save(getArtifactsDir() + "WorkingWithOleObjectsAndActiveX.InsertOleObject.docx"); + //ExEnd:InsertOleObject + } + + @Test + public void insertOleObjectWithOlePackage() throws Exception { + //ExStart:InsertOleObjectwithOlePackage + //GistId:4996b573cf231d9f66ab0d1f3f981222 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + byte[] bs = FileUtils.readFileToByteArray(new File(getMyDir() + "Zip file.zip")); + + try (ByteArrayInputStream stream = new ByteArrayInputStream(bs)) { + Shape shape = builder.insertOleObject(stream, "Package", true, null); + OlePackage olePackage = shape.getOleFormat().getOlePackage(); + olePackage.setFileName("filename.zip"); + olePackage.setDisplayName("displayname.zip"); + + doc.save(getArtifactsDir() + "WorkingWithOleObjectsAndActiveX.InsertOleObjectWithOlePackage.docx"); + } + //ExEnd:InsertOleObjectwithOlePackage + + //ExStart:GetAccessToOleObjectRawData + //GistId:4996b573cf231d9f66ab0d1f3f981222 + Shape oleShape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + byte[] oleRawData = oleShape.getOleFormat().getRawData(); + //ExEnd:GetAccessToOleObjectRawData + } + + @Test + public void insertOleObjectAsIcon() throws Exception { + //ExStart:InsertOleObjectAsIcon + //GistId:4996b573cf231d9f66ab0d1f3f981222 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertOleObjectAsIcon(getMyDir() + "Presentation.pptx", false, getImagesDir() + "Logo icon.ico", + "My embedded file"); + + doc.save(getArtifactsDir() + "WorkingWithOleObjectsAndActiveX.InsertOleObjectAsIcon.docx"); + //ExEnd:InsertOleObjectAsIcon + } + + @Test + public void insertOleObjectAsIconUsingStream() throws Exception { + //ExStart:InsertOleObjectAsIconUsingStream + //GistId:4996b573cf231d9f66ab0d1f3f981222 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + try (ByteArrayInputStream stream = new ByteArrayInputStream(FileUtils.readFileToByteArray(new File(getMyDir() + "Presentation.pptx")))) { + builder.insertOleObjectAsIcon(stream, "Package", getImagesDir() + "Logo icon.ico", "My embedded file"); + } + + doc.save(getArtifactsDir() + "WorkingWithOleObjectsAndActiveX.InsertOleObjectAsIconUsingStream.docx"); + //ExEnd:InsertOleObjectAsIconUsingStream + } + + @Test + public void readActiveXControlProperties() throws Exception { + Document doc = new Document(getMyDir() + "ActiveX controls.docx"); + + String properties = ""; + for (Shape shape : (Iterable) doc.getChildNodes(NodeType.SHAPE, true)) { + if (shape.getOleFormat() == null) break; + + OleControl oleControl = shape.getOleFormat().getOleControl(); + if (oleControl.isForms2OleControl()) { + Forms2OleControl checkBox = (Forms2OleControl) oleControl; + properties = properties + "\nCaption: " + checkBox.getCaption(); + properties = properties + "\nValue: " + checkBox.getValue(); + properties = properties + "\nEnabled: " + checkBox.getEnabled(); + properties = properties + "\nType: " + checkBox.getType(); + if (checkBox.getChildNodes() != null) { + properties = properties + "\nChildNodes: " + checkBox.getChildNodes(); + } + + properties += "\n"; + } + } + + properties = properties + "\nTotal ActiveX Controls found: " + doc.getChildNodes(NodeType.SHAPE, true).getCount(); + System.out.println("\n" + properties); + } + + @Test + public void insertOnlineVideo() throws Exception { + //ExStart:InsertOnlineVideo + //GistId:4996b573cf231d9f66ab0d1f3f981222 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + String url = "https://youtu.be/t_1LYZ102RA"; + double width = 360.0; + double height = 270.0; + + Shape shape = builder.insertOnlineVideo(url, width, height); + + doc.save(getArtifactsDir() + "WorkingWithOleObjectsAndActiveX.InsertOnlineVideo.docx"); + //ExEnd:InsertOnlineVideo + } + + @Test + public void insertOnlineVideoWithEmbedHtml() throws Exception { + //ExStart:InsertOnlineVideoWithEmbedHtml + //GistId:4996b573cf231d9f66ab0d1f3f981222 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + double width = 360.0; + double height = 270.0; + + String videoUrl = "https://vimeo.com/52477838"; + String videoEmbedCode = + ""; + + byte[] thumbnailImageBytes = Files.readAllBytes(Paths.get(getImagesDir() + "Logo.jpg")); + + builder.insertOnlineVideo(videoUrl, videoEmbedCode, thumbnailImageBytes, width, height); + + doc.save(getArtifactsDir() + "WorkingWithOleObjectsAndActiveX.InsertOnlineVideoWithEmbedHtml.docx"); + //ExEnd:InsertOnlineVideoWithEmbedHtml + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithRevisions.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithRevisions.java new file mode 100644 index 00000000..689fc9f5 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithRevisions.java @@ -0,0 +1,258 @@ +package DocsExamples.Programming_with_documents; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.apache.commons.collections4.IterableUtils; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.text.MessageFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.List; + +@Test +public class WorkingWithRevisions extends DocsExamplesBase { + @Test + public void acceptRevisions() throws Exception { + //ExStart:AcceptAllRevisions + //GistId:e8d71fde166d275d0fc9471c56c3ad39 + Document doc = new Document(); + Body body = doc.getFirstSection().getBody(); + Paragraph para = body.getFirstParagraph(); + + // Add text to the first paragraph, then add two more paragraphs. + para.appendChild(new Run(doc, "Paragraph 1. ")); + body.appendParagraph("Paragraph 2. "); + body.appendParagraph("Paragraph 3. "); + + // We have three paragraphs, none of which registered as any type of revision + // If we add/remove any content in the document while tracking revisions, + // they will be displayed as such in the document and can be accepted/rejected. + doc.startTrackRevisions("John Doe", new Date()); + + // This paragraph is a revision and will have the according "IsInsertRevision" flag set. + para = body.appendParagraph("Paragraph 4. "); + Assert.assertTrue(para.isInsertRevision()); + + // Get the document's paragraph collection and remove a paragraph. + ParagraphCollection paragraphs = body.getParagraphs(); + Assert.assertEquals(4, paragraphs.getCount()); + para = paragraphs.get(2); + para.remove(); + + // Since we are tracking revisions, the paragraph still exists in the document, will have the "IsDeleteRevision" set + // and will be displayed as a revision in Microsoft Word, until we accept or reject all revisions. + Assert.assertEquals(4, paragraphs.getCount()); + Assert.assertTrue(para.isDeleteRevision()); + + // The delete revision paragraph is removed once we accept changes. + doc.acceptAllRevisions(); + Assert.assertEquals(3, paragraphs.getCount()); + Assert.assertEquals(para.getRuns().getCount(), 0); //was Is.Empty + + // Stopping the tracking of revisions makes this text appear as normal text. + // Revisions are not counted when the document is changed. + doc.stopTrackRevisions(); + + // Save the document. + doc.save(getArtifactsDir() + "WorkingWithRevisions.AcceptRevisions.docx"); + //ExEnd:AcceptAllRevisions + } + + @Test + public void getRevisionTypes() throws Exception { + //ExStart:GetRevisionTypes + Document doc = new Document(getMyDir() + "Revisions.docx"); + + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + for (int i = 0; i < paragraphs.getCount(); i++) { + if (paragraphs.get(i).isMoveFromRevision()) + System.out.println(MessageFormat.format("The paragraph {0} has been moved (deleted).", i)); + if (paragraphs.get(i).isMoveToRevision()) + System.out.println(MessageFormat.format("The paragraph {0} has been moved (inserted).", i)); + } + //ExEnd:GetRevisionTypes + } + + @Test + public void getRevisionGroups() throws Exception { + //ExStart:GetRevisionGroups + Document doc = new Document(getMyDir() + "Revisions.docx"); + + for (RevisionGroup group : doc.getRevisions().getGroups()) { + System.out.println(MessageFormat.format("{0}, {1}:", group.getAuthor(), group.getRevisionType())); + System.out.println(group.getText()); + } + //ExEnd:GetRevisionGroups + } + + @Test + public void removeCommentsInPdf() throws Exception { + //ExStart:RemoveCommentsInPDF + Document doc = new Document(getMyDir() + "Revisions.docx"); + + // Do not render the comments in PDF. + doc.getLayoutOptions().setCommentDisplayMode(CommentDisplayMode.HIDE); + + doc.save(getArtifactsDir() + "WorkingWithRevisions.RemoveCommentsInPdf.pdf"); + //ExEnd:RemoveCommentsInPDF + } + + @Test + public void showRevisionsInBalloons() throws Exception { + //ExStart:ShowRevisionsInBalloons + //GistId:ce015d9bade4e0294485ffb47462ded4 + //ExStart:SetMeasurementUnit + //ExStart:SetRevisionBarsPosition + Document doc = new Document(getMyDir() + "Revisions.docx"); + + // Renders insert revisions inline, delete and format revisions in balloons. + doc.getLayoutOptions().getRevisionOptions().setShowInBalloons(ShowInBalloons.FORMAT_AND_DELETE); + doc.getLayoutOptions().getRevisionOptions().setMeasurementUnit(MeasurementUnits.INCHES); + // Renders revision bars on the right side of a page. + doc.getLayoutOptions().getRevisionOptions().setRevisionBarsPosition(HorizontalAlignment.RIGHT); + + doc.save(getArtifactsDir() + "WorkingWithRevisions.ShowRevisionsInBalloons.pdf"); + //ExEnd:SetRevisionBarsPosition + //ExEnd:SetMeasurementUnit + //ExEnd:ShowRevisionsInBalloons + } + + @Test + public void getRevisionGroupDetails() throws Exception { + //ExStart:GetRevisionGroupDetails + Document doc = new Document(getMyDir() + "Revisions.docx"); + + for (Revision revision : doc.getRevisions()) { + String groupText = revision.getGroup() != null + ? "Revision group text: " + revision.getGroup().getText() + : "Revision has no group"; + + System.out.println("Type: " + revision.getRevisionType()); + System.out.println("Author: " + revision.getAuthor()); + System.out.println("Date: " + revision.getDateTime()); + System.out.println("Revision text: " + revision.getParentNode().toString(SaveFormat.TEXT)); + System.out.println(groupText); + } + //ExEnd:GetRevisionGroupDetails + } + + @Test + public void accessRevisedVersion() throws Exception { + //ExStart:AccessRevisedVersion + Document doc = new Document(getMyDir() + "Revisions.docx"); + doc.updateListLabels(); + + // Switch to the revised version of the document. + doc.setRevisionsView(RevisionsView.FINAL); + + for (Revision revision : doc.getRevisions()) { + if (revision.getParentNode().getNodeType() == NodeType.PARAGRAPH) { + Paragraph paragraph = (Paragraph) revision.getParentNode(); + if (paragraph.isListItem()) { + System.out.println(paragraph.getListLabel().getLabelString()); + System.out.println(paragraph.getListFormat().getListLevel()); + } + } + } + //ExEnd:AccessRevisedVersion + } + + @Test + public void moveNodeInTrackedDocument() throws Exception { + //ExStart:MoveNodeInTrackedDocument + //GistId:e8d71fde166d275d0fc9471c56c3ad39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Paragraph 1"); + builder.writeln("Paragraph 2"); + builder.writeln("Paragraph 3"); + builder.writeln("Paragraph 4"); + builder.writeln("Paragraph 5"); + builder.writeln("Paragraph 6"); + Body body = doc.getFirstSection().getBody(); + System.out.println(MessageFormat.format("Paragraph count: {0}", body.getParagraphs().getCount())); + + Calendar calendar = new GregorianCalendar(2020, Calendar.DECEMBER, 23); + calendar.set(Calendar.HOUR, 14); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + + // Start tracking revisions. + doc.startTrackRevisions("Author", calendar.getTime()); + + // Generate revisions when moving a node from one location to another. + Node node = body.getParagraphs().get(3); + Node endNode = body.getParagraphs().get(5).getNextSibling(); + Node referenceNode = body.getParagraphs().get(0); + while (node != endNode) { + Node nextNode = node.getNextSibling(); + body.insertBefore(node, referenceNode); + node = nextNode; + } + + // Stop the process of tracking revisions. + doc.stopTrackRevisions(); + + // There are 3 additional paragraphs in the move-from range. + System.out.println(MessageFormat.format("Paragraph count: {0}", body.getParagraphs().getCount())); + doc.save(getArtifactsDir() + "WorkingWithRevisions.MoveNodeInTrackedDocument.docx"); + //ExEnd:MoveNodeInTrackedDocument + } + + @Test + public void shapeRevision() throws Exception { + //ExStart:ShapeRevision + //GistId:e8d71fde166d275d0fc9471c56c3ad39 + Document doc = new Document(); + + // Insert an inline shape without tracking revisions. + Assert.assertFalse(doc.getTrackRevisions()); + Shape shape = new Shape(doc, ShapeType.CUBE); + shape.setWrapType(WrapType.INLINE); + shape.setWidth(100.0); + shape.setHeight(100.0); + doc.getFirstSection().getBody().getFirstParagraph().appendChild(shape); + + // Start tracking revisions and then insert another shape. + doc.startTrackRevisions("John Doe"); + shape = new Shape(doc, ShapeType.SUN); + shape.setWrapType(WrapType.INLINE); + shape.setWidth(100.0); + shape.setHeight(100.0); + doc.getFirstSection().getBody().getFirstParagraph().appendChild(shape); + + // Get the document's shape collection which includes just the two shapes we added. + List shapes = IterableUtils.toList(doc.getChildNodes(NodeType.SHAPE, true)); + Assert.assertEquals(2, shapes.size()); + + // Remove the first shape. + shapes.get(0).remove(); + + // Because we removed that shape while changes were being tracked, the shape counts as a delete revision. + Assert.assertEquals(ShapeType.CUBE, shapes.get(0).getShapeType()); + Assert.assertTrue(shapes.get(0).isDeleteRevision()); + + // And we inserted another shape while tracking changes, so that shape will count as an insert revision. + Assert.assertEquals(ShapeType.SUN, shapes.get(1).getShapeType()); + Assert.assertTrue(shapes.get(1).isInsertRevision()); + + // The document has one shape that was moved, but shape move revisions will have two instances of that shape. + // One will be the shape at its arrival destination and the other will be the shape at its original location. + doc = new Document(getMyDir() + "Revision shape.docx"); + + shapes = IterableUtils.toList(doc.getChildNodes(NodeType.SHAPE, true)); + Assert.assertEquals(2, shapes.size()); + + // This is the move to revision, also the shape at its arrival destination. + Assert.assertFalse(shapes.get(0).isMoveFromRevision()); + Assert.assertTrue(shapes.get(0).isMoveToRevision()); + + // This is the move from revision, which is the shape at its original location. + Assert.assertTrue(shapes.get(1).isMoveFromRevision()); + Assert.assertFalse(shapes.get(1).isMoveToRevision()); + //ExEnd:ShapeRevision + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithSection.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithSection.java new file mode 100644 index 00000000..e951ec30 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithSection.java @@ -0,0 +1,232 @@ +package DocsExamples.Programming_with_documents; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.text.MessageFormat; + +@Test +public class WorkingWithSection extends DocsExamplesBase { + @Test + public void addSection() throws Exception { + //ExStart:AddSection + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello1"); + builder.writeln("Hello2"); + + Section sectionToAdd = new Section(doc); + doc.getSections().add(sectionToAdd); + //ExEnd:AddSection + } + + @Test + public void deleteSection() throws Exception { + //ExStart:DeleteSection + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello1"); + doc.appendChild(new Section(doc)); + builder.writeln("Hello2"); + doc.appendChild(new Section(doc)); + + doc.getSections().removeAt(0); + //ExEnd:DeleteSection + } + + @Test + public void deleteAllSections() throws Exception { + //ExStart:DeleteAllSections + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello1"); + doc.appendChild(new Section(doc)); + builder.writeln("Hello2"); + doc.appendChild(new Section(doc)); + + doc.getSections().clear(); + //ExEnd:DeleteAllSections + } + + @Test + public void appendSectionContent() throws Exception { + //ExStart:AppendSectionContent + //GistId:7c0668453e53ed7a57d3ea3a05520f21 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Section 1"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.write("Section 2"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.write("Section 3"); + + // This is the section that we will append and prepend to. + Section section = doc.getSections().get(2); + + // Insert the contents of the first section to the beginning of the third section. + Section sectionToPrepend = doc.getSections().get(0); + section.prependContent(sectionToPrepend); + + // Insert the contents of the second section to the end of the third section. + Section sectionToAppend = doc.getSections().get(1); + section.appendContent(sectionToAppend); + //ExEnd:AppendSectionContent + } + + @Test + public void cloneSection() throws Exception { + //ExStart:CloneSection + //GistId:7c0668453e53ed7a57d3ea3a05520f21 + Document doc = new Document(getMyDir() + "Document.docx"); + Section cloneSection = doc.getSections().get(0).deepClone(); + //ExEnd:CloneSection + } + + @Test + public void copySection() throws Exception { + //ExStart:CopySection + //GistId:7c0668453e53ed7a57d3ea3a05520f21 + Document srcDoc = new Document(getMyDir() + "Document.docx"); + Document dstDoc = new Document(); + + Section sourceSection = srcDoc.getSections().get(0); + Section newSection = (Section) dstDoc.importNode(sourceSection, true); + dstDoc.getSections().add(newSection); + + dstDoc.save(getArtifactsDir() + "WorkingWithSection.CopySection.docx"); + //ExEnd:CopySection + } + + @Test + public void deleteHeaderFooterContent() throws Exception { + //ExStart:DeleteHeaderFooterContent + //GistId:7c0668453e53ed7a57d3ea3a05520f21 + Document doc = new Document(getMyDir() + "Document.docx"); + + Section section = doc.getSections().get(0); + section.clearHeadersFooters(); + //ExEnd:DeleteHeaderFooterContent + } + + @Test + public void deleteHeaderFooterShapes() throws Exception { + //ExStart:DeleteHeaderFooterShapes + //GistId:7c0668453e53ed7a57d3ea3a05520f21 + Document doc = new Document(getMyDir() + "Document.docx"); + + Section section = doc.getSections().get(0); + section.deleteHeaderFooterShapes(); + //ExEnd:DeleteHeaderFooterShapes + } + + @Test + public void deleteSectionContent() throws Exception { + //ExStart:DeleteSectionContent + Document doc = new Document(getMyDir() + "Document.docx"); + + Section section = doc.getSections().get(0); + section.clearContent(); + //ExEnd:DeleteSectionContent + } + + @Test + public void modifyPageSetupInAllSections() throws Exception { + //ExStart:ModifyPageSetupInAllSections + //GistId:7c0668453e53ed7a57d3ea3a05520f21 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Section 1"); + doc.appendChild(new Section(doc)); + builder.writeln("Section 2"); + doc.appendChild(new Section(doc)); + builder.writeln("Section 3"); + doc.appendChild(new Section(doc)); + builder.writeln("Section 4"); + + // It is important to understand that a document can contain many sections, + // and each section has its page setup. In this case, we want to modify them all. + for (Section section : doc.getSections()) + section.getPageSetup().setPaperSize(PaperSize.LETTER); + + doc.save(getArtifactsDir() + "WorkingWithSection.ModifyPageSetupInAllSections.doc"); + //ExEnd:ModifyPageSetupInAllSections + } + + @Test + public void sectionsAccessByIndex() throws Exception { + //ExStart:SectionsAccessByIndex + Document doc = new Document(getMyDir() + "Document.docx"); + + Section section = doc.getSections().get(0); + section.getPageSetup().setLeftMargin(90.0); // 3.17 cm + section.getPageSetup().setRightMargin(90.0); // 3.17 cm + section.getPageSetup().setTopMargin(72.0); // 2.54 cm + section.getPageSetup().setBottomMargin(72.0); // 2.54 cm + section.getPageSetup().setHeaderDistance(35.4); // 1.25 cm + section.getPageSetup().setFooterDistance(35.4); // 1.25 cm + section.getPageSetup().getTextColumns().setSpacing(35.4); // 1.25 cm + //ExEnd:SectionsAccessByIndex + } + + @Test + public void sectionChildNodes() throws Exception { + //ExStart:SectionChildNodes + //GistId:7c0668453e53ed7a57d3ea3a05520f21 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Section 1"); + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.write("Primary header"); + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + builder.write("Primary footer"); + + Section section = doc.getFirstSection(); + + // A Section is a composite node and can contain child nodes, + // but only if those child nodes are of a "Body" or "HeaderFooter" node type. + for (Node node : section) { + switch (node.getNodeType()) { + case NodeType.BODY: { + Body body = (Body) node; + + System.out.println("Body:"); + System.out.println(MessageFormat.format("\t\"{0}\"", body.getText().trim())); + break; + } + case NodeType.HEADER_FOOTER: { + HeaderFooter headerFooter = (HeaderFooter) node; + + System.out.println(MessageFormat.format("HeaderFooter type: {0}:", headerFooter.getHeaderFooterType())); + System.out.println(MessageFormat.format("\t\"{0}\"", headerFooter.getText().trim())); + break; + } + default: { + throw new Exception("Unexpected node type in a section."); + } + } + } + //ExEnd:SectionChildNodes + } + + @Test + public void ensureMinimum() throws Exception { + //ExStart:EnsureMinimum + //GistId:7c0668453e53ed7a57d3ea3a05520f21 + Document doc = new Document(); + + // If we add a new section like this, it will not have a body, or any other child nodes. + doc.getSections().add(new Section(doc)); + // Run the "EnsureMinimum" method to add a body and a paragraph to this section to begin editing it. + doc.getLastSection().ensureMinimum(); + + doc.getSections().get(0).getBody().getFirstParagraph().appendChild(new Run(doc, "Hello world!")); + //ExEnd:EnsureMinimum + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithTextboxes.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithTextboxes.java new file mode 100644 index 00000000..c801e8a3 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithTextboxes.java @@ -0,0 +1,71 @@ +package DocsExamples.Programming_with_documents; + +import com.aspose.words.Document; +import com.aspose.words.Shape; +import com.aspose.words.ShapeType; +import com.aspose.words.TextBox; +import org.testng.annotations.Test; + +@Test +public class WorkingWithTextboxes { + @Test + public void createLink() throws Exception { + //ExStart:CreateLink + //GistId:68b6041746b3d6bf5137cff8e6385b5f + Document doc = new Document(); + + Shape shape1 = new Shape(doc, ShapeType.TEXT_BOX); + Shape shape2 = new Shape(doc, ShapeType.TEXT_BOX); + + TextBox textBox1 = shape1.getTextBox(); + TextBox textBox2 = shape2.getTextBox(); + + if (textBox1.isValidLinkTarget(textBox2)) + textBox1.setNext(textBox2); + //ExEnd:CreateLink + } + + @Test + public void checkSequence() throws Exception { + //ExStart:CheckSequence + //GistId:68b6041746b3d6bf5137cff8e6385b5f + Document doc = new Document(); + + Shape shape = new Shape(doc, ShapeType.TEXT_BOX); + TextBox textBox = shape.getTextBox(); + + if (textBox.getNext() != null && textBox.getPrevious() == null) { + System.out.println("The head of the sequence"); + } + + if (textBox.getNext() != null && textBox.getPrevious() != null) { + System.out.println("The Middle of the sequence."); + } + + if (textBox.getNext() == null && textBox.getPrevious() != null) { + System.out.println("The Tail of the sequence."); + } + //ExEnd:CheckSequence + } + + @Test + public void breakLink() throws Exception { + //ExStart:BreakLink + //GistId:68b6041746b3d6bf5137cff8e6385b5f + Document doc = new Document(); + + Shape shape = new Shape(doc, ShapeType.TEXT_BOX); + TextBox textBox = shape.getTextBox(); + + // Break a forward link. + textBox.breakForwardLink(); + + // Break a forward link by setting a null. + textBox.setNext(null); + + // Break a link, which leads to this textbox. + if (textBox.getPrevious() != null) + textBox.getPrevious().breakForwardLink(); + //ExEnd:BreakLink + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithVbaMacros.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithVbaMacros.java new file mode 100644 index 00000000..4af38153 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/WorkingWithVbaMacros.java @@ -0,0 +1,158 @@ +package DocsExamples.Programming_with_documents; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +@Test +public class WorkingWithVbaMacros extends DocsExamplesBase { + @Test + public void createVbaProject() throws Exception { + //ExStart:CreateVbaProject + //GistId:d9bac4ed890f81ea3de392ecfeedbc55 + Document doc = new Document(); + + VbaProject project = new VbaProject(); + project.setName("AsposeProject"); + doc.setVbaProject(project); + + // Create a new module and specify a macro source code. + VbaModule module = new VbaModule(); + module.setName("AsposeModule"); + module.setType(VbaModuleType.PROCEDURAL_MODULE); + module.setSourceCode("New source code"); + + // Add module to the VBA project. + doc.getVbaProject().getModules().add(module); + + doc.save(getArtifactsDir() + "WorkingWithVba.CreateVbaProject.docm"); + //ExEnd:CreateVbaProject + } + + @Test + public void readVbaMacros() throws Exception { + //ExStart:ReadVbaMacros + //GistId:d9bac4ed890f81ea3de392ecfeedbc55 + Document doc = new Document(getMyDir() + "VBA project.docm"); + + if (doc.getVbaProject() != null) { + for (VbaModule module : doc.getVbaProject().getModules()) { + System.out.println(module.getSourceCode()); + } + } + //ExEnd:ReadVbaMacros + } + + @Test + public void modifyVbaMacros() throws Exception { + //ExStart:ModifyVbaMacros + //GistId:d9bac4ed890f81ea3de392ecfeedbc55 + Document doc = new Document(getMyDir() + "VBA project.docm"); + + VbaProject project = doc.getVbaProject(); + + final String NEW_SOURCE_CODE = "Test change source code"; + project.getModules().get(0).setSourceCode(NEW_SOURCE_CODE); + //ExEnd:ModifyVbaMacros + + doc.save(getArtifactsDir() + "WorkingWithVba.ModifyVbaMacros.docm"); + //ExEnd:ModifyVbaMacros + } + + @Test + public void cloneVbaProject() throws Exception { + //ExStart:CloneVbaProject + //GistId:d9bac4ed890f81ea3de392ecfeedbc55 + Document doc = new Document(getMyDir() + "VBA project.docm"); + Document destDoc = new Document(); + { + destDoc.setVbaProject(doc.getVbaProject().deepClone()); + } + + destDoc.save(getArtifactsDir() + "WorkingWithVba.CloneVbaProject.docm"); + //ExEnd:CloneVbaProject + } + + @Test + public void cloneVbaModule() throws Exception { + //ExStart:CloneVbaModule + //GistId:d9bac4ed890f81ea3de392ecfeedbc55 + Document doc = new Document(getMyDir() + "VBA project.docm"); + Document destDoc = new Document(); + { + destDoc.setVbaProject(new VbaProject()); + } + + VbaModule copyModule = doc.getVbaProject().getModules().get("Module1").deepClone(); + destDoc.getVbaProject().getModules().add(copyModule); + + destDoc.save(getArtifactsDir() + "WorkingWithVba.CloneVbaModule.docm"); + //ExEnd:CloneVbaModule + } + + @Test + public void removeVbaReferences() throws Exception { + //ExStart:RemoveVbaReferences + //GistId:d9bac4ed890f81ea3de392ecfeedbc55 + Document doc = new Document(getMyDir() + "VBA project.docm"); + + // Find and remove the reference with some LibId path. + final String BROKEN_PATH = "brokenPath.dll"; + VbaReferenceCollection references = doc.getVbaProject().getReferences(); + for (int i = references.getCount() - 1; i >= 0; i--) { + VbaReference reference = doc.getVbaProject().getReferences().get(i); + + String path = getLibIdPath(reference); + if (BROKEN_PATH.equals(path)) + references.removeAt(i); + } + + doc.save(getArtifactsDir() + "WorkingWithVba.RemoveVbaReferences.docm"); + //ExEnd:RemoveVbaReferences + } + + //ExStart:GetLibIdAndReferencePath + //GistId:d9bac4ed890f81ea3de392ecfeedbc55 + /// + /// Returns string representing LibId path of a specified reference. + /// + private String getLibIdPath(VbaReference reference) { + switch (reference.getType()) { + case VbaReferenceType.REGISTERED: + case VbaReferenceType.ORIGINAL: + case VbaReferenceType.CONTROL: + return getLibIdReferencePath(reference.getLibId()); + case VbaReferenceType.PROJECT: + return getLibIdProjectPath(reference.getLibId()); + default: + throw new IllegalArgumentException(); + } + } + + /// + /// Returns path from a specified identifier of an Automation type library. + /// + /// + /// Please see details for the syntax at [MS-OVBA], 2.1.1.8 LibidReference. + /// + private String getLibIdReferencePath(String libIdReference) { + if (libIdReference != null) { + String[] refParts = libIdReference.split("#"); + if (refParts.length > 3) + return refParts[3]; + } + + return ""; + } + + /// + /// Returns path from a specified identifier of an Automation type library. + /// + /// + /// Please see details for the syntax at [MS-OVBA], 2.1.1.12 ProjectReference. + /// + private String getLibIdProjectPath(String libIdProject) { + return (libIdProject != null) ? libIdProject.substring(3) : ""; + } + //ExEnd:GetLibIdAndReferencePath +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/AddContentUsingDocumentBuilder.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/AddContentUsingDocumentBuilder.java new file mode 100644 index 00000000..dc24ebdc --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/AddContentUsingDocumentBuilder.java @@ -0,0 +1,565 @@ +package DocsExamples.Programming_with_documents.Working_with_document; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Font; +import com.aspose.words.Shape; +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.awt.*; +import java.text.MessageFormat; +import java.util.regex.Pattern; + +@Test +public class AddContentUsingDocumentBuilder extends DocsExamplesBase { + @Test + public void createNewDocument() throws Exception { + //ExStart:CreateNewDocument + //GistId:ae20848f6cefd3f85ab9bcbbdda340c7 + Document doc = new Document(); + + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello World!"); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.CreateNewDocument.docx"); + //ExEnd:CreateNewDocument + } + + @Test + public void insertBookmark() throws Exception { + //ExStart:InsertBookmark + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startBookmark("FineBookmark"); + builder.writeln("This is just a fine bookmark."); + builder.endBookmark("FineBookmark"); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertBookmark.docx"); + //ExEnd:InsertBookmark + } + + @Test + public void buildTable() throws Exception { + //ExStart:BuildTable + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + + builder.getCellFormat().setVerticalAlignment(CellVerticalAlignment.CENTER); + builder.write("This is row 1 cell 1"); + + builder.insertCell(); + builder.write("This is row 1 cell 2"); + + builder.endRow(); + + builder.insertCell(); + + builder.getRowFormat().setHeight(100.0); + builder.getRowFormat().setHeightRule(HeightRule.EXACTLY); + builder.getCellFormat().setOrientation(TextOrientation.UPWARD); + builder.writeln("This is row 2 cell 1"); + + builder.insertCell(); + builder.getCellFormat().setOrientation(TextOrientation.DOWNWARD); + builder.writeln("This is row 2 cell 2"); + + builder.endRow(); + builder.endTable(); + + table.autoFit(AutoFitBehavior.FIXED_COLUMN_WIDTHS); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.BuildTable.docx"); + //ExEnd:BuildTable + } + + @Test + public void insertHorizontalRule() throws Exception { + //ExStart:InsertHorizontalRule + //GistId:ae9835338c044aaa3ac54592b7062db8 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Insert a horizontal rule shape into the document."); + builder.insertHorizontalRule(); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertHorizontalRule.docx"); + //ExEnd:InsertHorizontalRule + } + + @Test + public void horizontalRuleFormat() throws Exception { + //ExStart:HorizontalRuleFormat + //GistId:ae9835338c044aaa3ac54592b7062db8 + DocumentBuilder builder = new DocumentBuilder(); + + Shape shape = builder.insertHorizontalRule(); + + HorizontalRuleFormat horizontalRuleFormat = shape.getHorizontalRuleFormat(); + horizontalRuleFormat.setAlignment(HorizontalRuleAlignment.CENTER); + horizontalRuleFormat.setWidthPercent(70.0); + horizontalRuleFormat.setHeight(3.0); + horizontalRuleFormat.setColor(Color.BLUE); + horizontalRuleFormat.setNoShade(true); + + builder.getDocument().save(getArtifactsDir() + "AddContentUsingDocumentBuilder.HorizontalRuleFormat.docx"); + //ExEnd:HorizontalRuleFormat + } + + @Test + public void insertBreak() throws Exception { + //ExStart:InsertBreak + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("This is page 1."); + builder.insertBreak(BreakType.PAGE_BREAK); + + builder.writeln("This is page 2."); + builder.insertBreak(BreakType.PAGE_BREAK); + + builder.writeln("This is page 3."); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertBreak.docx"); + //ExEnd:InsertBreak + } + + @Test + public void insertTextInputFormField() throws Exception { + //ExStart:InsertTextInputFormField + //GistId:1d9d7d13906d89380213310f7a0dffdc + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", "Hello", 0); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertTextInputFormField.docx"); + //ExEnd:InsertTextInputFormField + } + + @Test + public void insertCheckBoxFormField() throws Exception { + //ExStart:InsertCheckBoxFormField + //GistId:1d9d7d13906d89380213310f7a0dffdc + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertCheckBox("CheckBox", true, true, 0); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertCheckBoxFormField.docx"); + //ExEnd:InsertCheckBoxFormField + } + + @Test + public void insertComboBoxFormField() throws Exception { + //ExStart:InsertComboBoxFormField + //GistId:1d9d7d13906d89380213310f7a0dffdc + String[] items = {"One", "Two", "Three"}; + + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertComboBox("DropDown", items, 0); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertComboBoxFormField.docx"); + //ExEnd:InsertComboBoxFormField + } + + @Test + public void insertHtml() throws Exception { + //ExStart:InsertHtml + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertHtml( + "

          Paragraph right

          " + + "Implicit paragraph left" + + "
          Div center
          " + + "

          Heading 1 left.

          "); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertHtml.docx"); + //ExEnd:InsertHtml + } + + @Test + public void insertHyperlink() throws Exception { + //ExStart:InsertHyperlink + //GistId:d94085c26baf5235d4e7ab5483980108 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Please make sure to visit "); + + builder.getFont().setStyle(doc.getStyles().getByStyleIdentifier(StyleIdentifier.HYPERLINK)); + builder.insertHyperlink("Aspose Website", "http://www.aspose.com", false); + builder.getFont().clearFormatting(); + + builder.write(" for more information."); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertHyperlink.docx"); + //ExEnd:InsertHyperlink + } + + @Test + public void insertTableOfContents() throws Exception { + //ExStart:InsertTableOfContents + //GistId:5d939fbdab0ac77c575636f79013ffb1 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertTableOfContents("\\o \"1-3\" \\h \\z \\u"); + + // Start the actual document content on the second page. + builder.insertBreak(BreakType.PAGE_BREAK); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + + builder.writeln("Heading 1"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); + + builder.writeln("Heading 1.1"); + builder.writeln("Heading 1.2"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + + builder.writeln("Heading 2"); + builder.writeln("Heading 3"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); + + builder.writeln("Heading 3.1"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_3); + + builder.writeln("Heading 3.1.1"); + builder.writeln("Heading 3.1.2"); + builder.writeln("Heading 3.1.3"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); + + builder.writeln("Heading 3.2"); + builder.writeln("Heading 3.3"); + + //ExStart:UpdateFields + //GistId:5d939fbdab0ac77c575636f79013ffb1 + // The newly inserted table of contents will be initially empty. + // It needs to be populated by updating the fields in the document. + doc.updateFields(); + //ExEnd:UpdateFields + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertTableOfContents.docx"); + //ExEnd:InsertTableOfContents + } + + @Test + public void insertInlineImage() throws Exception { + //ExStart:InsertInlineImage + //GistId:5b273ed7ba940f81b6a42a3a78609316 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertImage(getImagesDir() + "Transparent background logo.png"); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertInlineImage.docx"); + //ExEnd:InsertInlineImage + } + + @Test + public void insertFloatingImage() throws Exception { + //ExStart:InsertFloatingImage + //GistId:5b273ed7ba940f81b6a42a3a78609316 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertImage(getImagesDir() + "Transparent background logo.png", + RelativeHorizontalPosition.MARGIN, + 100.0, + RelativeVerticalPosition.MARGIN, + 100.0, + 200.0, + 100.0, + WrapType.SQUARE); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertFloatingImage.docx"); + //ExEnd:InsertFloatingImage + } + + @Test + public void insertParagraph() throws Exception { + //ExStart:InsertParagraph + //GistId:f241f6361cb8566b906f0daa559ea33d + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Font font = builder.getFont(); + font.setSize(16.0); + font.setBold(true); + font.setColor(Color.BLUE); + font.setName("Arial"); + font.setUnderline(Underline.DASH); + + ParagraphFormat paragraphFormat = builder.getParagraphFormat(); + paragraphFormat.setFirstLineIndent(8.0); + paragraphFormat.setAlignment(ParagraphAlignment.JUSTIFY); + paragraphFormat.setKeepTogether(true); + + builder.writeln("A whole paragraph."); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertParagraph.docx"); + //ExEnd:InsertParagraph + } + + @Test + public void insertTcField() throws Exception { + //ExStart:InsertTcField + //GistId:5d939fbdab0ac77c575636f79013ffb1 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField("TC \"Entry Text\" \\f t"); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertTcField.docx"); + //ExEnd:InsertTcField + } + + @Test + public void insertTcFieldsAtText() throws Exception { + //ExStart:InsertTcFieldsAtText + //GistId:5d939fbdab0ac77c575636f79013ffb1 + Document doc = new Document(); + + FindReplaceOptions options = new FindReplaceOptions(); + options.getApplyFont().setHighlightColor(Color.ORANGE); + options.setReplacingCallback(new InsertTCFieldHandler("Chapter 1", "\\l 1")); + + doc.getRange().replace(Pattern.compile("The Beginning"), "", options); + //ExEnd:InsertTcFieldsAtText + } + + //ExStart:InsertTCFieldHandler + public final static class InsertTCFieldHandler implements IReplacingCallback { + // Store the text and switches to be used for the TC fields. + private String mFieldText; + private String mFieldSwitches; + + /// + /// The display text and switches to use for each TC field. Display name can be an empty string or null. + /// + public InsertTCFieldHandler(String text, String switches) { + mFieldText = text; + mFieldSwitches = switches; + } + + public int replacing(ReplacingArgs args) throws Exception { + DocumentBuilder builder = new DocumentBuilder((Document) args.getMatchNode().getDocument()); + builder.moveTo(args.getMatchNode()); + + // If the user-specified text to be used in the field as display text, then use that, + // otherwise use the match string as the display text. + String insertText = !mFieldText.isEmpty() ? mFieldText : args.getMatch().group(); + + builder.insertField(MessageFormat.format("TC \"{0}\" {1}", insertText, mFieldSwitches)); + + return ReplaceAction.SKIP; + } + } + //ExEnd:InsertTCFieldHandler + + @Test + public void cursorPosition() throws Exception { + //ExStart:CursorPosition + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Node curNode = builder.getCurrentNode(); + Paragraph curParagraph = builder.getCurrentParagraph(); + //ExEnd:CursorPosition + + System.out.println("\nCursor move to paragraph: " + curParagraph.getText()); + } + + @Test + public void moveToNode() throws Exception { + //ExStart:MoveToNode + //GistId:402a4aea5f494d032783f0e9365d5990 + //ExStart:MoveToBookmark + //GistId:402a4aea5f494d032783f0e9365d5990 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Start a bookmark and add content to it using a DocumentBuilder. + builder.startBookmark("MyBookmark"); + builder.writeln("Bookmark contents."); + builder.endBookmark("MyBookmark"); + + // The node that the DocumentBuilder is currently at is past the boundaries of the bookmark. + Assert.assertEquals(doc.getRange().getBookmarks().get(0).getBookmarkEnd(), builder.getCurrentParagraph().getFirstChild()); + + // If we wish to revise the content of our bookmark with the DocumentBuilder, we can move back to it like this. + builder.moveToBookmark("MyBookmark"); + + // Now we're located between the bookmark's BookmarkStart and BookmarkEnd nodes, so any text the builder adds will be within it. + Assert.assertEquals(doc.getRange().getBookmarks().get(0).getBookmarkStart(), builder.getCurrentParagraph().getFirstChild()); + + // We can move the builder to an individual node, + // which in this case will be the first node of the first paragraph, like this. + builder.moveTo(doc.getFirstSection().getBody().getFirstParagraph().getChildNodes(NodeType.ANY, false).get(0)); + //ExEnd:MoveToBookmark + + Assert.assertEquals(NodeType.BOOKMARK_START, builder.getCurrentNode().getNodeType()); + Assert.assertTrue(builder.isAtStartOfParagraph()); + + // A shorter way of moving the very start/end of a document is with these methods. + builder.moveToDocumentEnd(); + Assert.assertTrue(builder.isAtEndOfParagraph()); + builder.moveToDocumentStart(); + Assert.assertTrue(builder.isAtStartOfParagraph()); + //ExEnd:MoveToNode + } + + @Test + public void moveToDocumentStartEnd() throws Exception { + //ExStart:MoveToDocumentStartEnd + //GistId:402a4aea5f494d032783f0e9365d5990 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Move the cursor position to the beginning of your document. + builder.moveToDocumentStart(); + System.out.println("\nThis is the beginning of the document."); + + // Move the cursor position to the end of your document. + builder.moveToDocumentEnd(); + System.out.println("\nThis is the end of the document."); + //ExEnd:MoveToDocumentStartEnd + } + + @Test + public void moveToSection() throws Exception { + //ExStart:MoveToSection + //GistId:402a4aea5f494d032783f0e9365d5990 + Document doc = new Document(); + doc.appendChild(new Section(doc)); + + // Move a DocumentBuilder to the second section and add text. + DocumentBuilder builder = new DocumentBuilder(doc); + builder.moveToSection(1); + builder.writeln("Text added to the 2nd section."); + + // Create document with paragraphs. + doc = new Document(getMyDir() + "Paragraphs.docx"); + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + Assert.assertEquals(22, paragraphs.getCount()); + + // When we create a DocumentBuilder for a document, its cursor is at the very beginning of the document by default, + // and any content added by the DocumentBuilder will just be prepended to the document. + builder = new DocumentBuilder(doc); + Assert.assertEquals(0, paragraphs.indexOf(builder.getCurrentParagraph())); + + // You can move the cursor to any position in a paragraph. + builder.moveToParagraph(2, 10); + Assert.assertEquals(2, paragraphs.indexOf(builder.getCurrentParagraph())); + builder.writeln("This is a new third paragraph. "); + Assert.assertEquals(3, paragraphs.indexOf(builder.getCurrentParagraph())); + //ExEnd:MoveToSection + } + + @Test + public void moveToHeadersFooters() throws Exception { + //ExStart:MoveToHeadersFooters + //GistId:402a4aea5f494d032783f0e9365d5990 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Specify that we want headers and footers different for first, even and odd pages. + builder.getPageSetup().setDifferentFirstPageHeaderFooter(true); + builder.getPageSetup().setOddAndEvenPagesHeaderFooter(true); + + // Create the headers. + builder.moveToHeaderFooter(HeaderFooterType.HEADER_FIRST); + builder.write("Header for the first page"); + builder.moveToHeaderFooter(HeaderFooterType.HEADER_EVEN); + builder.write("Header for even pages"); + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.write("Header for all other pages"); + + // Create two pages in the document. + builder.moveToSection(0); + builder.writeln("Page1"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page2"); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.MoveToHeadersFooters.docx"); + //ExEnd:MoveToHeadersFooters + } + + @Test + public void moveToParagraph() throws Exception { + //ExStart:MoveToParagraph + Document doc = new Document(getMyDir() + "Paragraphs.docx"); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.moveToParagraph(2, 0); + builder.writeln("This is the 3rd paragraph."); + //ExEnd:MoveToParagraph + } + + @Test + public void moveToTableCell() throws Exception { + //ExStart:MoveToTableCell + //GistId:402a4aea5f494d032783f0e9365d5990 + Document doc = new Document(getMyDir() + "Tables.docx"); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Move the builder to row 3, cell 4 of the first table. + builder.moveToCell(0, 2, 3, 0); + builder.write("\nCell contents added by DocumentBuilder"); + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + Assert.assertEquals(table.getRows().get(2).getCells().get(3), builder.getCurrentNode().getParentNode().getParentNode()); + Assert.assertEquals("Cell contents added by DocumentBuilderCell 3 contents", table.getRows().get(2).getCells().get(3).getText().trim()); + //ExEnd:MoveToTableCell + } + + @Test + public void moveToBookmarkEnd() throws Exception { + //ExStart:MoveToBookmarkEnd + //GistId:f241f6361cb8566b906f0daa559ea33d + Document doc = new Document(getMyDir() + "Bookmarks.docx"); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.moveToBookmark("MyBookmark1", false, true); + builder.writeln("This is a bookmark."); + //ExEnd:MoveToBookmarkEnd + } + + @Test + public void moveToMergeField() throws Exception { + //ExStart:MoveToMergeField + //GistId:402a4aea5f494d032783f0e9365d5990 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a field using the DocumentBuilder and add a run of text after it. + Field field = builder.insertField("MERGEFIELD field"); + builder.write(" Text after the field."); + + // The builder's cursor is currently at end of the document. + Assert.assertNull(builder.getCurrentNode()); + // We can move the builder to a field like this, placing the cursor at immediately after the field. + builder.moveToField(field, true); + + // Note that the cursor is at a place past the FieldEnd node of the field, meaning that we are not actually inside the field. + // If we wish to move the DocumentBuilder to inside a field, + // we will need to move it to a field's FieldStart or FieldSeparator node using the DocumentBuilder.MoveTo() method. + Assert.assertEquals(field.getEnd(), builder.getCurrentNode().getPreviousSibling()); + builder.write(" Text immediately after the field."); + //ExEnd:MoveToMergeField + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/CloneAndCombineDocuments.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/CloneAndCombineDocuments.java new file mode 100644 index 00000000..9066abca --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/CloneAndCombineDocuments.java @@ -0,0 +1,251 @@ +package DocsExamples.Programming_with_documents.Working_with_document; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.io.ByteArrayInputStream; +import java.util.regex.Pattern; + +@Test +public class CloneAndCombineDocuments extends DocsExamplesBase { + @Test + public void cloneDocument() throws Exception { + //ExStart:CloneDocument + //GistId:faf236ea6d4dc5da50bae0db08b5e0a5 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("This is the original document before applying the clone method"); + + // Clone the document. + Document clone = doc.deepClone(); + + // Edit the cloned document. + builder = new DocumentBuilder(clone); + builder.write("Section 1"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.write("Section 2"); + + // This shows what is in the document originally. The document has two sections. + Assert.assertEquals("Section 1\fSection 2This is the original document before applying the clone method", clone.getText().trim()); + + // Duplicate the last section and append the copy to the end of the document. + int lastSectionIdx = clone.getSections().getCount() - 1; + Section newSection = clone.getSections().get(lastSectionIdx).deepClone(); + clone.getSections().add(newSection); + + // Check what the document contains after we changed it. + Assert.assertEquals("Section 1\fSection 2This is the original document before applying the clone method" + + "\r\fSection 2This is the original document before applying the clone method", clone.getText().trim()); + clone.save(getArtifactsDir() + "CloneAndCombineDocuments.CloningDocument.docx"); + //ExEnd:CloneDocument + } + + @Test + public void insertDocumentAtReplace() throws Exception { + //ExStart:InsertDocumentAtReplace + //GistId:6e5c8fd2462c6d7ba26da4d9f66ff77b + Document mainDoc = new Document(getMyDir() + "Document insertion 1.docx"); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setDirection(FindReplaceDirection.BACKWARD); + options.setReplacingCallback(new InsertDocumentAtReplaceHandler()); + + mainDoc.getRange().replace(Pattern.compile("\\[MY_DOCUMENT\\]"), "", options); + mainDoc.save(getArtifactsDir() + "CloneAndCombineDocuments.InsertDocumentAtReplace.docx"); + //ExEnd:InsertDocumentAtReplace + } + + @Test + public void insertDocumentAtBookmark() throws Exception { + //ExStart:InsertDocumentAtBookmark + //GistId:6e5c8fd2462c6d7ba26da4d9f66ff77b + Document mainDoc = new Document(getMyDir() + "Document insertion 1.docx"); + Document subDoc = new Document(getMyDir() + "Document insertion 2.docx"); + + Bookmark bookmark = mainDoc.getRange().getBookmarks().get("insertionPlace"); + insertDocument(bookmark.getBookmarkStart().getParentNode(), subDoc); + + mainDoc.save(getArtifactsDir() + "CloneAndCombineDocuments.InsertDocumentAtBookmark.docx"); + //ExEnd:InsertDocumentAtBookmark + } + + @Test + public void insertDocumentAtMailMerge() throws Exception { + //ExStart:InsertDocumentAtMailMerge + //GistId:6e5c8fd2462c6d7ba26da4d9f66ff77b + Document mainDoc = new Document(getMyDir() + "Document insertion 1.docx"); + + mainDoc.getMailMerge().setFieldMergingCallback(new InsertDocumentAtMailMergeHandler()); + // The main document has a merge field in it called "Document_1". + // The corresponding data for this field contains a fully qualified path to the document. + // That should be inserted to this field. + mainDoc.getMailMerge().execute(new String[]{"Document_1"}, new Object[]{getMyDir() + "Document insertion 2.docx"}); + + mainDoc.save(getArtifactsDir() + "CloneAndCombineDocuments.InsertDocumentAtMailMerge.doc"); + //ExEnd:InsertDocumentAtMailMerge + } + + //ExStart:InsertDocumentAsNodes + //GistId:6e5c8fd2462c6d7ba26da4d9f66ff77b + /// + /// Inserts content of the external document after the specified node. + /// Section breaks and section formatting of the inserted document are ignored. + /// + /// Node in the destination document after which the content + /// Should be inserted. This node should be a block level node (paragraph or table). + /// The document to insert. + private static void insertDocument(Node insertionDestination, Document docToInsert) { + if (insertionDestination.getNodeType() == NodeType.PARAGRAPH || insertionDestination.getNodeType() == NodeType.TABLE) { + CompositeNode destinationParent = insertionDestination.getParentNode(); + + NodeImporter importer = + new NodeImporter(docToInsert, insertionDestination.getDocument(), ImportFormatMode.KEEP_SOURCE_FORMATTING); + + // Loop through all block-level nodes in the section's body, + // then clone and insert every node that is not the last empty paragraph of a section. + for (Section srcSection : docToInsert.getSections()) + for (Node srcNode : srcSection.getBody()) { + if (srcNode.getNodeType() == NodeType.PARAGRAPH) { + Paragraph para = (Paragraph) srcNode; + if (para.isEndOfSection() && !para.hasChildNodes()) + continue; + } + + Node newNode = importer.importNode(srcNode, true); + + destinationParent.insertAfter(newNode, insertionDestination); + insertionDestination = newNode; + } + } else { + throw new IllegalArgumentException("The destination node should be either a paragraph or table."); + } + } + //ExEnd:InsertDocumentAsNodes + + //ExStart:InsertDocumentWithSectionFormatting + /// + /// Inserts content of the external document after the specified node. + /// + /// Node in the destination document after which the content + /// Should be inserted. This node should be a block level node (paragraph or table). + /// The document to insert. + private void insertDocumentWithSectionFormatting(Node insertAfterNode, Document srcDoc) { + if (insertAfterNode.getNodeType() != NodeType.PARAGRAPH && + insertAfterNode.getNodeType() != NodeType.TABLE) + throw new IllegalArgumentException("The destination node should be either a paragraph or table."); + + Document dstDoc = (Document) insertAfterNode.getDocument(); + // To retain section formatting, split the current section into two at the marker node and then import the content + // from srcDoc as whole sections. The section of the node to which the insert marker node belongs. + Section currentSection = (Section) insertAfterNode.getAncestor(NodeType.SECTION); + + // Don't clone the content inside the section, we just want the properties of the section retained. + Section cloneSection = (Section) currentSection.deepClone(false); + // However, make sure the clone section has a body but no empty first paragraph. + cloneSection.ensureMinimum(); + cloneSection.getBody().getFirstParagraph().remove(); + + insertAfterNode.getDocument().insertAfter(cloneSection, currentSection); + + // Append all nodes after the marker node to the new section. This will split the content at the section level at. + // The marker so the sections from the other document can be inserted directly. + Node currentNode = insertAfterNode.getNextSibling(); + while (currentNode != null) { + Node nextNode = currentNode.getNextSibling(); + cloneSection.getBody().appendChild(currentNode); + currentNode = nextNode; + } + + // This object will be translating styles and lists during the import. + NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.USE_DESTINATION_STYLES); + for (Section srcSection : srcDoc.getSections()) { + Node newNode = importer.importNode(srcSection, true); + + dstDoc.insertAfter(newNode, currentSection); + currentSection = (Section) newNode; + } + } + //ExEnd:InsertDocumentWithSectionFormatting + + //ExStart:InsertDocumentAtMailMergeHandler + //GistId:6e5c8fd2462c6d7ba26da4d9f66ff77b + private static class InsertDocumentAtMailMergeHandler implements IFieldMergingCallback { + // This handler makes special processing for the "Document_1" field. + // The field value contains the path to load the document. + // We load the document and insert it into the current merge field. + public void fieldMerging(FieldMergingArgs args) throws Exception { + if ("Document_1".equals(args.getDocumentFieldName())) { + // Use document builder to navigate to the merge field with the specified name. + DocumentBuilder builder = new DocumentBuilder(args.getDocument()); + builder.moveToMergeField(args.getDocumentFieldName()); + + // The name of the document to load and insert is stored in the field value. + Document subDoc = new Document((String) args.getFieldValue()); + + insertDocument(builder.getCurrentParagraph(), subDoc); + + // The paragraph that contained the merge field might be empty now, and you probably want to delete it. + if (!builder.getCurrentParagraph().hasChildNodes()) + builder.getCurrentParagraph().remove(); + + // Indicate to the mail merge engine that we have inserted what we wanted. + args.setText(null); + } + } + + public void imageFieldMerging(ImageFieldMergingArgs args) { + // Do nothing. + } + } + //ExEnd:InsertDocumentAtMailMergeHandler + + //ExStart:InsertDocumentAtMailMergeBlobHandler + private static class InsertDocumentAtMailMergeBlobHandler implements IFieldMergingCallback { + /// + /// This handler makes special processing for the "Document_1" field. + /// The field value contains the path to load the document. + /// We load the document and insert it into the current merge field. + /// + public void fieldMerging(FieldMergingArgs e) throws Exception { + if ("Document_1".equals(e.getDocumentFieldName())) { + DocumentBuilder builder = new DocumentBuilder(e.getDocument()); + builder.moveToMergeField(e.getDocumentFieldName()); + + ByteArrayInputStream stream = new ByteArrayInputStream((byte[]) e.getFieldValue()); + Document subDoc = new Document(stream); + + insertDocument(builder.getCurrentParagraph(), subDoc); + + // The paragraph that contained the merge field might be empty now, and you probably want to delete it. + if (!builder.getCurrentParagraph().hasChildNodes()) + builder.getCurrentParagraph().remove(); + + e.setText(null); + } + } + + public void imageFieldMerging(ImageFieldMergingArgs args) { + // Do nothing. + } + } + //ExEnd:InsertDocumentAtMailMergeBlobHandler + + //ExStart:InsertDocumentAtReplaceHandler + //GistId:6e5c8fd2462c6d7ba26da4d9f66ff77b + private static class InsertDocumentAtReplaceHandler implements IReplacingCallback { + public int replacing(ReplacingArgs args) throws Exception { + Document subDoc = new Document(getMyDir() + "Document insertion 2.docx"); + + // Insert a document after the paragraph, containing the match text. + Paragraph para = (Paragraph) args.getMatchNode().getParentNode(); + insertDocument(para, subDoc); + + // Remove the paragraph with the match text. + para.remove(); + return ReplaceAction.SKIP; + } + } + //ExEnd:InsertDocumentAtReplaceHandler +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/CompareDocuments.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/CompareDocuments.java new file mode 100644 index 00000000..149cfb70 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/CompareDocuments.java @@ -0,0 +1,78 @@ +package DocsExamples.Programming_with_documents.Working_with_document; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.util.Date; + +@Test +public class CompareDocuments extends DocsExamplesBase { + @Test + public void compareForEqual() throws Exception { + //ExStart:CompareForEqual + //GistId:bb20fc6b8fbf12d0a3175a5fe1cb3d29 + Document docA = new Document(getMyDir() + "Document.docx"); + Document docB = docA.deepClone(); + + // DocA now contains changes as revisions. + docA.compare(docB, "user", new Date()); + + System.out.println(docA.getRevisions().getCount() == 0 ? "Documents are equal" : "Documents are not equal"); + //ExEnd:CompareForEqual + } + + @Test + public void compareOptions() throws Exception { + //ExStart:CompareOptions + //GistId:bb20fc6b8fbf12d0a3175a5fe1cb3d29 + Document docA = new Document(getMyDir() + "Document.docx"); + Document docB = docA.deepClone(); + + CompareOptions options = new CompareOptions(); + options.setIgnoreFormatting(true); + options.setIgnoreHeadersAndFooters(true); + options.setIgnoreCaseChanges(true); + options.setIgnoreTables(true); + options.setIgnoreFields(true); + options.setIgnoreComments(true); + options.setIgnoreTextboxes(true); + options.setIgnoreFootnotes(true); + + docA.compare(docB, "user", new Date(), options); + + System.out.println(docA.getRevisions().getCount() == 0 ? "Documents are equal" : "Documents are not equal"); + //ExEnd:CompareOptions + } + + @Test + public void comparisonTarget() throws Exception { + //ExStart:ComparisonTarget + Document docA = new Document(getMyDir() + "Document.docx"); + Document docB = docA.deepClone(); + + // Relates to Microsoft Word "Show changes in" option in "Compare Documents" dialog box. + CompareOptions options = new CompareOptions(); + options.setIgnoreFormatting(true); + options.setTarget(ComparisonTargetType.NEW); + + docA.compare(docB, "user", new Date(), options); + //ExEnd:ComparisonTarget + } + + @Test + public void comparisonGranularity() throws Exception { + //ExStart:ComparisonGranularity + DocumentBuilder builderA = new DocumentBuilder(new Document()); + DocumentBuilder builderB = new DocumentBuilder(new Document()); + + builderA.writeln("This is A simple word"); + builderB.writeln("This is B simple words"); + + CompareOptions compareOptions = new CompareOptions(); + compareOptions.setGranularity(Granularity.CHAR_LEVEL); + + builderA.getDocument().compare(builderB.getDocument(), "author", new Date(), compareOptions); + //ExEnd:ComparisonGranularity + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/DocumentFormatting.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/DocumentFormatting.java new file mode 100644 index 00000000..e4b24544 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/DocumentFormatting.java @@ -0,0 +1,255 @@ +package DocsExamples.Programming_with_documents.Working_with_document; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.awt.*; + +@Test +public class DocumentFormatting extends DocsExamplesBase { + @Test + public void spaceBetweenAsianAndLatinText() throws Exception { + //ExStart:SpaceBetweenAsianAndLatinText + //GistId:93caa5d439a29d1632a48bdcf8a5efe9 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + ParagraphFormat paragraphFormat = builder.getParagraphFormat(); + paragraphFormat.setAddSpaceBetweenFarEastAndAlpha(true); + paragraphFormat.setAddSpaceBetweenFarEastAndDigit(true); + + builder.writeln("Automatically adjust space between Asian and Latin text"); + builder.writeln("Automatically adjust space between Asian text and numbers"); + + doc.save(getArtifactsDir() + "DocumentFormatting.SpaceBetweenAsianAndLatinText.docx"); + //ExEnd:SpaceBetweenAsianAndLatinText + } + + @Test + public void asianTypographyLineBreakGroup() throws Exception { + //ExStart:AsianTypographyLineBreakGroup + //GistId:93caa5d439a29d1632a48bdcf8a5efe9 + Document doc = new Document(getMyDir() + "Asian typography.docx"); + + ParagraphFormat format = doc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat(); + format.setFarEastLineBreakControl(false); + format.setWordWrap(true); + format.setHangingPunctuation(false); + + doc.save(getArtifactsDir() + "DocumentFormatting.AsianTypographyLineBreakGroup.docx"); + //ExEnd:AsianTypographyLineBreakGroup + } + + @Test + public void paragraphFormatting() throws Exception { + //ExStart:ParagraphFormatting + //GistId:75080b633887e95c397bce7d14d7cbf1 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + ParagraphFormat paragraphFormat = builder.getParagraphFormat(); + paragraphFormat.setAlignment(ParagraphAlignment.CENTER); + paragraphFormat.setLeftIndent(50.0); + paragraphFormat.setRightIndent(50.0); + paragraphFormat.setSpaceAfter(25.0); + + builder.writeln( + "I'm a very nice formatted paragraph. I'm intended to demonstrate how the left and right indents affect word wrapping."); + builder.writeln( + "I'm another nice formatted paragraph. I'm intended to demonstrate how the space after paragraph looks like."); + + doc.save(getArtifactsDir() + "DocumentFormatting.ParagraphFormatting.docx"); + //ExEnd:ParagraphFormatting + } + + @Test + public void multilevelListFormatting() throws Exception { + //ExStart:MultilevelListFormatting + //GistId:bcc8db50f6937463ef0f1acd71da30a8 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getListFormat().applyNumberDefault(); + builder.writeln("Item 1"); + builder.writeln("Item 2"); + + builder.getListFormat().listIndent(); + builder.writeln("Item 2.1"); + builder.writeln("Item 2.2"); + + builder.getListFormat().listIndent(); + builder.writeln("Item 2.2.1"); + builder.writeln("Item 2.2.2"); + + builder.getListFormat().listOutdent(); + builder.writeln("Item 2.3"); + + builder.getListFormat().listOutdent(); + builder.writeln("Item 3"); + + builder.getListFormat().removeNumbers(); + + doc.save(getArtifactsDir() + "DocumentFormatting.MultilevelListFormatting.docx"); + //ExEnd:MultilevelListFormatting + } + + @Test + public void applyParagraphStyle() throws Exception { + //ExStart:ApplyParagraphStyle + //GistId:75080b633887e95c397bce7d14d7cbf1 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.TITLE); + builder.write("Hello"); + + doc.save(getArtifactsDir() + "DocumentFormatting.ApplyParagraphStyle.docx"); + //ExEnd:ApplyParagraphStyle + } + + @Test + public void applyBordersAndShadingToParagraph() throws Exception { + //ExStart:ApplyBordersAndShadingToParagraph + //GistId:75080b633887e95c397bce7d14d7cbf1 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + BorderCollection borders = builder.getParagraphFormat().getBorders(); + borders.setDistanceFromText(20.0); + borders.getByBorderType(BorderType.LEFT).setLineStyle(LineStyle.DOUBLE); + borders.getByBorderType(BorderType.RIGHT).setLineStyle(LineStyle.DOUBLE); + borders.getByBorderType(BorderType.TOP).setLineStyle(LineStyle.DOUBLE); + borders.getByBorderType(BorderType.BOTTOM).setLineStyle(LineStyle.DOUBLE); + + Shading shading = builder.getParagraphFormat().getShading(); + shading.setTexture(TextureIndex.TEXTURE_DIAGONAL_CROSS); + shading.setBackgroundPatternColor(Color.lightGray); + shading.setForegroundPatternColor(Color.orange); + + builder.write("I'm a formatted paragraph with double border and nice shading."); + + doc.save(getArtifactsDir() + "DocumentFormatting.ApplyBordersAndShadingToParagraph.doc"); + //ExEnd:ApplyBordersAndShadingToParagraph + } + + @Test + public void changeAsianParagraphSpacingAndIndents() throws Exception { + //ExStart:ChangeAsianParagraphSpacingAndIndents + Document doc = new Document(getMyDir() + "Asian typography.docx"); + + ParagraphFormat format = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat(); + format.setCharacterUnitLeftIndent(10.0); // ParagraphFormat.LeftIndent will be updated + format.setCharacterUnitRightIndent(10.0); // ParagraphFormat.RightIndent will be updated + format.setCharacterUnitFirstLineIndent(20.0); // ParagraphFormat.FirstLineIndent will be updated + format.setLineUnitBefore(5.0); // ParagraphFormat.SpaceBefore will be updated + format.setLineUnitAfter(10.0); // ParagraphFormat.SpaceAfter will be updated + + doc.save(getArtifactsDir() + "DocumentFormatting.ChangeAsianParagraphSpacingAndIndents.doc"); + //ExEnd:ChangeAsianParagraphSpacingAndIndents + } + + @Test + public void snapToGrid() throws Exception { + //ExStart:SetSnapToGrid + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Optimize the layout when typing in Asian characters. + Paragraph par = doc.getFirstSection().getBody().getFirstParagraph(); + par.getParagraphFormat().setSnapToGrid(true); + + builder.writeln("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod " + + "tempor incididunt ut labore et dolore magna aliqua."); + + par.getRuns().get(0).getFont().setSnapToGrid(true); + + doc.save(getArtifactsDir() + "Paragraph.SnapToGrid.docx"); + //ExEnd:SetSnapToGrid + } + + @Test + public void getParagraphStyleSeparator() throws Exception { + //ExStart:GetParagraphStyleSeparator + //GistId:75080b633887e95c397bce7d14d7cbf1 + Document doc = new Document(getMyDir() + "Document.docx"); + + for (Paragraph paragraph : (Iterable) doc.getChildNodes(NodeType.PARAGRAPH, true)) { + if (paragraph.getBreakIsStyleSeparator()) { + System.out.println("Separator Found!"); + } + } + //ExEnd:GetParagraphStyleSeparator + } + + @Test + //ExStart:GetParagraphLines + //GistId:75080b633887e95c397bce7d14d7cbf1 + public void getParagraphLines() throws Exception { + Document doc = new Document(getMyDir() + "Properties.docx"); + + LayoutCollector collector = new LayoutCollector(doc); + LayoutEnumerator enumerator = new LayoutEnumerator(doc); + + for (Paragraph paragraph : (Iterable) doc.getChildNodes(NodeType.PARAGRAPH, true)) { + processParagraph(paragraph, collector, enumerator); + } + } + + private static void processParagraph(Paragraph paragraph, LayoutCollector collector, LayoutEnumerator enumerator) throws Exception { + Object paragraphBreak = collector.getEntity(paragraph); + if (paragraphBreak == null) + return; + + Object stopEntity = getStopEntity(paragraph, collector, enumerator); + + enumerator.setCurrent(paragraphBreak); + enumerator.moveParent(); + + int lineCount = countLines(enumerator, stopEntity); + + String paragraphText = getTruncatedText(paragraph.getText()); + System.out.println("Paragraph '" + paragraphText + "' has " + lineCount + " line(-s)."); + } + + private static Object getStopEntity(Paragraph paragraph, LayoutCollector collector, LayoutEnumerator enumerator) throws Exception { + Node previousNode = paragraph.getPreviousSibling(); + if (previousNode == null) + return null; + + if (previousNode instanceof Paragraph) { + Paragraph prevParagraph = (Paragraph) previousNode; + enumerator.setCurrent(collector.getEntity(prevParagraph)); // Para break. + enumerator.moveParent(); // Last line. + return enumerator.getCurrent(); + } else if (previousNode instanceof Table) { + Table table = (Table) previousNode; + enumerator.setCurrent(collector.getEntity(table.getLastRow().getLastCell().getLastParagraph())); // Cell break. + enumerator.moveParent(); // Cell. + enumerator.moveParent(); // Row. + return enumerator.getCurrent(); + } else { + throw new IllegalStateException("Unsupported node type encountered."); + } + } + + /** + * We move from line to line in a paragraph. + * When paragraph spans multiple pages the we will follow across them. + */ + private static int countLines(LayoutEnumerator enumerator, Object stopEntity) throws Exception { + int count = 1; + while (enumerator.getCurrent() != stopEntity) { + if (!enumerator.movePreviousLogical()) + break; + count++; + } + return count; + } + + private static String getTruncatedText(String text) { + int MaxChars = 16; + return text.length() > MaxChars ? text.substring(0, MaxChars) + "..." : text; + } + //ExEnd:GetParagraphLines +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/JoinAndAppendDocuments.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/JoinAndAppendDocuments.java new file mode 100644 index 00000000..6d744064 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/JoinAndAppendDocuments.java @@ -0,0 +1,612 @@ +package DocsExamples.Programming_with_documents.Working_with_document; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.List; +import com.aspose.words.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.awt.*; +import java.text.MessageFormat; +import java.util.HashMap; + +@Test +public class JoinAndAppendDocuments extends DocsExamplesBase { + @Test + public void simpleAppendDocument() throws Exception { + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // Append the source document to the destination document using no extra options. + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.SimpleAppendDocument.docx"); + } + + @Test + public void appendDocument() throws Exception { + //ExStart:AppendDocumentManually + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // Loop through all sections in the source document. + // Section nodes are immediate children of the Document node so we can just enumerate the Document. + for (Section srcSection : srcDoc.getSections()) { + // Because we are copying a section from one document to another, + // it is required to import the Section node into the destination document. + // This adjusts any document-specific references to styles, lists, etc. + // + // Importing a node creates a copy of the original node, but the copy + // ss ready to be inserted into the destination document. + Node dstSection = dstDoc.importNode(srcSection, true, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + // Now the new section node can be appended to the destination document. + dstDoc.appendChild(dstSection); + } + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.AppendDocument.docx"); + //ExEnd:AppendDocumentManually + } + + @Test + public void appendDocumentToBlank() throws Exception { + //ExStart:AppendDocumentToBlank + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(); + + // The destination document is not empty, often causing a blank page to appear before the appended document. + // This is due to the base document having an empty section and the new document being started on the next page. + // Remove all content from the destination document before appending. + dstDoc.removeAllChildren(); + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.AppendDocumentToBlank.docx"); + //ExEnd:AppendDocumentToBlank + } + + @Test + public void appendWithImportFormatOptions() throws Exception { + //ExStart:AppendWithImportFormatOptions + Document srcDoc = new Document(getMyDir() + "Document source with list.docx"); + Document dstDoc = new Document(getMyDir() + "Document destination with list.docx"); + + // Specify that if numbering clashes in source and destination documents, + // then numbering from the source document will be used. + ImportFormatOptions options = new ImportFormatOptions(); + options.setKeepSourceNumbering(true); + + dstDoc.appendDocument(srcDoc, ImportFormatMode.USE_DESTINATION_STYLES, options); + //ExEnd:AppendWithImportFormatOptions + } + + @Test + public void convertNumPageFields() throws Exception { + //ExStart:ConvertNumPageFields + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // Restart the page numbering on the start of the source document. + srcDoc.getFirstSection().getPageSetup().setRestartPageNumbering(true); + srcDoc.getFirstSection().getPageSetup().setPageStartingNumber(1); + + // Append the source document to the end of the destination document. + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + // After joining the documents the NUMPAGE fields will now display the total number of pages which + // is undesired behavior. Call this method to fix them by replacing them with PAGEREF fields. + convertNumPageFieldsToPageRef(dstDoc); + + // This needs to be called in order to update the new fields with page numbers. + dstDoc.updatePageLayout(); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.ConvertNumPageFields.docx"); + //ExEnd:ConvertNumPageFields + } + + //ExStart:ConvertNumPageFieldsToPageRef + private void convertNumPageFieldsToPageRef(Document doc) throws Exception { + // This is the prefix for each bookmark, which signals where page numbering restarts. + // The underscore "_" at the start inserts this bookmark as hidden in MS Word. + String bookmarkPrefix = "_SubDocumentEnd"; + String numpagesFieldName = "NUMPAGES"; + String pagerefFieldName = "PAGEREF"; + + // Defines the number of page restarts encountered and, therefore, + // the number of "sub" documents found within this document. + int subDocumentCount = 0; + + DocumentBuilder builder = new DocumentBuilder(doc); + + for (Section section : doc.getSections()) { + // This section has its page numbering restarted to treat this as the start of a sub-document. + // Any PAGENUM fields in this inner document must be converted to special PAGEREF fields to correct numbering. + if (section.getPageSetup().getRestartPageNumbering()) { + // Don't do anything if this is the first section of the document. + // This part of the code will insert the bookmark marking the end of the previous sub-document so, + // therefore, it does not apply to the first section in the document. + if (!section.equals(doc.getFirstSection())) { + // Get the previous section and the last node within the body of that section. + Section prevSection = (Section) section.getPreviousSibling(); + Node lastNode = prevSection.getBody().getLastChild(); + + builder.moveTo(lastNode); + + // This bookmark represents the end of the sub-document. + builder.startBookmark(bookmarkPrefix + subDocumentCount); + builder.endBookmark(bookmarkPrefix + subDocumentCount); + + // Increase the sub-document count to insert the correct bookmarks. + subDocumentCount++; + } + } + + // The last section needs the ending bookmark to signal that it is the end of the current sub-document. + if (section.equals(doc.getLastSection())) { + // Insert the bookmark at the end of the body of the last section. + // Don't increase the count this time as we are just marking the end of the document. + Node lastNode = doc.getLastSection().getBody().getLastChild(); + + builder.moveTo(lastNode); + builder.startBookmark(bookmarkPrefix + subDocumentCount); + builder.endBookmark(bookmarkPrefix + subDocumentCount); + } + + // Iterate through each NUMPAGES field in the section and replace it with a PAGEREF field + // referring to the bookmark of the current sub-document. This bookmark is positioned at the end + // of the sub-document but does not exist yet. It is inserted when a section with restart page numbering + // or the last section is encountered. + Node[] nodes = section.getChildNodes(NodeType.FIELD_START, true).toArray(); + + for (Node fieldStartNode : nodes) { + FieldStart fieldStart = (FieldStart) fieldStartNode; + + if (fieldStart.getFieldType() == FieldType.FIELD_NUM_PAGES) { + String fieldCode = getFieldCode(fieldStart); + // Since the NUMPAGES field does not take any additional parameters, + // we can assume the field's remaining part. Code after the field name is the switches. + // We will use these to help recreate the NUMPAGES field as a PAGEREF field. + String fieldSwitches = fieldCode.replace(numpagesFieldName, "").trim(); + + // Inserting the new field directly at the FieldStart node of the original field will cause + // the new field not to pick up the original field's formatting. To counter this, + // insert the field just before the original field if a previous run cannot be found, + // we are forced to use the FieldStart node. + Node previousNode = (fieldStart.getPreviousSibling() != null ? fieldStart.getPreviousSibling() : fieldStart); + + // Insert a PAGEREF field at the same position as the field. + builder.moveTo(previousNode); + + Field newField = builder.insertField( + MessageFormat.format(" {0} {1}{2} {3} ", pagerefFieldName, bookmarkPrefix, subDocumentCount, fieldSwitches)); + + // The field will be inserted before the referenced node. Move the node before the field instead. + previousNode.getParentNode().insertBefore(previousNode, newField.getStart()); + + // Remove the original NUMPAGES field from the document. + removeField(fieldStart); + } + } + } + } + //ExEnd:ConvertNumPageFieldsToPageRef + + //ExStart:GetRemoveField + private void removeField(FieldStart fieldStart) { + boolean isRemoving = true; + + Node currentNode = fieldStart; + while (currentNode != null && isRemoving) { + if (currentNode.getNodeType() == NodeType.FIELD_END) + isRemoving = false; + + Node nextNode = currentNode.nextPreOrder(currentNode.getDocument()); + currentNode.remove(); + currentNode = nextNode; + } + } + + private String getFieldCode(FieldStart fieldStart) { + StringBuilder builder = new StringBuilder(); + + for (Node node = fieldStart; + node != null && node.getNodeType() != NodeType.FIELD_SEPARATOR && + node.getNodeType() != NodeType.FIELD_END; + node = node.nextPreOrder(node.getDocument())) { + // Use text only of Run nodes to avoid duplication. + if (node.getNodeType() == NodeType.RUN) + builder.append(node.getText()); + } + + return builder.toString(); + } + //ExEnd:GetRemoveField + + @Test + public void differentPageSetup() throws Exception { + //ExStart:DifferentPageSetup + //GistId:6e5c8fd2462c6d7ba26da4d9f66ff77b + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // Set the source document to continue straight after the end of the destination document. + srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.CONTINUOUS); + + // Restart the page numbering on the start of the source document. + srcDoc.getFirstSection().getPageSetup().setRestartPageNumbering(true); + srcDoc.getFirstSection().getPageSetup().setPageStartingNumber(1); + + // To ensure this does not happen when the source document has different page setup settings, make sure the + // settings are identical between the last section of the destination document. + // If there are further continuous sections that follow on in the source document, + // this will need to be repeated for those sections. + srcDoc.getFirstSection().getPageSetup().setPageWidth(dstDoc.getLastSection().getPageSetup().getPageWidth()); + srcDoc.getFirstSection().getPageSetup().setPageHeight(dstDoc.getLastSection().getPageSetup().getPageHeight()); + srcDoc.getFirstSection().getPageSetup().setOrientation(dstDoc.getLastSection().getPageSetup().getOrientation()); + + // Iterate through all sections in the source document. + for (Paragraph para : (Iterable) srcDoc.getChildNodes(NodeType.PARAGRAPH, true)) { + para.getParagraphFormat().setKeepWithNext(true); + } + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.DifferentPageSetup.docx"); + //ExEnd:DifferentPageSetup + } + + @Test + public void joinContinuous() throws Exception { + //ExStart:JoinContinuous + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // Make the document appear straight after the destination documents content. + srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.CONTINUOUS); + // Append the source document using the original styles found in the source document. + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.JoinContinuous.docx"); + //ExEnd:JoinContinuous + } + + @Test + public void joinNewPage() throws Exception { + //ExStart:JoinNewPage + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // Set the appended document to start on a new page. + srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.NEW_PAGE); + // Append the source document using the original styles found in the source document. + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.JoinNewPage.docx"); + //ExEnd:JoinNewPage + } + + @Test + public void keepSourceFormatting() throws Exception { + //ExStart:KeepSourceFormatting + //GistId:6e5c8fd2462c6d7ba26da4d9f66ff77b + Document dstDoc = new Document(); + dstDoc.getFirstSection().getBody().appendParagraph("Destination document text. "); + + Document srcDoc = new Document(); + srcDoc.getFirstSection().getBody().appendParagraph("Source document text. "); + // Append the source document to the destination document. + // Pass format mode to retain the original formatting of the source document when importing it. + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.KeepSourceFormatting.docx"); + //ExEnd:KeepSourceFormatting + } + + @Test + public void keepSourceTogether() throws Exception { + //ExStart:KeepSourceTogether + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Document destination with list.docx"); + + // Set the source document to appear straight after the destination document's content. + srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.CONTINUOUS); + + for (Paragraph para : (Iterable) srcDoc.getChildNodes(NodeType.PARAGRAPH, true)) { + para.getParagraphFormat().setKeepWithNext(true); + } + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.KeepSourceTogether.docx"); + //ExEnd:KeepSourceTogether + } + + @Test + public void listKeepSourceFormatting() throws Exception { + //ExStart:ListKeepSourceFormatting + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Document destination with list.docx"); + + // Append the content of the document so it flows continuously. + srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.CONTINUOUS); + + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.ListKeepSourceFormatting.docx"); + //ExEnd:ListKeepSourceFormatting + } + + @Test + public void listUseDestinationStyles() throws Exception { + //ExStart:ListUseDestinationStyles + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Document destination with list.docx"); + + // Set the source document to continue straight after the end of the destination document. + srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.CONTINUOUS); + + // Keep track of the lists that are created. + HashMap newLists = new HashMap<>(); + + for (Paragraph para : (Iterable) srcDoc.getChildNodes(NodeType.PARAGRAPH, true)) { + if (para.isListItem()) { + int listId = para.getListFormat().getList().getListId(); + + // Check if the destination document contains a list with this ID already. If it does, then this may + // cause the two lists to run together. Create a copy of the list in the source document instead. + if (dstDoc.getLists().getListByListId(listId) != null) { + List currentList; + // A newly copied list already exists for this ID, retrieve the stored list, + // and use it on the current paragraph. + if (newLists.containsKey(listId)) { + currentList = newLists.get(listId); + } else { + // Add a copy of this list to the document and store it for later reference. + currentList = srcDoc.getLists().addCopy(para.getListFormat().getList()); + newLists.put(listId, currentList); + } + + // Set the list of this paragraph to the copied list. + para.getListFormat().setList(currentList); + } + } + } + + // Append the source document to end of the destination document. + dstDoc.appendDocument(srcDoc, ImportFormatMode.USE_DESTINATION_STYLES); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.ListUseDestinationStyles.docx"); + //ExEnd:ListUseDestinationStyles + } + + @Test + public void restartPageNumbering() throws Exception { + //ExStart:RestartPageNumbering + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.NEW_PAGE); + srcDoc.getFirstSection().getPageSetup().setRestartPageNumbering(true); + + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.RestartPageNumbering.docx"); + //ExEnd:RestartPageNumbering + } + + @Test + public void updatePageLayout() throws Exception { + //ExStart:UpdatePageLayout + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // If the destination document is rendered to PDF, image etc. + // or UpdatePageLayout is called before the source document. Is appended, + // then any changes made after will not be reflected in the rendered output + dstDoc.updatePageLayout(); + + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + // For the changes to be updated to rendered output, UpdatePageLayout must be called again. + // If not called again, the appended document will not appear in the output of the next rendering. + dstDoc.updatePageLayout(); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.UpdatePageLayout.docx"); + //ExEnd:UpdatePageLayout + } + + @Test + public void useDestinationStyles() throws Exception { + //ExStart:UseDestinationStyles + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // Append the source document using the styles of the destination document. + dstDoc.appendDocument(srcDoc, ImportFormatMode.USE_DESTINATION_STYLES); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.UseDestinationStyles.docx"); + //ExEnd:UseDestinationStyles + } + + @Test + public void smartStyleBehavior() throws Exception { + //ExStart:SmartStyleBehavior + Document dstDoc = new Document(); + DocumentBuilder builder = new DocumentBuilder(dstDoc); + + Style myStyle = builder.getDocument().getStyles().add(StyleType.PARAGRAPH, "MyStyle"); + myStyle.getFont().setSize(14.0); + myStyle.getFont().setName("Courier New"); + myStyle.getFont().setColor(Color.BLUE); + + builder.getParagraphFormat().setStyleName(myStyle.getName()); + builder.writeln("Hello world!"); + + // Clone the document and edit the clone's "MyStyle" style, so it is a different color than that of the original. + // If we insert the clone into the original document, the two styles with the same name will cause a clash. + Document srcDoc = dstDoc.deepClone(); + srcDoc.getStyles().get("MyStyle").getFont().setColor(Color.RED); + + // When we enable SmartStyleBehavior and use the KeepSourceFormatting import format mode, + // Aspose.Words will resolve style clashes by converting source document styles. + // with the same names as destination styles into direct paragraph attributes. + ImportFormatOptions options = new ImportFormatOptions(); + options.setSmartStyleBehavior(true); + + builder.insertDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING, options); + + builder.getDocument().save(getArtifactsDir() + "JoinAndAppendDocuments.SmartStyleBehavior.docx"); + //ExEnd:SmartStyleBehavior + } + + @Test + public void insertDocument() throws Exception { + //ExStart:InsertDocumentWithBuilder + //GistId:6e5c8fd2462c6d7ba26da4d9f66ff77b + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + DocumentBuilder builder = new DocumentBuilder(dstDoc); + + builder.moveToDocumentEnd(); + builder.insertBreak(BreakType.PAGE_BREAK); + + builder.insertDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + builder.getDocument().save(getArtifactsDir() + "JoinAndAppendDocuments.insertDocument.docx"); + //ExEnd:InsertDocumentWithBuilder + } + + @Test + public void insertDocumentInline() throws Exception { + //ExStart:InsertDocumentInlineWithBuilder + //GistId:6e5c8fd2462c6d7ba26da4d9f66ff77b + DocumentBuilder srcDoc = new DocumentBuilder(); + srcDoc.write("[src content]"); + + // Create destination document. + DocumentBuilder dstDoc = new DocumentBuilder(); + dstDoc.write("Before "); + dstDoc.insertNode(new BookmarkStart(dstDoc.getDocument(), "src_place")); + dstDoc.insertNode(new BookmarkEnd(dstDoc.getDocument(), "src_place")); + dstDoc.write(" after"); + + Assert.assertEquals("Before after", dstDoc.getDocument().getText().trim()); + + // Insert source document into destination inline. + dstDoc.moveToBookmark("src_place"); + dstDoc.insertDocumentInline(srcDoc.getDocument(), ImportFormatMode.USE_DESTINATION_STYLES, new ImportFormatOptions()); + + Assert.assertEquals("Before [src content] after", dstDoc.getDocument().getText().trim()); + //ExEnd:InsertDocumentInlineWithBuilder + } + + @Test + public void keepSourceNumbering() throws Exception { + //ExStart:KeepSourceNumbering + Document srcDoc = new Document(getMyDir() + "List source.docx"); + Document dstDoc = new Document(getMyDir() + "List destination.docx"); + + ImportFormatOptions options = new ImportFormatOptions(); + // If there is a clash of list styles, apply the list format of the source document. + // Set the "KeepSourceNumbering" property to "false" to not import any list numbers into the destination document. + // Set the "KeepSourceNumbering" property to "true" import all clashing + // list style numbering with the same appearance that it had in the source document. + options.setKeepSourceNumbering(true); + + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING, options); + dstDoc.updateListLabels(); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.KeepSourceNumbering.docx"); + //ExEnd:KeepSourceNumbering + } + + @Test + public void ignoreTextBoxes() throws Exception { + //ExStart:IgnoreTextBoxes + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // Keep the source text boxes formatting when importing. + ImportFormatOptions importFormatOptions = new ImportFormatOptions(); + importFormatOptions.setIgnoreTextBoxes(false); + + NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING, + importFormatOptions); + + ParagraphCollection srcParas = srcDoc.getFirstSection().getBody().getParagraphs(); + for (Paragraph srcPara : srcParas) { + Node importedNode = importer.importNode(srcPara, true); + dstDoc.getFirstSection().getBody().appendChild(importedNode); + } + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.IgnoreTextBoxes.docx"); + //ExEnd:IgnoreTextBoxes + } + + @Test + public void ignoreHeaderFooter() throws Exception { + //ExStart:IgnoreHeaderFooter + Document srcDocument = new Document(getMyDir() + "Document source.docx"); + Document dstDocument = new Document(getMyDir() + "Northwind traders.docx"); + + ImportFormatOptions importFormatOptions = new ImportFormatOptions(); + importFormatOptions.setIgnoreHeaderFooter(false); + + dstDocument.appendDocument(srcDocument, ImportFormatMode.KEEP_SOURCE_FORMATTING, importFormatOptions); + + dstDocument.save(getArtifactsDir() + "JoinAndAppendDocuments.IgnoreHeaderFooter.docx"); + //ExEnd:IgnoreHeaderFooter + } + + @Test + public void linkHeadersFooters() throws Exception { + //ExStart:LinkHeadersFooters + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // Set the appended document to appear on a new page. + srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.NEW_PAGE); + // Link the headers and footers in the source document to the previous section. + // This will override any headers or footers already found in the source document. + srcDoc.getFirstSection().getHeadersFooters().linkToPrevious(true); + + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.LinkHeadersFooters.docx"); + //ExEnd:LinkHeadersFooters + } + + @Test + public void removeSourceHeadersFooters() throws Exception { + //ExStart:RemoveSourceHeadersFooters + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // Remove the headers and footers from each of the sections in the source document. + for (Section section : (Iterable
          ) srcDoc.getSections()) { + section.clearHeadersFooters(); + } + + // Even after the headers and footers are cleared from the source document, the "LinkToPrevious" setting + // for HeadersFooters can still be set. This will cause the headers and footers to continue from the destination + // document. This should set to false to avoid this behavior. + srcDoc.getFirstSection().getHeadersFooters().linkToPrevious(false); + + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.RemoveSourceHeadersFooters.docx"); + //ExEnd:RemoveSourceHeadersFooters + } + + @Test + public void unlinkHeadersFooters() throws Exception { + //ExStart:UnlinkHeadersFooters + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // Unlink the headers and footers in the source document to stop this + // from continuing the destination document's headers and footers. + srcDoc.getFirstSection().getHeadersFooters().linkToPrevious(false); + + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.UnlinkHeadersFooters.docx"); + //ExEnd:UnlinkHeadersFooters + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/WorkingWithDocumentOptionsAndSettings.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/WorkingWithDocumentOptionsAndSettings.java new file mode 100644 index 00000000..cffaa36e --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/WorkingWithDocumentOptionsAndSettings.java @@ -0,0 +1,202 @@ +package DocsExamples.Programming_with_documents.Working_with_document; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.awt.*; +import java.text.MessageFormat; + +@Test +public class WorkingWithDocumentOptionsAndSettings extends DocsExamplesBase { + @Test + public void optimizeFor() throws Exception { + //ExStart:OptimizeFor + //GistId:2e73ea09c5fcbcb9f7b99f01602ecd34 + Document doc = new Document(getMyDir() + "Document.docx"); + + doc.getCompatibilityOptions().optimizeFor(MsWordVersion.WORD_2016); + + doc.save(getArtifactsDir() + "WorkingWithDocumentOptionsAndSettings.OptimizeFor.docx"); + //ExEnd:OptimizeFor + } + + @Test + public void showGrammaticalAndSpellingErrors() throws Exception { + //ExStart:ShowGrammaticalAndSpellingErrors + Document doc = new Document(getMyDir() + "Document.docx"); + + doc.setShowGrammaticalErrors(true); + doc.setShowSpellingErrors(true); + + doc.save(getArtifactsDir() + "WorkingWithDocumentOptionsAndSettings.ShowGrammaticalAndSpellingErrors.docx"); + //ExEnd:ShowGrammaticalAndSpellingErrors + } + + @Test + public void cleanupUnusedStylesAndLists() throws Exception { + //ExStart:CleanupUnusedStylesAndLists + //GistId:01b0f3024b265f429ec00ffd6ec30407 + Document doc = new Document(getMyDir() + "Unused styles.docx"); + + // Combined with the built-in styles, the document now has eight styles. + // A custom style is marked as "used" while there is any text within the document + // formatted in that style. This means that the 4 styles we added are currently unused. + System.out.println(MessageFormat.format("Count of styles before Cleanup: {0}\n", doc.getStyles().getCount()) + + MessageFormat.format("Count of lists before Cleanup: {0}", doc.getLists().getCount())); + + // Cleans unused styles and lists from the document depending on given CleanupOptions. + CleanupOptions cleanupOptions = new CleanupOptions(); + cleanupOptions.setUnusedLists(false); + cleanupOptions.setUnusedStyles(true); + + doc.cleanup(cleanupOptions); + + System.out.println(MessageFormat.format("Count of styles after Cleanup was decreased: {0}\n", doc.getStyles().getCount()) + + MessageFormat.format("Count of lists after Cleanup is the same: {0}", doc.getLists().getCount())); + + doc.save(getArtifactsDir() + "WorkingWithDocumentOptionsAndSettings.CleanupUnusedStylesAndLists.docx"); + //ExEnd:CleanupUnusedStylesAndLists + } + + @Test + public void cleanupDuplicateStyle() throws Exception { + //ExStart:CleanupDuplicateStyle + //GistId:01b0f3024b265f429ec00ffd6ec30407 + Document doc = new Document(getMyDir() + "Document.docx"); + + // Count of styles before Cleanup. + System.out.println(doc.getStyles().getCount()); + + // Cleans duplicate styles from the document. + CleanupOptions options = new CleanupOptions(); + options.setDuplicateStyle(true); + + doc.cleanup(options); + + // Count of styles after Cleanup was decreased. + System.out.println(doc.getStyles().getCount()); + + doc.save(getArtifactsDir() + "WorkingWithDocumentOptionsAndSettings.CleanupDuplicateStyle.docx"); + //ExEnd:CleanupDuplicateStyle + } + + @Test + public void viewOptions() throws Exception { + //ExStart:SetViewOption + //GistId:2e73ea09c5fcbcb9f7b99f01602ecd34 + Document doc = new Document(getMyDir() + "Document.docx"); + + doc.getViewOptions().setViewType(ViewType.PAGE_LAYOUT); + doc.getViewOptions().setZoomPercent(50); + + doc.save(getArtifactsDir() + "WorkingWithDocumentOptionsAndSettings.ViewOptions.docx"); + //ExEnd:SetViewOption + } + + @Test + public void documentPageSetup() throws Exception { + //ExStart:DocumentPageSetup + //GistId:2e73ea09c5fcbcb9f7b99f01602ecd34 + Document doc = new Document(getMyDir() + "Document.docx"); + + // Set the layout mode for a section allowing to define the document grid behavior. + // Note that the Document Grid tab becomes visible in the Page Setup dialog of MS Word + // if any Asian language is defined as editing language. + doc.getFirstSection().getPageSetup().setLayoutMode(SectionLayoutMode.GRID); + doc.getFirstSection().getPageSetup().setCharactersPerLine(30); + doc.getFirstSection().getPageSetup().setLinesPerPage(10); + + doc.save(getArtifactsDir() + "WorkingWithDocumentOptionsAndSettings.DocumentPageSetup.docx"); + //ExEnd:DocumentPageSetup + } + + @Test + public void addEditingLanguage() throws Exception { + //ExStart:AddEditingLanguage + //GistId:9216df344e0dc0025f5eda608b9f33d8 + LoadOptions loadOptions = new LoadOptions(); + // Set language preferences that will be used when document is loading. + loadOptions.getLanguagePreferences().addEditingLanguage(EditingLanguage.JAPANESE); + + Document doc = new Document(getMyDir() + "No default editing language.docx", loadOptions); + //ExEnd:AddEditingLanguage + + int localeIdFarEast = doc.getStyles().getDefaultFont().getLocaleIdFarEast(); + System.out.println(localeIdFarEast == (int) EditingLanguage.JAPANESE + ? "The document either has no any FarEast language set in defaults or it was set to Japanese originally." + : "The document default FarEast language was set to another than Japanese language originally, so it is not overridden."); + } + + @Test + public void setRussianAsDefaultEditingLanguage() throws Exception { + //ExStart:SetRussianAsDefaultEditingLanguage + //GistId:2e73ea09c5fcbcb9f7b99f01602ecd34 + LoadOptions loadOptions = new LoadOptions(); + loadOptions.getLanguagePreferences().setDefaultEditingLanguage(EditingLanguage.RUSSIAN); + + Document doc = new Document(getMyDir() + "No default editing language.docx", loadOptions); + + int localeId = doc.getStyles().getDefaultFont().getLocaleId(); + System.out.println(localeId == (int) EditingLanguage.RUSSIAN + ? "The document either has no any language set in defaults or it was set to Russian originally." + : "The document default language was set to another than Russian language originally, so it is not overridden."); + //ExEnd:SetRussianAsDefaultEditingLanguage + } + + @Test + public void pageSetupAndSectionFormatting() throws Exception { + //ExStart:PageSetupAndSectionFormatting + //GistId:7c0668453e53ed7a57d3ea3a05520f21 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getPageSetup().setOrientation(Orientation.LANDSCAPE); + builder.getPageSetup().setLeftMargin(50.0); + builder.getPageSetup().setPaperSize(PaperSize.PAPER_10_X_14); + + doc.save(getArtifactsDir() + "WorkingWithDocumentOptionsAndSettings.PageSetupAndSectionFormatting.docx"); + //ExEnd:PageSetupAndSectionFormatting + } + + @Test + public void pageBorderProperties() throws Exception { + //ExStart:PageBorderProperties + Document doc = new Document(); + + PageSetup pageSetup = doc.getSections().get(0).getPageSetup(); + pageSetup.setBorderAlwaysInFront(false); + pageSetup.setBorderDistanceFrom(PageBorderDistanceFrom.PAGE_EDGE); + pageSetup.setBorderAppliesTo(PageBorderAppliesTo.FIRST_PAGE); + + Border border = pageSetup.getBorders().getByBorderType(BorderType.TOP); + border.setLineStyle(LineStyle.SINGLE); + border.setLineWidth(30.0); + border.setColor(Color.BLUE); + border.setDistanceFromText(0.0); + + doc.save(getArtifactsDir() + "WorkingWithDocumentOptionsAndSettings.PageBorderProperties.docx"); + //ExEnd:PageBorderProperties + } + + @Test + public void lineGridSectionLayoutMode() throws Exception { + //ExStart:LineGridSectionLayoutMode + //GistId:7c0668453e53ed7a57d3ea3a05520f21 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Enable pitching, and then use it to set the number of lines per page in this section. + // A large enough font size will push some lines down onto the next page to avoid overlapping characters. + builder.getPageSetup().setLayoutMode(SectionLayoutMode.LINE_GRID); + builder.getPageSetup().setLinesPerPage(15); + + builder.getParagraphFormat().setSnapToGrid(true); + + for (int i = 0; i < 30; i++) + builder.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "); + + doc.save(getArtifactsDir() + "WorkingWithDocumentOptionsAndSettings.LinesPerPage.docx"); + //ExEnd:LineGridSectionLayoutMode + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/WorkingWithDocumentProperties.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/WorkingWithDocumentProperties.java new file mode 100644 index 00000000..dad981e2 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/WorkingWithDocumentProperties.java @@ -0,0 +1,139 @@ +package DocsExamples.Programming_with_documents.Working_with_document; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.text.MessageFormat; +import java.util.Date; +import java.util.Map; + +@Test +public class WorkingWithDocumentProperties extends DocsExamplesBase { + @Test + public void getVariables() throws Exception { + //ExStart:GetVariables + //GistId:feb3c519327ef97a854a50fe24cebba7 + Document doc = new Document(getMyDir() + "Document.docx"); + + String variables = ""; + for (Map.Entry entry : doc.getVariables()) { + String name = entry.getKey(); + String value = entry.getValue(); + if ("".equals(variables)) + variables = "Name: " + name + "," + "Value: {1}" + value; + else + variables = variables + "Name: " + name + "," + "Value: {1}" + value; + } + + System.out.println("\nDocument have following variables " + variables); + //ExEnd:GetVariables + } + + @Test + public void enumerateProperties() throws Exception { + //ExStart:EnumerateProperties + //GistId:feb3c519327ef97a854a50fe24cebba7 + Document doc = new Document(getMyDir() + "Properties.docx"); + + System.out.println(MessageFormat.format("1. Document name: {0}", doc.getOriginalFileName())); + System.out.println("2. Built-in Properties"); + + for (DocumentProperty prop : doc.getBuiltInDocumentProperties()) + System.out.println(MessageFormat.format("{0} : {1}", prop.getName(), prop.getValue())); + + System.out.println("3. Custom Properties"); + + for (DocumentProperty prop : doc.getCustomDocumentProperties()) + System.out.println(MessageFormat.format("{0} : {1}", prop.getName(), prop.getValue())); + //ExEnd:EnumerateProperties + } + + @Test + public void addCustomProperties() throws Exception { + //ExStart:AddCustomProperties + //GistId:feb3c519327ef97a854a50fe24cebba7 + Document doc = new Document(getMyDir() + "Properties.docx"); + + CustomDocumentProperties customDocumentProperties = doc.getCustomDocumentProperties(); + + if (customDocumentProperties.get("Authorized") != null) return; + + customDocumentProperties.add("Authorized", true); + customDocumentProperties.add("Authorized By", "John Smith"); + customDocumentProperties.add("Authorized Date", new Date()); + customDocumentProperties.add("Authorized Revision", doc.getBuiltInDocumentProperties().getRevisionNumber()); + customDocumentProperties.add("Authorized Amount", 123.45); + //ExEnd:AddCustomProperties + } + + @Test + public void removeCustomProperties() throws Exception { + //ExStart:RemoveCustomProperties + //GistId:feb3c519327ef97a854a50fe24cebba7 + Document doc = new Document(getMyDir() + "Properties.docx"); + doc.getCustomDocumentProperties().remove("Authorized Date"); + //ExEnd:RemoveCustomProperties + } + + @Test + public void removePersonalInformation() throws Exception { + //ExStart:RemovePersonalInformation + //GistId:feb3c519327ef97a854a50fe24cebba7 + Document doc = new Document(getMyDir() + "Properties.docx"); + doc.setRemovePersonalInformation(true); + + doc.save(getArtifactsDir() + "DocumentPropertiesAndVariables.RemovePersonalInformation.docx"); + //ExEnd:RemovePersonalInformation + } + + @Test + public void configuringLinkToContent() throws Exception { + //ExStart:ConfiguringLinkToContent + //GistId:feb3c519327ef97a854a50fe24cebba7 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startBookmark("MyBookmark"); + builder.writeln("Text inside a bookmark."); + builder.endBookmark("MyBookmark"); + + // Retrieve a list of all custom document properties from the file. + CustomDocumentProperties customProperties = doc.getCustomDocumentProperties(); + // Add linked to content property. + DocumentProperty customProperty = customProperties.addLinkToContent("Bookmark", "MyBookmark"); + customProperty = customProperties.get("Bookmark"); + + boolean isLinkedToContent = customProperty.isLinkToContent(); + String linkSource = customProperty.getLinkSource(); + String customPropertyValue = customProperty.getValue().toString(); + //ExEnd:ConfiguringLinkToContent + } + + @Test + public void convertBetweenMeasurementUnits() throws Exception { + //ExStart:ConvertBetweenMeasurementUnits + //GistId:1c2a7e0357432a333546e8b33057046a + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + PageSetup pageSetup = builder.getPageSetup(); + pageSetup.setTopMargin(ConvertUtil.inchToPoint(1.0)); + pageSetup.setBottomMargin(ConvertUtil.inchToPoint(1.0)); + pageSetup.setLeftMargin(ConvertUtil.inchToPoint(1.5)); + pageSetup.setRightMargin(ConvertUtil.inchToPoint(1.5)); + pageSetup.setHeaderDistance(ConvertUtil.inchToPoint(0.2)); + pageSetup.setFooterDistance(ConvertUtil.inchToPoint(0.2)); + //ExEnd:ConvertBetweenMeasurementUnits + } + + @Test + public void useControlCharacters() { + //ExStart:UseControlCharacters + //GistId:920532ffbf33fbda20b92054f596a8ac + String text = "test\r"; + // Replace "\r" control character with "\r\n". + String replace = text.replace(ControlChar.CR, ControlChar.CR_LF); + //ExEnd:UseControlCharacters + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/WorkingWithWebExtension.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/WorkingWithWebExtension.java new file mode 100644 index 00000000..500af0e2 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_document/WorkingWithWebExtension.java @@ -0,0 +1,47 @@ +package DocsExamples.Programming_with_documents.Working_with_document; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.text.MessageFormat; + +@Test +public class WorkingWithWebExtension extends DocsExamplesBase { + @Test + public void webExtensionTaskPanes() throws Exception { + //ExStart:WebExtensionTaskPanes + //GistId:b91d438dcc82b6b4a3c8db34ad732c7d + Document doc = new Document(); + + TaskPane taskPane = new TaskPane(); + doc.getWebExtensionTaskPanes().add(taskPane); + + taskPane.setDockState(TaskPaneDockState.RIGHT); + taskPane.isVisible(true); + taskPane.setWidth(300.0); + + taskPane.getWebExtension().getReference().setId("wa102923726"); + taskPane.getWebExtension().getReference().setVersion("1.0.0.0"); + taskPane.getWebExtension().getReference().setStoreType(WebExtensionStoreType.OMEX); + taskPane.getWebExtension().getReference().setStore("th-TH"); + taskPane.getWebExtension().getProperties().add(new WebExtensionProperty("mailchimpCampaign", "mailchimpCampaign")); + taskPane.getWebExtension().getBindings().add(new WebExtensionBinding("UnnamedBinding_0_1506535429545", + WebExtensionBindingType.TEXT, "194740422")); + + doc.save(getArtifactsDir() + "WorkingWithWebExtension.WebExtensionTaskPanes.docx"); + //ExEnd:WebExtensionTaskPanes + + //ExStart:GetListOfAddins + //GistId:b91d438dcc82b6b4a3c8db34ad732c7d + doc = new Document(getArtifactsDir() + "WorkingWithWebExtension.WebExtensionTaskPanes.docx"); + + System.out.println("Task panes sources:\n"); + + for (TaskPane taskPaneInfo : doc.getWebExtensionTaskPanes()) { + WebExtensionReference reference = taskPaneInfo.getWebExtension().getReference(); + System.out.println(MessageFormat.format("Provider: \"{0}\", version: \"{1}\", catalog identifier: \"{2}\";", reference.getStore(), reference.getVersion(), reference.getId())); + } + //ExEnd:GetListOfAddins + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_graphic_elements/CustomBarcodeGenerator.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_graphic_elements/CustomBarcodeGenerator.java new file mode 100644 index 00000000..9447248e --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_graphic_elements/CustomBarcodeGenerator.java @@ -0,0 +1,262 @@ +package DocsExamples.Programming_with_documents.Working_with_graphic_elements; + +import com.aspose.barcode.generation.*; +import com.aspose.words.BarcodeParameters; +import com.aspose.words.IBarcodeGenerator; + +import java.awt.*; +import java.awt.image.BufferedImage; + +//ExStart:CustomBarcodeGenerator +//GistId:689e63b98de2dcbb12dffc37afbe9067 +class CustomBarcodeGeneratorUtils { + /// + /// Converts a height value in twips to pixels using a default DPI of 96. + /// + /// The height value in twips. + /// The default value to return if the conversion fails. + /// The height value in pixels. + public static double twipsToPixels(String heightInTwips, double defVal) { + return twipsToPixels(heightInTwips, 96.0, defVal); + } + + /// + /// Converts a height value in twips to pixels based on the given resolution. + /// + /// The height value in twips to be converted. + /// The resolution in pixels per inch. + /// The default value to be returned if the conversion fails. + /// The converted height value in pixels. + public static double twipsToPixels(String heightInTwips, double resolution, double defVal) { + try { + int lVal = Integer.parseInt(heightInTwips); + return (lVal / 1440.0) * resolution; + } catch (Exception e) { + return defVal; + } + } + + /// + /// Gets the rotation angle in degrees based on the given rotation angle string. + /// + /// The rotation angle string. + /// The default value to return if the rotation angle is not recognized. + /// The rotation angle in degrees. + public static float getRotationAngle(String rotationAngle, float defVal) { + switch (rotationAngle) { + case "0": + return 0f; + case "1": + return 270f; + case "2": + return 180f; + case "3": + return 90f; + default: + return defVal; + } + } + + /// + /// Converts a string representation of an error correction level to a QRErrorLevel enum value. + /// + /// The string representation of the error correction level. + /// The default error correction level to return if the input is invalid. + /// The corresponding QRErrorLevel enum value. + public static QRErrorLevel getQRCorrectionLevel(String errorCorrectionLevel, QRErrorLevel def) { + switch (errorCorrectionLevel) { + case "0": + return QRErrorLevel.LEVEL_L; + case "1": + return QRErrorLevel.LEVEL_M; + case "2": + return QRErrorLevel.LEVEL_Q; + case "3": + return QRErrorLevel.LEVEL_H; + default: + return def; + } + } + + /// + /// Gets the barcode encode type based on the given encode type from Word. + /// + /// The encode type from Word. + /// The barcode encode type. + public static SymbologyEncodeType getBarcodeEncodeType(String encodeTypeFromWord) { + // https://support.microsoft.com/en-au/office/field-codes-displaybarcode-6d81eade-762d-4b44-ae81-f9d3d9e07be3 + switch (encodeTypeFromWord) { + case "QR": + return EncodeTypes.QR; + case "CODE128": + return EncodeTypes.CODE_128; + case "CODE39": + return EncodeTypes.CODE_39; + case "JPPOST": + return EncodeTypes.RM_4_SCC; + case "EAN8": + case "JAN8": + return EncodeTypes.EAN_8; + case "EAN13": + case "JAN13": + return EncodeTypes.EAN_13; + case "UPCA": + return EncodeTypes.UPCA; + case "UPCE": + return EncodeTypes.UPCE; + case "CASE": + case "ITF14": + return EncodeTypes.ITF_14; + case "NW7": + return EncodeTypes.CODABAR; + default: + return EncodeTypes.NONE; + } + } + + /// + /// Converts a hexadecimal color string to a Color object. + /// + /// The hexadecimal color string to convert. + /// The default Color value to return if the conversion fails. + /// The Color object representing the converted color, or the default value if the conversion fails. + public static Color convertColor(String inputColor, Color defVal) { + if (inputColor == null || inputColor.isEmpty()) return defVal; + try { + int color = Integer.parseInt(inputColor, 16); + // Return Color.FromArgb((color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF); + return new Color((color & 0xFF), ((color >> 8) & 0xFF), ((color >> 16) & 0xFF)); + } catch (Exception e) { + return defVal; + } + } + + /// + /// Calculates the scale factor based on the provided string representation. + /// + /// The string representation of the scale factor. + /// The default value to return if the scale factor cannot be parsed. + /// + /// The scale factor as a decimal value between 0 and 1, or the default value if the scale factor cannot be parsed. + /// + public static double scaleFactor(String scaleFactor, double defVal) { + try { + int scale = Integer.parseInt(scaleFactor); + return scale / 100.0; + } catch (Exception e) { + return defVal; + } + } + + /// + /// Sets the position code style for a barcode generator. + /// + /// The barcode generator. + /// The position code style to set. + /// The barcode value. + public static void setPosCodeStyle(BarcodeGenerator gen, String posCodeStyle, String barcodeValue) { + switch (posCodeStyle) { + // STD default and without changes. + case "SUP2": + gen.setCodeText(barcodeValue.substring((0), (0) + (barcodeValue.length() - 2))); + gen.getParameters().getBarcode().getSupplement().setSupplementData(barcodeValue.substring((barcodeValue.length() - 2), (barcodeValue.length() - 2) + (2))); + break; + case "SUP5": + gen.setCodeText(barcodeValue.substring((0), (0) + (barcodeValue.length() - 5))); + gen.getParameters().getBarcode().getSupplement().setSupplementData(barcodeValue.substring((barcodeValue.length() - 5), (barcodeValue.length() - 5) + (5))); + break; + case "CASE": + gen.getParameters().getBorder().setVisible(true); + gen.getParameters().getBorder().setColor(gen.getParameters().getBarcode().getBarColor()); + gen.getParameters().getBorder().setDashStyle(BorderDashStyle.SOLID); + gen.getParameters().getBorder().getWidth().setPixels(gen.getParameters().getBarcode().getXDimension().getPixels() * 5); + break; + } + } + + public static final double DEFAULT_QRX_DIMENSION_IN_PIXELS = 4.0; + public static final double DEFAULT_1_DX_DIMENSION_IN_PIXELS = 1.0; + + /// + /// Draws an error image with the specified exception message. + /// + /// The exception containing the error message. + /// A Bitmap object representing the error image. + public static BufferedImage drawErrorImage(Exception error) { + BufferedImage bmp = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB); + + Graphics2D grf = bmp.createGraphics(); + grf.setColor(Color.WHITE); + grf.fillRect(0, 0, bmp.getWidth(), bmp.getHeight()); + grf.setFont(new Font("Microsoft Sans Serif", 8, FontStyle.REGULAR)); + grf.setColor(Color.RED); + grf.drawString(error.getMessage(), 0, 0); + + return bmp; + } + + public static BufferedImage convertImageToWord(BufferedImage bmp) { + return bmp; + } +} + +class CustomBarcodeGenerator implements IBarcodeGenerator { + public BufferedImage getBarcodeImage(BarcodeParameters parameters) { + try { + BarcodeGenerator gen = new BarcodeGenerator(CustomBarcodeGeneratorUtils.getBarcodeEncodeType(parameters.getBarcodeType()), parameters.getBarcodeValue()); + + // Set color. + gen.getParameters().getBarcode().setBarColor(CustomBarcodeGeneratorUtils.convertColor(parameters.getForegroundColor(), gen.getParameters().getBarcode().getBarColor())); + gen.getParameters().setBackColor(CustomBarcodeGeneratorUtils.convertColor(parameters.getBackgroundColor(), gen.getParameters().getBackColor())); + + // Set display or hide text. + if (!parameters.getDisplayText()) + gen.getParameters().getBarcode().getCodeTextParameters().setLocation(CodeLocation.NONE); + else + gen.getParameters().getBarcode().getCodeTextParameters().setLocation(CodeLocation.BELOW); + + // Set QR Code error correction level.s + gen.getParameters().getBarcode().getQR().setQrErrorLevel(QRErrorLevel.LEVEL_H); + String errorCorrectionLevel = parameters.getErrorCorrectionLevel(); + if (errorCorrectionLevel != null) + gen.getParameters().getBarcode().getQR().setQrErrorLevel(CustomBarcodeGeneratorUtils.getQRCorrectionLevel(errorCorrectionLevel, gen.getParameters().getBarcode().getQR().getQrErrorLevel())); + + // Set rotation angle. + String symbolRotation = parameters.getSymbolRotation(); + if (symbolRotation != null) + gen.getParameters().setRotationAngle(CustomBarcodeGeneratorUtils.getRotationAngle(symbolRotation, gen.getParameters().getRotationAngle())); + + // Set scaling factor. + double scalingFactor = 1.0; + if (parameters.getScalingFactor() != null) + scalingFactor = CustomBarcodeGeneratorUtils.scaleFactor(parameters.getScalingFactor(), scalingFactor); + + // Set size. + if (gen.getBarcodeType() == EncodeTypes.QR) + gen.getParameters().getBarcode().getXDimension().setPixels((float) Math.max(1.0, Math.round(CustomBarcodeGeneratorUtils.DEFAULT_QRX_DIMENSION_IN_PIXELS * scalingFactor))); + else + gen.getParameters().getBarcode().getXDimension().setPixels((float) Math.max(1.0, Math.round(CustomBarcodeGeneratorUtils.DEFAULT_1_DX_DIMENSION_IN_PIXELS * scalingFactor))); + + //Set height. + String symbolHeight = parameters.getSymbolHeight(); + if (symbolHeight != null) + gen.getParameters().getBarcode().getBarHeight().setPixels((float) Math.max(5.0, + Math.round(CustomBarcodeGeneratorUtils.twipsToPixels(symbolHeight, gen.getParameters().getBarcode().getBarHeight().getPixels()) * scalingFactor))); + + // Set style of a Point-of-Sale barcode. + String posCodeStyle = parameters.getPosCodeStyle(); + if (posCodeStyle != null) + CustomBarcodeGeneratorUtils.setPosCodeStyle(gen, posCodeStyle, parameters.getBarcodeValue()); + + return CustomBarcodeGeneratorUtils.convertImageToWord(gen.generateBarCodeImage()); + } catch (Exception e) { + return CustomBarcodeGeneratorUtils.convertImageToWord(CustomBarcodeGeneratorUtils.drawErrorImage(e)); + } + } + + public BufferedImage getOldBarcodeImage(BarcodeParameters parameters) { + throw new UnsupportedOperationException(); + } +} +//ExEnd:CustomBarcodeGenerator + diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_graphic_elements/WorkingWithBarcodeGenerator.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_graphic_elements/WorkingWithBarcodeGenerator.java new file mode 100644 index 00000000..8fc82818 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_graphic_elements/WorkingWithBarcodeGenerator.java @@ -0,0 +1,20 @@ +package DocsExamples.Programming_with_documents.Working_with_graphic_elements; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Document; +import org.testng.annotations.Test; + +@Test +public class WorkingWithBarcodeGenerator extends DocsExamplesBase { + @Test + public void barcodeGenerator() throws Exception { + //ExStart:BarcodeGenerator + //GistId:689e63b98de2dcbb12dffc37afbe9067 + Document doc = new Document(getMyDir() + "Field sample - BARCODE.docx"); + + doc.getFieldOptions().setBarcodeGenerator(new CustomBarcodeGenerator()); + + doc.save(getArtifactsDir() + "WorkingWithBarcodeGenerator.GenerateACustomBarCodeImage.pdf"); + //ExEnd:BarcodeGenerator + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_graphic_elements/WorkingWithCharts.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_graphic_elements/WorkingWithCharts.java new file mode 100644 index 00000000..3fbae331 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_graphic_elements/WorkingWithCharts.java @@ -0,0 +1,536 @@ +package DocsExamples.Programming_with_documents.Working_with_graphic_elements; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Shape; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.awt.*; +import java.util.Date; + +@Test +public class WorkingWithCharts extends DocsExamplesBase { + @Test + public void formatNumberOfDataLabel() throws Exception { + //ExStart:FormatNumberOfDataLabel + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.LINE, 432.0, 252.0); + + Chart chart = shape.getChart(); + chart.getTitle().setText("Data Labels With Different Number Format"); + + // Delete default generated series. + chart.getSeries().clear(); + + ChartSeries series = chart.getSeries().add("Aspose Series 1", + new String[]{"Category 1", "Category 2", "Category 3"}, + new double[]{2.5, 1.5, 3.5}); + + series.hasDataLabels(true); + series.getDataLabels().setShowValue(true); + series.getDataLabels().get(0).getNumberFormat().setFormatCode("\"$\"#,##0.00"); + series.getDataLabels().get(1).getNumberFormat().setFormatCode("dd/mm/yyyy"); + series.getDataLabels().get(2).getNumberFormat().setFormatCode("0.00%"); + + // Or you can set format code to be linked to a source cell, + // in this case NumberFormat will be reset to general and inherited from a source cell. + series.getDataLabels().get(2).getNumberFormat().isLinkedToSource(true); + + doc.save(getArtifactsDir() + "WorkingWithCharts.FormatNumberOfDataLabel.docx"); + //ExEnd:FormatNumberOfDataLabel + } + + @Test + public void createChartUsingShape() throws Exception { + //ExStart:CreateChartUsingShape + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.LINE, 432.0, 252.0); + + Chart chart = shape.getChart(); + chart.getTitle().setShow(true); + chart.getTitle().setText("Line Chart Title"); + chart.getTitle().setOverlay(false); + + // Please note if null or empty value is specified as title text, auto generated title will be shown. + chart.getLegend().setPosition(LegendPosition.LEFT); + chart.getLegend().setOverlay(true); + + doc.save(getArtifactsDir() + "WorkingWithCharts.CreateChartUsingShape.docx"); + //ExEnd:CreateChartUsingShape + } + + @Test + public void insertSimpleColumnChart() throws Exception { + //ExStart:InsertSimpleColumnChart + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // You can specify different chart types and sizes. + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + + Chart chart = shape.getChart(); + //ExStart:ChartSeriesCollection + //GistId:23d39c0b874655d7e7354f1ecc122e39 + ChartSeriesCollection seriesColl = chart.getSeries(); + + System.out.println(seriesColl.getCount()); + //ExEnd:ChartSeriesCollection + + // Delete default generated series. + seriesColl.clear(); + + // Create category names array, in this example we have two categories. + String[] categories = new String[]{"Category 1", "Category 2"}; + + // Please note, data arrays must not be empty and arrays must be the same size. + seriesColl.add("Aspose Series 1", categories, new double[]{1.0, 2.0}); + seriesColl.add("Aspose Series 2", categories, new double[]{3.0, 4.0}); + seriesColl.add("Aspose Series 3", categories, new double[]{5.0, 6.0}); + seriesColl.add("Aspose Series 4", categories, new double[]{7.0, 8.0}); + seriesColl.add("Aspose Series 5", categories, new double[]{9.0, 10.0}); + + doc.save(getArtifactsDir() + "WorkingWithCharts.InsertSimpleColumnChart.docx"); + //ExEnd:InsertSimpleColumnChart + } + + @Test + public void insertColumnChart() throws Exception { + //ExStart:InsertColumnChart + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + + Chart chart = shape.getChart(); + chart.getSeries().add("Aspose Series 1", new String[]{"Category 1", "Category 2"}, new double[]{1.0, 2.0}); + + doc.save(getArtifactsDir() + "WorkingWithCharts.InsertColumnChart.docx"); + //ExEnd:InsertColumnChart + } + + @Test + public void insertAreaChart() throws Exception { + //ExStart:InsertAreaChart + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.AREA, 432.0, 252.0); + + Chart chart = shape.getChart(); + chart.getSeries().add("Aspose Series 1", new Date[] + { + new Date(2002, 5, 1), + new Date(2002, 6, 1), + new Date(2002, 7, 1), + new Date(2002, 8, 1), + new Date(2002, 9, 1) + }, + new double[]{32.0, 32.0, 28.0, 12.0, 15.0}); + + doc.save(getArtifactsDir() + "WorkingWithCharts.InsertAreaChart.docx"); + //ExEnd:InsertAreaChart + } + + @Test + public void insertBubbleChart() throws Exception { + //ExStart:InsertBubbleChart + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.BUBBLE, 432.0, 252.0); + + Chart chart = shape.getChart(); + chart.getSeries().add("Aspose Series 1", new double[]{0.7, 1.8, 2.6}, new double[]{2.7, 3.2, 0.8}, + new double[]{10.0, 4.0, 8.0}); + + doc.save(getArtifactsDir() + "WorkingWithCharts.InsertBubbleChart.docx"); + //ExEnd:InsertBubbleChart + } + + @Test + public void insertScatterChart() throws Exception { + //ExStart:InsertScatterChart + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.SCATTER, 432.0, 252.0); + + Chart chart = shape.getChart(); + chart.getSeries().add("Aspose Series 1", new double[]{0.7, 1.8, 2.6}, new double[]{2.7, 3.2, 0.8}); + + doc.save(getArtifactsDir() + "WorkingWithCharts.InsertScatterChart.docx"); + //ExEnd:InsertScatterChart + } + + @Test + public void defineAxisProperties() throws Exception { + //ExStart:DefineAxisProperties + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert chart + Shape shape = builder.insertChart(ChartType.AREA, 432.0, 252.0); + + Chart chart = shape.getChart(); + + chart.getSeries().clear(); + + chart.getSeries().add("Aspose Series 1", + new Date[] + { + new Date(2002, 1, 1), new Date(2002, 6, 1), new Date(2002, 7, 1), + new Date(2002, 8, 1), new Date(2002, 9, 1) + }, + new double[]{640.0, 320.0, 280.0, 120.0, 150.0}); + + ChartAxis xAxis = chart.getAxisX(); + ChartAxis yAxis = chart.getAxisY(); + + // Change the X axis to be category instead of date, so all the points will be put with equal interval on the X axis. + xAxis.setCategoryType(AxisCategoryType.CATEGORY); + xAxis.setCrosses(AxisCrosses.CUSTOM); + xAxis.setCrossesAt(3.0); // Measured in display units of the Y axis (hundreds). + xAxis.setReverseOrder(true); + xAxis.setMajorTickMark(AxisTickMark.CROSS); + xAxis.setMinorTickMark(AxisTickMark.OUTSIDE); + xAxis.getTickLabels().setOffset(200); + + yAxis.getTickLabels().setPosition(AxisTickLabelPosition.HIGH); + yAxis.setMajorUnit(100.0); + yAxis.setMinorUnit(50.0); + yAxis.getDisplayUnit().setUnit(AxisBuiltInUnit.HUNDREDS); + yAxis.getScaling().setMinimum(new AxisBound(100.0)); + yAxis.getScaling().setMaximum(new AxisBound(700.0)); + + doc.save(getArtifactsDir() + "WorkingWithCharts.DefineAxisProperties.docx"); + //ExEnd:DefineAxisProperties + } + + @Test + public void dateTimeValuesToAxis() throws Exception { + //ExStart:DateTimeValuesToAxis + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + Chart chart = shape.getChart(); + + chart.getSeries().clear(); + + chart.getSeries().add("Aspose Series 1", + new Date[] + { + new Date(2017, 11, 6), new Date(2017, 11, 9), new Date(2017, 11, 15), + new Date(2017, 11, 21), new Date(2017, 11, 25), new Date(2017, 11, 29) + }, + new double[]{1.2, 0.3, 2.1, 2.9, 4.2, 5.3}); + + ChartAxis xAxis = chart.getAxisX(); + xAxis.getScaling().setMinimum(new AxisBound(new Date(2017, 11, 5))); + xAxis.getScaling().setMaximum(new AxisBound(new Date(2017, 12, 3))); + + // Set major units to a week and minor units to a day. + xAxis.setMajorUnit(7.0); + xAxis.setMinorUnit(1.0); + xAxis.setMajorTickMark(AxisTickMark.CROSS); + xAxis.setMinorTickMark(AxisTickMark.OUTSIDE); + + doc.save(getArtifactsDir() + "WorkingWithCharts.DateTimeValuesToAxis.docx"); + //ExEnd:DateTimeValuesToAxis + } + + @Test + public void numberFormatForAxis() throws Exception { + //ExStart:NumberFormatForAxis + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + Chart chart = shape.getChart(); + chart.getSeries().clear(); + + chart.getSeries().add("Aspose Series 1", + new String[]{"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"}, + new double[]{1900000.0, 850000.0, 2100000.0, 600000.0, 1500000.0}); + chart.getAxisY().getNumberFormat().setFormatCode("#,##0"); + + doc.save(getArtifactsDir() + "WorkingWithCharts.NumberFormatForAxis.docx"); + //ExEnd:NumberFormatForAxis + } + + @Test + public void boundsOfAxis() throws Exception { + //ExStart:BoundsOfAxis + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + Chart chart = shape.getChart(); + chart.getSeries().clear(); + + chart.getSeries().add("Aspose Series 1", + new String[]{"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"}, + new double[]{1.2, 0.3, 2.1, 2.9, 4.2}); + chart.getAxisY().getScaling().setMinimum(new AxisBound(0.0)); + chart.getAxisY().getScaling().setMaximum(new AxisBound(6.0)); + + doc.save(getArtifactsDir() + "WorkingWithCharts.BoundsOfAxis.docx"); + //ExEnd:BoundsOfAxis + } + + @Test + public void intervalUnitBetweenLabelsOnAxis() throws Exception { + //ExStart:IntervalUnitBetweenLabelsOnAxis + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + Chart chart = shape.getChart(); + chart.getSeries().clear(); + + chart.getSeries().add("Aspose Series 1", + new String[]{"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"}, + new double[]{1.2, 0.3, 2.1, 2.9, 4.2}); + chart.getAxisX().getTickLabels().setSpacing(2); + + doc.save(getArtifactsDir() + "WorkingWithCharts.IntervalUnitBetweenLabelsOnAxis.docx"); + //ExEnd:IntervalUnitBetweenLabelsOnAxis + } + + @Test + public void hideChartAxis() throws Exception { + //ExStart:HideChartAxis + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + Chart chart = shape.getChart(); + chart.getSeries().clear(); + + chart.getSeries().add("Aspose Series 1", + new String[]{"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"}, + new double[]{1.2, 0.3, 2.1, 2.9, 4.2}); + chart.getAxisY().setHidden(true); + + doc.save(getArtifactsDir() + "WorkingWithCharts.HideChartAxis.docx"); + //ExEnd:HideChartAxis + } + + @Test + public void tickMultiLineLabelAlignment() throws Exception { + //ExStart:TickMultiLineLabelAlignment + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.SCATTER, 450.0, 250.0); + + ChartAxis axis = shape.getChart().getAxisX(); + // This property has effect only for multi-line labels. + axis.getTickLabels().setAlignment(ParagraphAlignment.RIGHT); + + doc.save(getArtifactsDir() + "WorkingWithCharts.TickMultiLineLabelAlignment.docx"); + //ExEnd:TickMultiLineLabelAlignment + } + + @Test + public void chartDataLabel() throws Exception { + //ExStart:WorkWithChartDataLabel + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.BAR, 432.0, 252.0); + Chart chart = shape.getChart(); + ChartSeries series0 = chart.getSeries().get(0); + + ChartDataLabelCollection labels = series0.getDataLabels(); + labels.setShowLegendKey(true); + // By default, when you add data labels to the data points in a pie chart, leader lines are displayed for data labels that are + // positioned far outside the end of data points. Leader lines create a visual connection between a data label and its + // corresponding data point. + labels.setShowLeaderLines(true); + labels.setShowCategoryName(false); + labels.setShowPercentage(false); + labels.setShowSeriesName(true); + labels.setShowValue(true); + labels.setSeparator("/"); + labels.setShowValue(true); + + doc.save(getArtifactsDir() + "WorkingWithCharts.ChartDataLabel.docx"); + //ExEnd:WorkWithChartDataLabel + } + + @Test + public void defaultOptionsForDataLabels() throws Exception { + //ExStart:DefaultOptionsForDataLabels + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.PIE, 432.0, 252.0); + Chart chart = shape.getChart(); + chart.getSeries().clear(); + + ChartSeries series = chart.getSeries().add("Aspose Series 1", + new String[]{"Category 1", "Category 2", "Category 3"}, + new double[]{2.7, 3.2, 0.8}); + + ChartDataLabelCollection labels = series.getDataLabels(); + labels.setShowPercentage(true); + labels.setShowValue(true); + labels.setShowLeaderLines(false); + labels.setSeparator(" - "); + + doc.save(getArtifactsDir() + "WorkingWithCharts.DefaultOptionsForDataLabels.docx"); + //ExEnd:DefaultOptionsForDataLabels + } + + @Test + public void singleChartDataPoint() throws Exception { + //ExStart:WorkWithSingleChartDataPoint + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.LINE, 432.0, 252.0); + + Chart chart = shape.getChart(); + ChartSeries series0 = chart.getSeries().get(0); + ChartSeries series1 = chart.getSeries().get(1); + + ChartDataPointCollection dataPointCollection = series0.getDataPoints(); + ChartDataPoint dataPoint00 = dataPointCollection.get(0); + ChartDataPoint dataPoint01 = dataPointCollection.get(1); + + dataPoint00.setExplosion(50); + dataPoint00.getMarker().setSymbol(MarkerSymbol.CIRCLE); + dataPoint00.getMarker().setSize(15); + + dataPoint01.getMarker().setSymbol(MarkerSymbol.DIAMOND); + dataPoint01.getMarker().setSize(20); + + ChartDataPoint dataPoint12 = series1.getDataPoints().get(2); + dataPoint12.setInvertIfNegative(true); + dataPoint12.getMarker().setSymbol(MarkerSymbol.STAR); + dataPoint12.getMarker().setSize(20); + + doc.save(getArtifactsDir() + "WorkingWithCharts.SingleChartDataPoint.docx"); + //ExEnd:WorkWithSingleChartDataPoint + } + + @Test + public void singleChartSeries() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.LINE, 432.0, 252.0); + Chart chart = shape.getChart(); + + //ExStart:WorkWithSingleChartSeries + //GistId:23d39c0b874655d7e7354f1ecc122e39 + ChartSeries series0 = chart.getSeries().get(0); + ChartSeries series1 = chart.getSeries().get(1); + + series0.setName("Chart Series Name 1"); + series1.setName("Chart Series Name 2"); + + // You can also specify whether the line connecting the points on the chart shall be smoothed using Catmull-Rom splines. + series0.setSmooth(true); + series1.setSmooth(true); + //ExEnd:WorkWithSingleChartSeries + + //ExStart:ChartDataPoint + //GistId:23d39c0b874655d7e7354f1ecc122e39 + // Specifies whether by default the parent element shall inverts its colors if the value is negative. + series0.setInvertIfNegative(true); + + series0.getMarker().setSymbol(MarkerSymbol.CIRCLE); + series0.getMarker().setSize(15); + + series1.getMarker().setSymbol(MarkerSymbol.STAR); + series1.getMarker().setSize(10); + //ExEnd:ChartDataPoint + + doc.save(getArtifactsDir() + "WorkingWithCharts.SingleChartSeries.docx"); + } + + @Test + public void fillFormatting() throws Exception { + //ExStart:FillFormatting + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + Chart chart = shape.getChart(); + ChartSeriesCollection seriesColl = chart.getSeries(); + + // Delete default generated series. + seriesColl.clear(); + + // Create category names array. + String[] categories = new String[]{"AW Category 1", "AW Category 2"}; + + // Adding new series. Value and category arrays must be the same size. + ChartSeries series1 = seriesColl.add("AW Series 1", categories, new double[]{1.0, 2.0}); + ChartSeries series2 = seriesColl.add("AW Series 2", categories, new double[]{3.0, 4.0}); + ChartSeries series3 = seriesColl.add("AW Series 3", categories, new double[]{5.0, 6.0}); + + // Set series color. + series1.getFormat().getFill().setForeColor(Color.RED); + series2.getFormat().getFill().setForeColor(Color.YELLOW); + series3.getFormat().getFill().setForeColor(Color.BLUE); + + doc.save(getArtifactsDir() + "WorkingWithCharts.FillFormatting.docx"); + //ExEnd:FillFormatting + } + + @Test + public void strokeFormatting() throws Exception { + //ExStart:StrokeFormatting + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.LINE, 432.0, 252.0); + Chart chart = shape.getChart(); + ChartSeriesCollection seriesColl = chart.getSeries(); + + // Delete default generated series. + seriesColl.clear(); + + // Adding new series. + ChartSeries series1 = seriesColl.add("AW Series 1", new double[]{0.7, 1.8, 2.6}, + new double[]{2.7, 3.2, 0.8}); + ChartSeries series2 = seriesColl.add("AW Series 2", new double[]{0.5, 1.5, 2.5}, + new double[]{3.0, 1.0, 2.0}); + + // Set series color. + series1.getFormat().getStroke().setForeColor(Color.RED); + series1.getFormat().getStroke().setWeight(5.0); + series2.getFormat().getStroke().setForeColor(Color.GREEN); + series2.getFormat().getStroke().setWeight(5.0); + + doc.save(getArtifactsDir() + "WorkingWithCharts.StrokeFormatting.docx"); + //ExEnd:StrokeFormatting + } +} + diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_graphic_elements/WorkingWithImages.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_graphic_elements/WorkingWithImages.java new file mode 100644 index 00000000..0df1b3ed --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_graphic_elements/WorkingWithImages.java @@ -0,0 +1,342 @@ +package DocsExamples.Programming_with_documents.Working_with_graphic_elements; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Shape; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import javax.imageio.ImageIO; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageOutputStream; +import java.awt.*; +import java.awt.geom.Point2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.text.MessageFormat; +import java.util.Iterator; + +public class WorkingWithImages extends DocsExamplesBase +{ + @Test + public void addImageToEachPage() throws Exception + { + Document doc = new Document(getMyDir() + "Document.docx"); + + // Create and attach collector before the document before page layout is built. + LayoutCollector layoutCollector = new LayoutCollector(doc); + + // Images in a document are added to paragraphs to add an image to every page we need + // to find at any paragraph belonging to each page. + Iterator enumerator = doc.selectNodes("// Body/Paragraph").iterator(); + + for (int page = 1; page <= doc.getPageCount(); page++) + { + while (enumerator.hasNext()) + { + // Check if the current paragraph belongs to the target page. + Paragraph paragraph = (Paragraph) enumerator.next(); + if (layoutCollector.getStartPageIndex(paragraph) == page) + { + addImageToPage(paragraph, page); + break; + } + } + } + + // If we need to save the document as a PDF or image, call UpdatePageLayout() method. + doc.updatePageLayout(); + + doc.save(getArtifactsDir() + "WorkingWithImages.AddImageToEachPage.docx"); + } + + /// + /// Adds an image to a page using the supplied paragraph. + /// + /// The paragraph to an an image to. + /// The page number the paragraph appears on. + public void addImageToPage(Paragraph para, int page) throws Exception + { + Document doc = (Document) para.getDocument(); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.moveTo(para); + + // Insert a logo to the top left of the page to place it in front of all other text. + builder.insertImage(getImagesDir() + "Transparent background logo.png", RelativeHorizontalPosition.PAGE, 60.0, + RelativeVerticalPosition.PAGE, 60.0, -1, -1, WrapType.NONE); + + // Insert a textbox next to the image which contains some text consisting of the page number. + Shape textBox = new Shape(doc, ShapeType.TEXT_BOX); + + // We want a floating shape relative to the page. + textBox.setWrapType(WrapType.NONE); + textBox.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE); + textBox.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE); + + textBox.setHeight(30.0); + textBox.setWidth(200.0); + textBox.setLeft(150.0); + textBox.setTop(80.0); + + textBox.appendChild(new Paragraph(doc)); + builder.insertNode(textBox); + builder.moveTo(textBox.getFirstChild()); + builder.writeln("This is a custom note for page " + page); + } + + @Test + public void insertBarcodeImage() throws Exception + { + //ExStart:InsertBarcodeImage + //GistId:6f849e51240635a6322ab0460938c922 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // The number of pages the document should have + final int NUM_PAGES = 4; + // The document starts with one section, insert the barcode into this existing section + insertBarcodeIntoFooter(builder, doc.getFirstSection(), HeaderFooterType.FOOTER_PRIMARY); + + for (int i = 1; i < NUM_PAGES; i++) + { + // Clone the first section and add it into the end of the document + Section cloneSection = (Section) doc.getFirstSection().deepClone(false); + cloneSection.getPageSetup().setSectionStart(SectionStart.NEW_PAGE); + doc.appendChild(cloneSection); + + // Insert the barcode and other information into the footer of the section + insertBarcodeIntoFooter(builder, cloneSection, HeaderFooterType.FOOTER_PRIMARY); + } + + // Save the document as a PDF to disk + // You can also save this directly to a stream + doc.save(getArtifactsDir() + "WorkingWithImages.InsertBarcodeImage.docx"); + //ExEnd:InsertBarcodeImage + } + + //ExStart:InsertBarcodeIntoFooter + //GistId:6f849e51240635a6322ab0460938c922 + private void insertBarcodeIntoFooter(DocumentBuilder builder, Section section, int footerType) throws Exception + { + // Move to the footer type in the specific section. + builder.moveToSection(section.getDocument().indexOf(section)); + builder.moveToHeaderFooter(footerType); + + // Insert the barcode, then move to the next line and insert the ID along with the page number. + // Use pageId if you need to insert a different barcode on each page. 0 = First page, 1 = Second page etc. + builder.insertImage(getImagesDir() + "Barcode.png"); + builder.writeln(); + builder.write("1234567890"); + builder.insertField("PAGE"); + + // Create a right-aligned tab at the right margin. + double tabPos = section.getPageSetup().getPageWidth() - section.getPageSetup().getRightMargin() - section.getPageSetup().getLeftMargin(); + builder.getCurrentParagraph().getParagraphFormat().getTabStops().add(new TabStop(tabPos, TabAlignment.RIGHT, + TabLeader.NONE)); + + // Move to the right-hand side of the page and insert the page and page total. + builder.write(ControlChar.TAB); + builder.insertField("PAGE"); + builder.write(" of "); + builder.insertField("NUMPAGES"); + } + //ExEnd:InsertBarcodeIntoFooter + + @Test + public void compressImages() throws Exception + { + Document doc = new Document(getMyDir() + "Images.docx"); + + // 220ppi Print - said to be excellent on most printers and screens. + // 150ppi Screen - said to be good for web pages and projectors. + // 96ppi Email - said to be good for minimal document size and sharing. + final int DESIRED_PPI = 150; + + // In .NET this seems to be a good compression/quality setting. + final int JPEG_QUALITY = 90; + + // Resample images to the desired PPI and save. + int count = Resampler.resample(doc, DESIRED_PPI, JPEG_QUALITY); + + System.out.println(MessageFormat.format("Resampled {0} images.", count)); + + if (count != 1) + System.out.println("We expected to have only 1 image resampled in this test document!"); + + doc.save(getArtifactsDir() + "WorkingWithImages.CompressImages.docx"); + + // Verify that the first image was compressed by checking the new PPI. + doc = new Document(getArtifactsDir() + "WorkingWithImages.CompressImages.docx"); + + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + double imagePpi = shape.getImageData().getImageSize().getWidthPixels() / + ConvertUtil.pointToInch(shape.getSizeInPoints().getX()); + + assert imagePpi < 150 : "Image was not resampled successfully."; + } + + @Test + public void cropImages() throws Exception + { + //ExStart:CropImages + //GistId:6f849e51240635a6322ab0460938c922 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + BufferedImage img = ImageIO.read(new File(getImagesDir() + "Logo.jpg")); + + int effectiveWidth = img.getWidth() - 570; + int effectiveHeight = img.getHeight() - 571; + + Shape croppedImage = builder.insertImage(img, + ConvertUtil.pixelToPoint(img.getWidth() - effectiveWidth), + ConvertUtil.pixelToPoint(img.getHeight() - effectiveHeight)); + + double widthRatio = croppedImage.getWidth() / ConvertUtil.pixelToPoint(img.getWidth()); + double heightRatio = croppedImage.getHeight() / ConvertUtil.pixelToPoint(img.getHeight()); + + if (widthRatio < 1) + croppedImage.getImageData().setCropRight(1.0 - widthRatio); + + if (heightRatio < 1) + croppedImage.getImageData().setCropBottom(1.0 - heightRatio); + + float leftToWidth = 124f / img.getWidth(); + float topToHeight = 90f / img.getHeight(); + + croppedImage.getImageData().setCropLeft(leftToWidth); + croppedImage.getImageData().setCropRight(croppedImage.getImageData().getCropRight() - leftToWidth); + + croppedImage.getImageData().setCropTop(topToHeight); + croppedImage.getImageData().setCropBottom(croppedImage.getImageData().getCropBottom() - topToHeight); + + croppedImage.getShapeRenderer().save(getArtifactsDir() + "WorkingWithImages.CropImages.jpg", new ImageSaveOptions(SaveFormat.JPEG)); + //ExEnd:CropImages + } +} + +class Resampler +{ + /// + /// Resamples all images in the document that are greater than the specified PPI (pixels per inch) to the specified PPI + /// and converts them to JPEG with the specified quality setting. + /// + /// The document to process. + /// Desired pixels per inch. 220 high quality. 150 screen quality. 96 email quality. + /// 0 - 100% JPEG quality. + /// + public static int resample(Document doc, int desiredPpi, int jpegQuality) throws Exception + { + int count = 0; + + for (Shape shape : (Iterable) doc.getChildNodes(NodeType.SHAPE, true)) + { + // It is important to use this method to get the picture shape size in points correctly, + // even if it is inside a group shape. + Point2D.Float shapeSizeInPoints = shape.getSizeInPoints(); + + if (resampleCore(shape.getImageData(), shapeSizeInPoints, desiredPpi, jpegQuality)) + count++; + } + + return count; + } + + /// + /// Resamples one VML or DrawingML image. + /// + private static boolean resampleCore(ImageData imageData, Point2D.Float shapeSizeInPoints, int ppi, int jpegQuality) throws Exception + { + // The are several shape types that can have an image (picture, ole object, ole control), let's skip other shapes. + if (imageData == null) + return false; + + // An image can be stored in shape or linked somewhere else, let's skip images that do not store bytes in shape. + byte[] originalBytes = imageData.getImageBytes(); + if (originalBytes == null) + return false; + + // Ignore metafiles, they are vector drawings, and we don't want to resample them. + int imageType = imageData.getImageType(); + if (imageType == ImageType.WMF || imageType == ImageType.EMF) + return false; + + try { + double shapeWidthInches = ConvertUtil.pointToInch(shapeSizeInPoints.getX()); + double shapeHeightInches = ConvertUtil.pointToInch(shapeSizeInPoints.getX()); + + // Calculate the current PPI of the image. + ImageSize imageSize = imageData.getImageSize(); + double currentPpiX = imageSize.getWidthPixels() / shapeWidthInches; + double currentPpiY = imageSize.getHeightPixels() / shapeHeightInches; + + System.out.println(MessageFormat.format("Image PpiX:{0}, PpiY:{1}. ", (int) currentPpiX, (int) currentPpiY)); + + // Let's resample only if the current PPI is higher than the requested PPI (e.g., we have extra data we can get rid of). + if (currentPpiX <= ppi || currentPpiY <= ppi) { + System.out.println("Skipping."); + return false; + } + + ByteArrayInputStream inputStream = new ByteArrayInputStream(originalBytes); + BufferedImage srcImage = ImageIO.read(inputStream); + + if (srcImage == null) { + System.out.println("Could not read image, skipping."); + return false; + } + + // Create a new image of such size that it will hold only the pixels required by the desired PPI. + int dstWidthPixels = (int) (shapeWidthInches * ppi); + int dstHeightPixels = (int) (shapeHeightInches * ppi); + + BufferedImage dstImage = new BufferedImage(dstWidthPixels, dstHeightPixels, BufferedImage.TYPE_INT_RGB); + + // Drawing the source image to the new image scales it to the new size. + Graphics2D gr = dstImage.createGraphics(); + gr.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); + gr.drawImage(srcImage, 0, 0, dstWidthPixels, dstHeightPixels, null); + gr.dispose(); + + // Save the image as JPEG to a byte array with quality setting. + ByteArrayOutputStream dstStream = new ByteArrayOutputStream(); + + // Get JPEG writer and set compression quality + Iterator writers = ImageIO.getImageWritersByFormatName("jpeg"); + if (!writers.hasNext()) { + throw new IllegalStateException("No JPEG writer found"); + } + + ImageWriter writer = writers.next(); + ImageWriteParam param = writer.getDefaultWriteParam(); + param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + param.setCompressionQuality(jpegQuality / 100.0f); + + ImageOutputStream ios = ImageIO.createImageOutputStream(dstStream); + writer.setOutput(ios); + writer.write(null, new javax.imageio.IIOImage(dstImage, null, null), param); + + writer.dispose(); + ios.close(); + + // If the image saved as JPEG is smaller than the original, store it in shape. + System.out.printf("Original size %d, new size %d.%n", originalBytes.length, dstStream.size()); + if (dstStream.size() < originalBytes.length) { + ByteArrayInputStream newImageStream = new ByteArrayInputStream(dstStream.toByteArray()); + imageData.setImage(newImageStream); + return true; + } + } + catch (Exception e) + { + // Catch an exception, log an error, and continue to process one of the images for whatever reason. + System.out.println("Error processing an image, ignoring. " + e.getMessage()); + } + + return false; + } +} + diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_graphic_elements/WorkingWithOfficeMath.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_graphic_elements/WorkingWithOfficeMath.java new file mode 100644 index 00000000..083f786b --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_graphic_elements/WorkingWithOfficeMath.java @@ -0,0 +1,23 @@ +package DocsExamples.Programming_with_documents.Working_with_graphic_elements; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +@Test +public class WorkingWithOfficeMath extends DocsExamplesBase { + @Test + public void mathEquations() throws Exception { + //ExStart:MathEquations + //GistId:e19d5874b376b07466fd7a397d554648 + Document doc = new Document(getMyDir() + "Office math.docx"); + OfficeMath officeMath = (OfficeMath) doc.getChild(NodeType.OFFICE_MATH, 0, true); + + // OfficeMath display type represents whether an equation is displayed inline with the text or displayed on its line. + officeMath.setDisplayType(OfficeMathDisplayType.DISPLAY); + officeMath.setJustification(OfficeMathJustification.LEFT); + + doc.save(getArtifactsDir() + "WorkingWithOfficeMath.MathEquations.docx"); + //ExEnd:MathEquations + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_graphic_elements/WorkingWithShapes.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_graphic_elements/WorkingWithShapes.java new file mode 100644 index 00000000..2db3978e --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_graphic_elements/WorkingWithShapes.java @@ -0,0 +1,204 @@ +package DocsExamples.Programming_with_documents.Working_with_graphic_elements; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Shape; +import com.aspose.words.*; +import org.apache.commons.collections4.IterableUtils; +import org.testng.annotations.Test; + +import java.awt.*; +import java.text.MessageFormat; +import java.util.List; + +@Test +public class WorkingWithShapes extends DocsExamplesBase { + @Test + public void addGroupShape() throws Exception { + //ExStart:AddGroupShape + //GistId:072edc4bbb0dd0eebf1f61f610bd8d36 + Document doc = new Document(); + doc.ensureMinimum(); + + GroupShape groupShape = new GroupShape(doc); + Shape accentBorderShape = new Shape(doc, ShapeType.ACCENT_BORDER_CALLOUT_1); + accentBorderShape.setWidth(100.0); + accentBorderShape.setHeight(100.0); + + groupShape.appendChild(accentBorderShape); + + Shape actionButtonShape = new Shape(doc, ShapeType.ACTION_BUTTON_BEGINNING); + actionButtonShape.setLeft(100.0); + actionButtonShape.setWidth(100.0); + actionButtonShape.setHeight(200.0); + + groupShape.appendChild(actionButtonShape); + + groupShape.setWidth(200.0); + groupShape.setHeight(200.0); + groupShape.setCoordSize(new Dimension(200, 200)); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertNode(groupShape); + + doc.save(getArtifactsDir() + "WorkingWithShapes.AddGroupShape.docx"); + //ExEnd:AddGroupShape + } + + @Test + public void insertShape() throws Exception { + //ExStart:InsertShape + //GistId:ad463bf5f128fe6e6c1485df3c046a4c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertShape(ShapeType.TEXT_BOX, RelativeHorizontalPosition.PAGE, 100.0, + RelativeVerticalPosition.PAGE, 100.0, 50.0, 50.0, WrapType.NONE); + shape.setRotation(30.0); + + builder.writeln(); + + shape = builder.insertShape(ShapeType.TEXT_BOX, 50.0, 50.0); + shape.setRotation(30.0); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(SaveFormat.DOCX); + saveOptions.setCompliance(OoxmlCompliance.ISO_29500_2008_TRANSITIONAL); + + doc.save(getArtifactsDir() + "WorkingWithShapes.InsertShape.docx", saveOptions); + //ExEnd:InsertShape + } + + @Test + public void aspectRatioLocked() throws Exception { + //ExStart:AspectRatioLocked + //GistId:ad463bf5f128fe6e6c1485df3c046a4c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertImage(getImagesDir() + "Transparent background logo.png"); + shape.setAspectRatioLocked(false); + + doc.save(getArtifactsDir() + "WorkingWithShapes.AspectRatioLocked.docx"); + //ExEnd:AspectRatioLocked + } + + @Test + public void layoutInCell() throws Exception { + //ExStart:LayoutInCell + //GistId:ad463bf5f128fe6e6c1485df3c046a4c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startTable(); + builder.getRowFormat().setHeight(100.0); + builder.getRowFormat().setHeightRule(HeightRule.EXACTLY); + + for (int i = 0; i < 31; i++) { + if (i != 0 && i % 7 == 0) builder.endRow(); + builder.insertCell(); + builder.write("Cell contents"); + } + + builder.endTable(); + + Shape watermark = new Shape(doc, ShapeType.TEXT_PLAIN_TEXT); + watermark.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE); + watermark.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE); + watermark.isLayoutInCell(true); // Display the shape outside of the table cell if it will be placed into a cell. + watermark.setWidth(300.0); + watermark.setHeight(70.0); + watermark.setHorizontalAlignment(HorizontalAlignment.CENTER); + watermark.setVerticalAlignment(VerticalAlignment.CENTER); + watermark.setRotation(-40); + + watermark.setFillColor(Color.GRAY); + watermark.setStrokeColor(Color.GRAY); + + watermark.getTextPath().setText("watermarkText"); + watermark.getTextPath().setFontFamily("Arial"); + + watermark.setName("WaterMark_{Guid.NewGuid()}"); + watermark.setWrapType(WrapType.NONE); + + Run run = (Run) doc.getChildNodes(NodeType.RUN, true).get(doc.getChildNodes(NodeType.RUN, true).getCount() - 1); + + builder.moveTo(run); + builder.insertNode(watermark); + doc.getCompatibilityOptions().optimizeFor(MsWordVersion.WORD_2010); + + doc.save(getArtifactsDir() + "WorkingWithShapes.LayoutInCell.docx"); + //ExEnd:LayoutInCell + } + + @Test + public void addCornersSnipped() throws Exception { + //ExStart:AddCornersSnipped + //GistId:ad463bf5f128fe6e6c1485df3c046a4c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertShape(ShapeType.TOP_CORNERS_SNIPPED, 50.0, 50.0); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(SaveFormat.DOCX); + saveOptions.setCompliance(OoxmlCompliance.ISO_29500_2008_TRANSITIONAL); + + doc.save(getArtifactsDir() + "WorkingWithShapes.AddCornersSnipped.docx", saveOptions); + //ExEnd:AddCornersSnipped + } + + @Test + public void getActualShapeBoundsPoints() throws Exception { + //ExStart:GetActualShapeBoundsPoints + //GistId:ad463bf5f128fe6e6c1485df3c046a4c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertImage(getImagesDir() + "Transparent background logo.png"); + shape.setAspectRatioLocked(false); + + System.out.println("\nGets the actual bounds of the shape in points: "); + System.out.println(shape.getShapeRenderer().getBoundsInPoints()); + //ExEnd:GetActualShapeBoundsPoints + } + + @Test + public void verticalAnchor() throws Exception { + //ExStart:VerticalAnchor + //GistId:ad463bf5f128fe6e6c1485df3c046a4c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape textBox = builder.insertShape(ShapeType.TEXT_BOX, 200.0, 200.0); + textBox.getTextBox().setVerticalAnchor(TextBoxAnchor.BOTTOM); + + builder.moveTo(textBox.getFirstParagraph()); + builder.write("Textbox contents"); + + doc.save(getArtifactsDir() + "WorkingWithShapes.VerticalAnchor.docx"); + //ExEnd:VerticalAnchor + } + + @Test + public void detectSmartArtShape() throws Exception { + //ExStart:DetectSmartArtShape + //GistId:ad463bf5f128fe6e6c1485df3c046a4c + Document doc = new Document(getMyDir() + "SmartArt.docx"); + + List shapes = IterableUtils.toList(doc.getChildNodes(NodeType.SHAPE, true)); + int count = (int) shapes.stream().filter(s -> s.hasSmartArt()).count(); + + System.out.println(MessageFormat.format("The document has {0} shapes with SmartArt.", count)); + //ExEnd:DetectSmartArtShape + } + + @Test + public void updateSmartArtDrawing() throws Exception { + Document doc = new Document(getMyDir() + "SmartArt.docx"); + + //ExStart:UpdateSmartArtDrawing + //GistId:683cdbe52b97598d9d4ee4695b4f83c9 + for (Shape shape : (Iterable) doc.getChildNodes(NodeType.SHAPE, true)) + if (shape.hasSmartArt()) + shape.updateSmartArtDrawing(); + //ExEnd:UpdateSmartArtDrawing + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_graphic_elements/WorkingWithWatermark.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_graphic_elements/WorkingWithWatermark.java new file mode 100644 index 00000000..151b04e7 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_graphic_elements/WorkingWithWatermark.java @@ -0,0 +1,168 @@ +package DocsExamples.Programming_with_documents.Working_with_graphic_elements; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Shape; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import javax.imageio.ImageIO; +import java.awt.*; + +@Test +public class WorkingWithWatermark extends DocsExamplesBase { + @Test + public void addTextWatermark() throws Exception { + //ExStart:AddTextWatermark + //GistId:1f690a31c188a851d80d7aed4ff7e44c + Document doc = new Document(getMyDir() + "Document.docx"); + + TextWatermarkOptions options = new TextWatermarkOptions(); + options.setFontFamily("Arial"); + options.setFontSize(36f); + options.setColor(Color.BLACK); + options.setLayout(WatermarkLayout.HORIZONTAL); + options.isSemitrasparent(false); + + doc.getWatermark().setText("Test", options); + + doc.save(getArtifactsDir() + "WorkWithWatermark.AddTextWatermark.docx"); + //ExEnd:AddTextWatermark + } + + @Test + public void addImageWatermark() throws Exception + { + //ExStart:AddImageWatermark + //GistId:1f690a31c188a851d80d7aed4ff7e44c + Document doc = new Document(getMyDir() + "Document.docx"); + + ImageWatermarkOptions options = new ImageWatermarkOptions(); + { + options.setScale(5.0); + options.isWashout(false); + } + + doc.getWatermark().setImage(getImagesDir() + "Transparent background logo.png", options); + + doc.save(getArtifactsDir() + "WorkWithWatermark.AddImageWatermark.docx"); + //ExEnd:AddImageWatermark + } + + @Test + public void removeDocumentWatermark() throws Exception + { + //ExStart:RemoveDocumentWatermark + //GistId:1f690a31c188a851d80d7aed4ff7e44c + Document doc = new Document(); + + // Add a plain text watermark. + doc.getWatermark().setText("Aspose Watermark"); + + // If we wish to edit the text formatting using it as a watermark, + // we can do so by passing a TextWatermarkOptions object when creating the watermark. + TextWatermarkOptions textWatermarkOptions = new TextWatermarkOptions(); + textWatermarkOptions.setFontFamily("Arial"); + textWatermarkOptions.setFontSize(36f); + textWatermarkOptions.setColor(Color.BLACK); + textWatermarkOptions.setLayout(WatermarkLayout.DIAGONAL); + textWatermarkOptions.isSemitrasparent(false); + + doc.getWatermark().setText("Aspose Watermark", textWatermarkOptions); + + doc.save(getArtifactsDir() + "Document.TextWatermark.docx"); + + // We can remove a watermark from a document like this. + if (doc.getWatermark().getType() == WatermarkType.TEXT) + doc.getWatermark().remove(); + + doc.save(getArtifactsDir() + "WorkWithWatermark.RemoveDocumentWatermark.docx"); + //ExEnd:RemoveDocumentWatermark + } + + //ExStart:AddDocumentWatermark + //GistId:1f690a31c188a851d80d7aed4ff7e44c + @Test + public void addAndRemoveWatermark() throws Exception { + Document doc = new Document(getMyDir() + "Document.docx"); + + insertWatermarkText(doc, "CONFIDENTIAL"); + doc.save(getArtifactsDir() + "WorkWithWatermark.AddWatermark.docx"); + + removeWatermarkShape(doc); + doc.save(getArtifactsDir() + "WorkWithWatermark.RemoveWatermark.docx"); + } + + /// + /// Inserts a watermark into a document. + /// + /// The input document. + /// Text of the watermark. + private void insertWatermarkText(Document doc, String watermarkText) throws Exception { + //ExStart:SetShapeName + //GistId:1f690a31c188a851d80d7aed4ff7e44c + // Create a watermark shape, this will be a WordArt shape. + Shape watermark = new Shape(doc, ShapeType.TEXT_PLAIN_TEXT); + watermark.setName("Watermark"); + //ExEnd:SetShapeName + + watermark.getTextPath().setText(watermarkText); + watermark.getTextPath().setFontFamily("Arial"); + watermark.setWidth(500.0); + watermark.setHeight(100.0); + + // Text will be directed from the bottom-left to the top-right corner. + watermark.setRotation(-40); + + // Remove the following two lines if you need a solid black text. + watermark.setFillColor(Color.GRAY); + watermark.setStrokeColor(Color.GRAY); + + // Place the watermark in the page center. + watermark.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE); + watermark.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE); + watermark.setWrapType(WrapType.NONE); + watermark.setVerticalAlignment(VerticalAlignment.CENTER); + watermark.setHorizontalAlignment(HorizontalAlignment.CENTER); + + // Create a new paragraph and append the watermark to this paragraph. + Paragraph watermarkPara = new Paragraph(doc); + watermarkPara.appendChild(watermark); + + // Insert the watermark into all headers of each document section. + for (Section sect : doc.getSections()) { + // There could be up to three different headers in each section. + // Since we want the watermark to appear on all pages, insert it into all headers. + insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_PRIMARY); + insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_FIRST); + insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_EVEN); + } + } + + private void insertWatermarkIntoHeader(Paragraph watermarkPara, Section sect, int headerType) { + HeaderFooter header = sect.getHeadersFooters().getByHeaderFooterType(headerType); + + if (header == null) { + // There is no header of the specified type in the current section, so we need to create it. + header = new HeaderFooter(sect.getDocument(), headerType); + sect.getHeadersFooters().add(header); + } + + // Insert a clone of the watermark into the header. + header.appendChild(watermarkPara.deepClone(true)); + } + //ExEnd:AddDocumentWatermark + + //ExStart:RemoveWatermarkShape + //GistId:1f690a31c188a851d80d7aed4ff7e44c + private void removeWatermarkShape(Document doc) { + for (HeaderFooter hf : (Iterable) doc.getChildNodes(NodeType.HEADER_FOOTER, true)) { + for (Shape shape : (Iterable) hf.getChildNodes(NodeType.SHAPE, true)) { + if (shape.getName().contains("Watermark")) { + shape.remove(); + } + } + } + } + //ExEnd:RemoveWatermarkShape +} + diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_tables/WorkingWithTableStylesAndFormatting.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_tables/WorkingWithTableStylesAndFormatting.java new file mode 100644 index 00000000..7cb26102 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_tables/WorkingWithTableStylesAndFormatting.java @@ -0,0 +1,414 @@ +package DocsExamples.Programming_with_documents.Working_with_tables; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.awt.*; + +@Test +public class WorkingWithTableStylesAndFormatting extends DocsExamplesBase { + @Test + public void distanceBetweenTableSurroundingText() throws Exception { + //ExStart:DistanceBetweenTableSurroundingText + //GistId:0f235c484e5edae70a542ebdaae40fd8 + Document doc = new Document(getMyDir() + "Tables.docx"); + + System.out.println("\nGet distance between table left, right, bottom, top and the surrounding text."); + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + System.out.println(table.getDistanceTop()); + System.out.println(table.getDistanceBottom()); + System.out.println(table.getDistanceRight()); + System.out.println(table.getDistanceLeft()); + //ExEnd:DistanceBetweenTableSurroundingText + } + + @Test + public void applyOutlineBorder() throws Exception { + //ExStart:ApplyOutlineBorder + //GistId:1c794bd06eb1e3b67f0368daa6f23b1f + //ExStart:InlineTablePosition + //GistId:0f235c484e5edae70a542ebdaae40fd8 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + // Align the table to the center of the page. + table.setAlignment(TableAlignment.CENTER); + //ExEnd:InlineTablePosition + // Clear any existing borders from the table. + table.clearBorders(); + + // Set a green border around the table but not inside. + table.setBorder(BorderType.LEFT, LineStyle.SINGLE, 1.5, Color.GREEN, true); + table.setBorder(BorderType.RIGHT, LineStyle.SINGLE, 1.5, Color.GREEN, true); + table.setBorder(BorderType.TOP, LineStyle.SINGLE, 1.5, Color.GREEN, true); + table.setBorder(BorderType.BOTTOM, LineStyle.SINGLE, 1.5, Color.GREEN, true); + + // Fill the cells with a light green solid color. + table.setShading(TextureIndex.TEXTURE_SOLID, Color.lightGray, new Color(0, true)); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.ApplyOutlineBorder.docx"); + //ExEnd:ApplyOutlineBorder + } + + @Test + public void buildTableWithBorders() throws Exception { + //ExStart:BuildTableWithBorders + //GistId:1c794bd06eb1e3b67f0368daa6f23b1f + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + // Clear any existing borders from the table. + table.clearBorders(); + // Set a green border around and inside the table. + table.setBorders(LineStyle.SINGLE, 1.5, Color.GREEN); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.BuildTableWithBorders.docx"); + //ExEnd:BuildTableWithBorders + } + + @Test + public void modifyRowFormatting() throws Exception { + //ExStart:ModifyRowFormatting + //GistId:1c794bd06eb1e3b67f0368daa6f23b1f + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + // Retrieve the first row in the table. + Row firstRow = table.getFirstRow(); + firstRow.getRowFormat().getBorders().setLineStyle(LineStyle.NONE); + firstRow.getRowFormat().setHeightRule(HeightRule.AUTO); + firstRow.getRowFormat().setAllowBreakAcrossPages(true); + //ExEnd:ModifyRowFormatting + } + + @Test + public void applyRowFormatting() throws Exception { + //ExStart:ApplyRowFormatting + //GistId:1c794bd06eb1e3b67f0368daa6f23b1f + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + + RowFormat rowFormat = builder.getRowFormat(); + rowFormat.setHeight(100.0); + rowFormat.setHeightRule(HeightRule.EXACTLY); + + // These formatting properties are set on the table and are applied to all rows in the table. + table.setLeftPadding(30.0); + table.setRightPadding(30.0); + table.setTopPadding(30.0); + table.setBottomPadding(30.0); + + builder.writeln("I'm a wonderful formatted row."); + + builder.endRow(); + builder.endTable(); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.ApplyRowFormatting.docx"); + //ExEnd:ApplyRowFormatting + } + + @Test + public void cellPadding() throws Exception { + //ExStart:CellPadding + //GistId:1c794bd06eb1e3b67f0368daa6f23b1f + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startTable(); + builder.insertCell(); + + // Sets the amount of space (in points) to add to the left/top/right/bottom of the cell's contents. + builder.getCellFormat().setPaddings(30.0, 50.0, 30.0, 50.0); + builder.writeln("I'm a wonderful formatted cell."); + + builder.endRow(); + builder.endTable(); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.CellPadding.docx"); + //ExEnd:CellPadding + } + + /// + /// Shows how to modify formatting of a table cell. + /// + @Test + public void modifyCellFormatting() throws Exception { + //ExStart:ModifyCellFormatting + //GistId:1c794bd06eb1e3b67f0368daa6f23b1f + Document doc = new Document(getMyDir() + "Tables.docx"); + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + Cell firstCell = table.getFirstRow().getFirstCell(); + firstCell.getCellFormat().setWidth(30.0); + firstCell.getCellFormat().setOrientation(TextOrientation.DOWNWARD); + firstCell.getCellFormat().getShading().setForegroundPatternColor(Color.GREEN); + //ExEnd:ModifyCellFormatting + } + + @Test + public void formatTableAndCellWithDifferentBorders() throws Exception { + //ExStart:FormatTableAndCellWithDifferentBorders + //GistId:1c794bd06eb1e3b67f0368daa6f23b1f + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + + // Set the borders for the entire table. + table.setBorders(LineStyle.SINGLE, 2.0, Color.BLACK); + + // Set the cell shading for this cell. + builder.getCellFormat().getShading().setBackgroundPatternColor(Color.RED); + builder.writeln("Cell #1"); + + builder.insertCell(); + + // Specify a different cell shading for the second cell. + builder.getCellFormat().getShading().setBackgroundPatternColor(Color.GREEN); + builder.writeln("Cell #2"); + + builder.endRow(); + + // Clear the cell formatting from previous operations. + builder.getCellFormat().clearFormatting(); + + builder.insertCell(); + + // Create larger borders for the first cell of this row. This will be different + // compared to the borders set for the table. + builder.getCellFormat().getBorders().getLeft().setLineWidth(4.0); + builder.getCellFormat().getBorders().getRight().setLineWidth(4.0); + builder.getCellFormat().getBorders().getTop().setLineWidth(4.0); + builder.getCellFormat().getBorders().getBottom().setLineWidth(4.0); + builder.writeln("Cell #3"); + + builder.insertCell(); + builder.getCellFormat().clearFormatting(); + builder.writeln("Cell #4"); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.FormatTableAndCellWithDifferentBorders.docx"); + //ExEnd:FormatTableAndCellWithDifferentBorders + } + + @Test + public void tableTitleAndDescription() throws Exception { + //ExStart:TableTitleAndDescription + //GistId:7855fd2588b90f4640bf0540285b5277 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + table.setTitle("Test title"); + table.setDescription("Test description"); + + OoxmlSaveOptions options = new OoxmlSaveOptions(); + options.setCompliance(OoxmlCompliance.ISO_29500_2008_STRICT); + + doc.getCompatibilityOptions().optimizeFor(com.aspose.words.MsWordVersion.WORD_2016); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.SetTableTitleAndDescription.docx", options); + //ExEnd:TableTitleAndDescription + } + + @Test + public void allowCellSpacing() throws Exception { + //ExStart:AllowCellSpacing + //GistId:1c794bd06eb1e3b67f0368daa6f23b1f + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + table.setAllowCellSpacing(true); + table.setCellSpacing(2.0); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.AllowCellSpacing.docx"); + //ExEnd:AllowCellSpacing + } + + @Test + public void buildTableWithStyle() throws Exception { + //ExStart:BuildTableWithStyle + //GistId:f1d06175603c48e6dabf5a2eea01207c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + + // We must insert at least one row first before setting any table formatting. + builder.insertCell(); + + // Set the table style used based on the unique style identifier. + table.setStyleIdentifier(StyleIdentifier.MEDIUM_SHADING_1_ACCENT_1); + + // Apply which features should be formatted by the style. + table.setStyleOptions(TableStyleOptions.FIRST_COLUMN | TableStyleOptions.ROW_BANDS | TableStyleOptions.FIRST_ROW); + table.autoFit(AutoFitBehavior.AUTO_FIT_TO_CONTENTS); + + builder.writeln("Item"); + builder.getCellFormat().setRightPadding(40.0); + builder.insertCell(); + builder.writeln("Quantity (kg)"); + builder.endRow(); + + builder.insertCell(); + builder.writeln("Apples"); + builder.insertCell(); + builder.writeln("20"); + builder.endRow(); + + builder.insertCell(); + builder.writeln("Bananas"); + builder.insertCell(); + builder.writeln("40"); + builder.endRow(); + + builder.insertCell(); + builder.writeln("Carrots"); + builder.insertCell(); + builder.writeln("50"); + builder.endRow(); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.BuildTableWithStyle.docx"); + //ExEnd:BuildTableWithStyle + } + + @Test + public void expandFormattingOnCellsAndRowFromStyle() throws Exception { + //ExStart:ExpandFormattingOnCellsAndRowFromStyle + //GistId:f1d06175603c48e6dabf5a2eea01207c + Document doc = new Document(getMyDir() + "Tables.docx"); + + // Get the first cell of the first table in the document. + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + Cell firstCell = table.getFirstRow().getFirstCell(); + + // First print the color of the cell shading. + // This should be empty as the current shading is stored in the table style. + Color cellShadingBefore = firstCell.getCellFormat().getShading().getBackgroundPatternColor(); + System.out.println("Cell shading before style expansion: " + cellShadingBefore); + + doc.expandTableStylesToDirectFormatting(); + + // Now print the cell shading after expanding table styles. + // A blue background pattern color should have been applied from the table style. + Color cellShadingAfter = firstCell.getCellFormat().getShading().getBackgroundPatternColor(); + System.out.println("Cell shading after style expansion: " + cellShadingAfter); + //ExEnd:ExpandFormattingOnCellsAndRowFromStyle + } + + @Test + public void createTableStyle() throws Exception { + //ExStart:CreateTableStyle + //GistId:f1d06175603c48e6dabf5a2eea01207c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + builder.write("Name"); + builder.insertCell(); + builder.write("Value"); + builder.endRow(); + builder.insertCell(); + builder.insertCell(); + builder.endTable(); + + TableStyle tableStyle = (TableStyle) doc.getStyles().add(StyleType.TABLE, "MyTableStyle1"); + tableStyle.getBorders().setLineStyle(LineStyle.DOUBLE); + tableStyle.getBorders().setLineWidth(1.0); + tableStyle.setLeftPadding(18.0); + tableStyle.setRightPadding(18.0); + tableStyle.setTopPadding(12.0); + tableStyle.setBottomPadding(12.0); + + table.setStyle(tableStyle); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.CreateTableStyle.docx"); + //ExEnd:CreateTableStyle + } + + @Test + public void defineConditionalFormatting() throws Exception { + //ExStart:DefineConditionalFormatting + //GistId:f1d06175603c48e6dabf5a2eea01207c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + builder.write("Name"); + builder.insertCell(); + builder.write("Value"); + builder.endRow(); + builder.insertCell(); + builder.insertCell(); + builder.endTable(); + + TableStyle tableStyle = (TableStyle) doc.getStyles().add(StyleType.TABLE, "MyTableStyle1"); + tableStyle.getConditionalStyles().getFirstRow().getShading().setBackgroundPatternColor(Color.yellow); + tableStyle.getConditionalStyles().getFirstRow().getShading().setTexture(TextureIndex.TEXTURE_NONE); + + table.setStyle(tableStyle); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.DefineConditionalFormatting.docx"); + //ExEnd:DefineConditionalFormatting + } + + @Test + public void setTableCellFormatting() throws Exception { + //ExStart:DocumentBuilderSetTableCellFormatting + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startTable(); + builder.insertCell(); + + CellFormat cellFormat = builder.getCellFormat(); + cellFormat.setWidth(250.0); + cellFormat.setLeftPadding(30.0); + cellFormat.setRightPadding(30.0); + cellFormat.setTopPadding(30.0); + cellFormat.setBottomPadding(30.0); + + builder.writeln("I'm a wonderful formatted cell."); + + builder.endRow(); + builder.endTable(); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.DocumentBuilderSetTableCellFormatting.docx"); + //ExEnd:DocumentBuilderSetTableCellFormatting + } + + @Test + public void setTableRowFormatting() throws Exception { + //ExStart:DocumentBuilderSetTableRowFormatting + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + + RowFormat rowFormat = builder.getRowFormat(); + rowFormat.setHeight(100.0); + rowFormat.setHeightRule(HeightRule.EXACTLY); + + // These formatting properties are set on the table and are applied to all rows in the table. + table.setLeftPadding(30.0); + table.setRightPadding(30.0); + table.setTopPadding(30.0); + table.setBottomPadding(30.0); + + builder.writeln("I'm a wonderful formatted row."); + + builder.endRow(); + builder.endTable(); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.DocumentBuilderSetTableRowFormatting.docx"); + //ExEnd:DocumentBuilderSetTableRowFormatting + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_tables/WorkingWithTables.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_tables/WorkingWithTables.java new file mode 100644 index 00000000..9b558a16 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Programming_with_documents/Working_with_tables/WorkingWithTables.java @@ -0,0 +1,1122 @@ +package DocsExamples.Programming_with_documents.Working_with_tables; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import com.aspose.words.net.System.Data.DataColumn; +import com.aspose.words.net.System.Data.DataRow; +import com.aspose.words.net.System.Data.DataSet; +import com.aspose.words.net.System.Data.DataTable; +import org.apache.commons.lang3.StringUtils; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; +import org.testng.annotations.Test; + +import java.awt.*; +import java.io.ByteArrayOutputStream; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; + +@Test +public class WorkingWithTables extends DocsExamplesBase { + @Test + public void removeColumn() throws Exception { + //ExStart:RemoveColumn + //GistId:14f5cea1b896ffd04f143627939e0878 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 1, true); + + Column column = Column.fromIndex(table, 2); + column.remove(); + //ExEnd:RemoveColumn + } + + @Test + public void insertBlankColumn() throws Exception { + //ExStart:InsertBlankColumn + //GistId:14f5cea1b896ffd04f143627939e0878 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + //ExStart:GetPlainText + Column column = Column.fromIndex(table, 0); + // Print the plain text of the column to the screen. + System.out.println(column.toTxt()); + //ExEnd:GetPlainText + + // Create a new column to the left of this column. + // This is the same as using the "Insert Column Before" command in Microsoft Word. + Column newColumn = column.insertColumnBefore(); + + for (Cell cell : newColumn.getColumnCells()) + cell.getFirstParagraph().appendChild(new Run(doc, "Column Text " + newColumn.indexOf(cell))); + //ExEnd:InsertBlankColumn + } + + //ExStart:ColumnClass + //GistId:14f5cea1b896ffd04f143627939e0878 + /// + /// Represents a facade object for a column of a table in a Microsoft Word document. + /// + static class Column { + private Column(Table table, int columnIndex) { + if (table != null) { + mTable = table; + } else { + throw new IllegalArgumentException("table"); + } + + mColumnIndex = columnIndex; + } + + /// + /// Returns a new column facade from the table and supplied zero-based index. + /// + public static Column fromIndex(Table table, int columnIndex) { + return new Column(table, columnIndex); + } + + private ArrayList getCells() { + return getColumnCells(); + } + + /// + /// Returns the index of the given cell in the column. + /// + public int indexOf(Cell cell) { + return getColumnCells().indexOf(cell); + } + + /// + /// Inserts a brand new column before this column into the table. + /// + public Column insertColumnBefore() { + ArrayList columnCells = getCells(); + + if (columnCells.size() == 0) + throw new IllegalArgumentException("Column must not be empty"); + + // Create a clone of this column. + for (Cell cell : columnCells) + cell.getParentRow().insertBefore(cell.deepClone(false), cell); + + // This is the new column. + Column column = new Column(columnCells.get(0).getParentRow().getParentTable(), mColumnIndex); + + // We want to make sure that the cells are all valid to work with (have at least one paragraph). + for (Cell cell : column.getCells()) + cell.ensureMinimum(); + + // Increase the index which this column represents since there is now one extra column in front. + mColumnIndex++; + + return column; + } + + /// + /// Removes the column from the table. + /// + public void remove() { + for (Cell cell : getCells()) + cell.remove(); + } + + /// + /// Returns the text of the column. + /// + public String toTxt() throws Exception { + StringBuilder builder = new StringBuilder(); + + for (Cell cell : getCells()) + builder.append(cell.toString(SaveFormat.TEXT)); + + return builder.toString(); + } + + /// + /// Provides an up-to-date collection of cells which make up the column represented by this facade. + /// + private ArrayList getColumnCells() { + ArrayList columnCells = new ArrayList(); + + for (Row row : mTable.getRows()) { + Cell cell = row.getCells().get(mColumnIndex); + if (cell != null) + columnCells.add(cell); + } + + return columnCells; + } + + private int mColumnIndex; + private Table mTable; + } + //ExEnd:ColumnClass + + @Test + public void autoFitTableToContents() throws Exception { + //ExStart:AutoFitTableToContents + //GistId:1c794bd06eb1e3b67f0368daa6f23b1f + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + table.autoFit(AutoFitBehavior.AUTO_FIT_TO_CONTENTS); + + doc.save(getArtifactsDir() + "WorkingWithTables.AutoFitTableToContents.docx"); + //ExEnd:AutoFitTableToContents + } + + @Test + public void autoFitTableToFixedColumnWidths() throws Exception { + //ExStart:AutoFitTableToFixedColumnWidths + //GistId:1c794bd06eb1e3b67f0368daa6f23b1f + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + // Disable autofitting on this table. + table.autoFit(AutoFitBehavior.FIXED_COLUMN_WIDTHS); + + doc.save(getArtifactsDir() + "WorkingWithTables.AutoFitTableToFixedColumnWidths.docx"); + //ExEnd:AutoFitTableToFixedColumnWidths + } + + @Test + public void autoFitTableToPageWidth() throws Exception { + //ExStart:AutoFitTableToPageWidth + //GistId:1c794bd06eb1e3b67f0368daa6f23b1f + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + // Autofit the first table to the page width. + table.autoFit(AutoFitBehavior.AUTO_FIT_TO_WINDOW); + + doc.save(getArtifactsDir() + "WorkingWithTables.AutoFitTableToWindow.docx"); + //ExEnd:AutoFitTableToPageWidth + } + + @Test + public void buildTableFromDataTable() throws Exception { + //ExStart:BuildTableFromDataTable + //GistId:b5330afb035e842063be7ce93cefe219 + Document doc = new Document(); + // We can position where we want the table to be inserted and specify any extra formatting to the table. + DocumentBuilder builder = new DocumentBuilder(doc); + + // We want to rotate the page landscape as we expect a wide table. + doc.getFirstSection().getPageSetup().setOrientation(Orientation.LANDSCAPE); + + DataSet ds = new DataSet(); + ds.readXml(getMyDir() + "List of people.xml"); + // Retrieve the data from our data source, which is stored as a DataTable. + DataTable dataTable = ds.getTables().get(0); + + // Build a table in the document from the data contained in the DataTable. + Table table = importTableFromDataTable(builder, dataTable, true); + + // We can apply a table style as a very quick way to apply formatting to the entire table. + table.setStyleIdentifier(StyleIdentifier.MEDIUM_LIST_2_ACCENT_1); + table.setStyleOptions(TableStyleOptions.FIRST_ROW | TableStyleOptions.ROW_BANDS | TableStyleOptions.LAST_COLUMN); + + // For our table, we want to remove the heading for the image column. + table.getFirstRow().getLastCell().removeAllChildren(); + + doc.save(getArtifactsDir() + "WorkingWithTables.BuildTableFromDataTable.docx"); + //ExEnd:BuildTableFromDataTable + } + + //ExStart:ImportTableFromDataTable + //GistId:b5330afb035e842063be7ce93cefe219 + /// + /// Imports the content from the specified DataTable into a new Aspose.Words Table object. + /// The table is inserted at the document builder's current position and using the current builder's formatting if any is defined. + /// + public Table importTableFromDataTable(DocumentBuilder builder, DataTable dataTable, + boolean importColumnHeadings) { + Table table = builder.startTable(); + + // Check if the columns' names from the data source are to be included in a header row. + if (importColumnHeadings) { + // Store the original values of these properties before changing them. + boolean boldValue = builder.getFont().getBold(); + int paragraphAlignmentValue = builder.getParagraphFormat().getAlignment(); + + // Format the heading row with the appropriate properties. + builder.getFont().setBold(true); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + + // Create a new row and insert the name of each column into the first row of the table. + for (DataColumn column : dataTable.getColumns()) { + builder.insertCell(); + builder.writeln(column.getColumnName()); + } + + builder.endRow(); + + // Restore the original formatting. + builder.getFont().setBold(boldValue); + builder.getParagraphFormat().setAlignment(paragraphAlignmentValue); + } + + for (DataRow dataRow : (Iterable) dataTable.getRows()) { + for (Object item : dataRow.getItemArray()) { + // Insert a new cell for each object. + builder.insertCell(); + + switch (item.getClass().getName()) { + case "DateTime": + // Define a custom format for dates and times. + Date dateTime = (Date) item; + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MMMM d, yyyy"); + builder.write(simpleDateFormat.format(dateTime)); + break; + default: + // By default any other item will be inserted as text. + builder.write(item.toString()); + break; + } + } + + // After we insert all the data from the current record, we can end the table row. + builder.endRow(); + } + + // We have finished inserting all the data from the DataTable, we can end the table. + builder.endTable(); + + return table; + } + //ExEnd:ImportTableFromDataTable + + @Test + public void cloneCompleteTable() throws Exception { + //ExStart:CloneCompleteTable + //GistId:68616fbf7f092a743b66d4491578d18c + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + // Clone the table and insert it into the document after the original. + Table tableClone = (Table) table.deepClone(true); + table.getParentNode().insertAfter(tableClone, table); + + // Insert an empty paragraph between the two tables, + // or else they will be combined into one upon saving this has to do with document validation. + table.getParentNode().insertAfter(new Paragraph(doc), table); + + doc.save(getArtifactsDir() + "WorkingWithTables.CloneCompleteTable.docx"); + //ExEnd:CloneCompleteTable + } + + @Test + public void cloneLastRow() throws Exception { + //ExStart:CloneLastRow + //GistId:68616fbf7f092a743b66d4491578d18c + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + Row clonedRow = (Row) table.getLastRow().deepClone(true); + // Remove all content from the cloned row's cells. This makes the row ready for new content to be inserted into. + for (Cell cell : clonedRow.getCells()) + cell.removeAllChildren(); + + table.appendChild(clonedRow); + + doc.save(getArtifactsDir() + "WorkingWithTables.CloneLastRow.docx"); + //ExEnd:CloneLastRow + } + + @Test + public void findingIndex() throws Exception { + Document doc = new Document(getMyDir() + "Tables.docx"); + + //ExStart:RetrieveTableIndex + //GistId:14f5cea1b896ffd04f143627939e0878 + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + NodeCollection allTables = doc.getChildNodes(NodeType.TABLE, true); + int tableIndex = allTables.indexOf(table); + //ExEnd:RetrieveTableIndex + System.out.println("\nTable index is " + tableIndex); + + //ExStart:RetrieveRowIndex + //GistId:14f5cea1b896ffd04f143627939e0878 + int rowIndex = table.indexOf(table.getLastRow()); + //ExEnd:RetrieveRowIndex + System.out.println("\nRow index is " + rowIndex); + + Row row = table.getLastRow(); + //ExStart:RetrieveCellIndex + //GistId:14f5cea1b896ffd04f143627939e0878 + int cellIndex = row.indexOf(row.getCells().get(4)); + //ExEnd:RetrieveCellIndex + System.out.println("\nCell index is " + cellIndex); + } + + @Test + public void insertTableDirectly() throws Exception { + //ExStart:InsertTableDirectly + //GistId:68616fbf7f092a743b66d4491578d18c + Document doc = new Document(); + + // We start by creating the table object. Note that we must pass the document object + // to the constructor of each node. This is because every node we create must belong + // to some document. + Table table = new Table(doc); + doc.getFirstSection().getBody().appendChild(table); + + // Here we could call EnsureMinimum to create the rows and cells for us. This method is used + // to ensure that the specified node is valid. In this case, a valid table should have at least one Row and one cell. + + // Instead, we will handle creating the row and table ourselves. + // This would be the best way to do this if we were creating a table inside an algorithm. + Row row = new Row(doc); + row.getRowFormat().setAllowBreakAcrossPages(true); + table.appendChild(row); + + Cell cell = new Cell(doc); + cell.getCellFormat().getShading().setBackgroundPatternColor(Color.BLUE); + cell.getCellFormat().setWidth(80.0); + cell.appendChild(new Paragraph(doc)); + cell.getFirstParagraph().appendChild(new Run(doc, "Row 1, Cell 1 Text")); + + row.appendChild(cell); + + // We would then repeat the process for the other cells and rows in the table. + // We can also speed things up by cloning existing cells and rows. + row.appendChild(cell.deepClone(false)); + row.getLastCell().appendChild(new Paragraph(doc)); + row.getLastCell().getFirstParagraph().appendChild(new Run(doc, "Row 1, Cell 2 Text")); + + // We can now apply any auto fit settings. + table.autoFit(AutoFitBehavior.FIXED_COLUMN_WIDTHS); + + doc.save(getArtifactsDir() + "WorkingWithTables.InsertTableDirectly.docx"); + //ExEnd:InsertTableDirectly + } + + @Test + public void insertTableFromHtml() throws Exception { + //ExStart:InsertTableFromHtml + //GistId:68616fbf7f092a743b66d4491578d18c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Note that AutoFitSettings does not apply to tables inserted from HTML. + builder.insertHtml("
          " + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "
          Row 1, Cell 1Row 1, Cell 2
          Row 2, Cell 2Row 2, Cell 2
          "); + + doc.save(getArtifactsDir() + "WorkingWithTables.InsertTableFromHtml.docx"); + //ExEnd:InsertTableFromHtml + } + + @Test + public void createSimpleTable() throws Exception { + //ExStart:CreateSimpleTable + //GistId:68616fbf7f092a743b66d4491578d18c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Start building the table. + builder.startTable(); + builder.insertCell(); + builder.write("Row 1, Cell 1 Content."); + + // Build the second cell. + builder.insertCell(); + builder.write("Row 1, Cell 2 Content."); + + // Call the following method to end the row and start a new row. + builder.endRow(); + + // Build the first cell of the second row. + builder.insertCell(); + builder.write("Row 2, Cell 1 Content"); + + // Build the second cell. + builder.insertCell(); + builder.write("Row 2, Cell 2 Content."); + builder.endRow(); + + // Signal that we have finished building the table. + builder.endTable(); + + doc.save(getArtifactsDir() + "WorkingWithTables.CreateSimpleTable.docx"); + //ExEnd:CreateSimpleTable + } + + @Test + public void formattedTable() throws Exception { + //ExStart:FormattedTable + //GistId:68616fbf7f092a743b66d4491578d18c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + + // Table wide formatting must be applied after at least one row is present in the table. + table.setLeftIndent(20.0); + + // Set height and define the height rule for the header row. + builder.getRowFormat().setHeight(40.0); + builder.getRowFormat().setHeightRule(HeightRule.AT_LEAST); + + builder.getCellFormat().getShading().setBackgroundPatternColor(new Color((198), (217), (241))); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.getFont().setSize(16.0); + builder.getFont().setName("Arial"); + builder.getFont().setBold(true); + + builder.getCellFormat().setWidth(100.0); + builder.write("Header Row,\n Cell 1"); + + // We don't need to specify this cell's width because it's inherited from the previous cell. + builder.insertCell(); + builder.write("Header Row,\n Cell 2"); + + builder.insertCell(); + builder.getCellFormat().setWidth(200.0); + builder.write("Header Row,\n Cell 3"); + builder.endRow(); + + builder.getCellFormat().getShading().setBackgroundPatternColor(Color.WHITE); + builder.getCellFormat().setWidth(100.0); + builder.getCellFormat().setVerticalAlignment(CellVerticalAlignment.CENTER); + + // Reset height and define a different height rule for table body. + builder.getRowFormat().setHeight(30.0); + builder.getRowFormat().setHeightRule(HeightRule.AUTO); + builder.insertCell(); + + // Reset font formatting. + builder.getFont().setSize(12.0); + builder.getFont().setBold(false); + + builder.write("Row 1, Cell 1 Content"); + builder.insertCell(); + builder.write("Row 1, Cell 2 Content"); + + builder.insertCell(); + builder.getCellFormat().setWidth(200.0); + builder.write("Row 1, Cell 3 Content"); + builder.endRow(); + + builder.insertCell(); + builder.getCellFormat().setWidth(100.0); + builder.write("Row 2, Cell 1 Content"); + + builder.insertCell(); + builder.write("Row 2, Cell 2 Content"); + + builder.insertCell(); + builder.getCellFormat().setWidth(200.0); + builder.write("Row 2, Cell 3 Content."); + builder.endRow(); + builder.endTable(); + + doc.save(getArtifactsDir() + "WorkingWithTables.FormattedTable.docx"); + //ExEnd:FormattedTable + } + + @Test + public void nestedTable() throws Exception { + //ExStart:NestedTable + //GistId:68616fbf7f092a743b66d4491578d18c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Cell cell = builder.insertCell(); + builder.writeln("Outer Table Cell 1"); + + builder.insertCell(); + builder.writeln("Outer Table Cell 2"); + + // This call is important to create a nested table within the first table. + // Without this call, the cells inserted below will be appended to the outer table. + builder.endTable(); + + // Move to the first cell of the outer table. + builder.moveTo(cell.getFirstParagraph()); + + // Build the inner table. + builder.insertCell(); + builder.writeln("Inner Table Cell 1"); + builder.insertCell(); + builder.writeln("Inner Table Cell 2"); + builder.endTable(); + + doc.save(getArtifactsDir() + "WorkingWithTables.NestedTable.docx"); + //ExEnd:NestedTable + } + + @Test + public void combineRows() throws Exception { + //ExStart:CombineRows + //GistId:89807559333317718ba2e6084fdcb3e2 + Document doc = new Document(getMyDir() + "Tables.docx"); + + // The rows from the second table will be appended to the end of the first table. + Table firstTable = (Table) doc.getChild(NodeType.TABLE, 0, true); + Table secondTable = (Table) doc.getChild(NodeType.TABLE, 1, true); + + // Append all rows from the current table to the next tables + // with different cell count and widths can be joined into one table. + while (secondTable.hasChildNodes()) + firstTable.getRows().add(secondTable.getFirstRow()); + + secondTable.remove(); + + doc.save(getArtifactsDir() + "WorkingWithTables.CombineRows.docx"); + //ExEnd:CombineRows + } + + @Test + public void splitTable() throws Exception { + //ExStart:SplitTable + //GistId:ff5affdcea04dcd20d1b872f9503dbfe + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table firstTable = (Table) doc.getChild(NodeType.TABLE, 0, true); + + // We will split the table at the third row (inclusive). + Row row = firstTable.getRows().get(2); + // Create a new container for the split table. + Table table = (Table) firstTable.deepClone(false); + // Insert the container after the original. + firstTable.getParentNode().insertAfter(table, firstTable); + // Add a buffer paragraph to ensure the tables stay apart. + firstTable.getParentNode().insertAfter(new Paragraph(doc), firstTable); + + Row currentRow; + do { + currentRow = firstTable.getLastRow(); + table.prependChild(currentRow); + } while (currentRow != row); + + doc.save(getArtifactsDir() + "WorkingWithTables.SplitTable.docx"); + //ExEnd:SplitTable + } + + @Test + public void rowFormatDisableBreakAcrossPages() throws Exception { + //ExStart:RowFormatDisableBreakAcrossPages + //GistId:14f5cea1b896ffd04f143627939e0878 + Document doc = new Document(getMyDir() + "Table spanning two pages.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + // Disable breaking across pages for all rows in the table. + for (Row row : table.getRows()) + row.getRowFormat().setAllowBreakAcrossPages(false); + + doc.save(getArtifactsDir() + "WorkingWithTables.RowFormatDisableBreakAcrossPages.docx"); + //ExEnd:RowFormatDisableBreakAcrossPages + } + + @Test + public void keepTableTogether() throws Exception { + //ExStart:KeepTableTogether + //GistId:14f5cea1b896ffd04f143627939e0878 + Document doc = new Document(getMyDir() + "Table spanning two pages.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + // We need to enable KeepWithNext for every paragraph in the table to keep it from breaking across a page, + // except for the last paragraphs in the last row of the table. + for (Cell cell : (Iterable) table.getChildNodes(NodeType.CELL, true)) { + cell.ensureMinimum(); + + for (Paragraph para : cell.getParagraphs()) + if (!(cell.getParentRow().isLastRow() && para.isEndOfCell())) + para.getParagraphFormat().setKeepWithNext(true); + } + + doc.save(getArtifactsDir() + "WorkingWithTables.KeepTableTogether.docx"); + //ExEnd:KeepTableTogether + } + + @Test + public void checkCellsMerged() throws Exception { + //ExStart:CheckCellsMerged + //GistId:4fe6fda3615c0c441401e2131533d93b + Document doc = new Document(getMyDir() + "Table with merged cells.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + for (Row row : table.getRows()) { + for (Cell cell : row.getCells()) { + System.out.println(printCellMergeType(cell)); + } + } + //ExEnd:CheckCellsMerged + } + + //ExStart:PrintCellMergeType + public String printCellMergeType(Cell cell) { + boolean isHorizontallyMerged = cell.getCellFormat().getHorizontalMerge() != CellMerge.NONE; + boolean isVerticallyMerged = cell.getCellFormat().getVerticalMerge() != CellMerge.NONE; + + String cellLocation = + MessageFormat.format("R{0}, C{1}", cell.getParentRow().getParentTable().indexOf(cell.getParentRow()) + 1, cell.getParentRow().indexOf(cell) + 1); + + if (isHorizontallyMerged && isVerticallyMerged) + return MessageFormat.format("The cell at {0} is both horizontally and vertically merged", cellLocation); + + if (isHorizontallyMerged) + return MessageFormat.format("The cell at {0} is horizontally merged.", cellLocation); + + if (isVerticallyMerged) + return MessageFormat.format("The cell at {0} is vertically merged", cellLocation); + + return MessageFormat.format("The cell at {0} is not merged", cellLocation); + } + //ExEnd:PrintCellMergeType + + @Test + public void verticalMerge() throws Exception { + //ExStart:VerticalMerge + //GistId:4fe6fda3615c0c441401e2131533d93b + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertCell(); + builder.getCellFormat().setVerticalMerge(CellMerge.FIRST); + builder.write("Text in merged cells."); + + builder.insertCell(); + builder.getCellFormat().setVerticalMerge(CellMerge.NONE); + builder.write("Text in one cell"); + builder.endRow(); + + builder.insertCell(); + // This cell is vertically merged to the cell above and should be empty. + builder.getCellFormat().setVerticalMerge(CellMerge.PREVIOUS); + + builder.insertCell(); + builder.getCellFormat().setVerticalMerge(CellMerge.NONE); + builder.write("Text in another cell"); + builder.endRow(); + builder.endTable(); + + doc.save(getArtifactsDir() + "WorkingWithTables.VerticalMerge.docx"); + //ExEnd:VerticalMerge + } + + @Test + public void horizontalMerge() throws Exception { + //ExStart:HorizontalMerge + //GistId:4fe6fda3615c0c441401e2131533d93b + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertCell(); + builder.getCellFormat().setHorizontalMerge(CellMerge.FIRST); + builder.write("Text in merged cells."); + + builder.insertCell(); + // This cell is merged to the previous and should be empty. + builder.getCellFormat().setHorizontalMerge(CellMerge.PREVIOUS); + builder.endRow(); + + builder.insertCell(); + builder.getCellFormat().setHorizontalMerge(CellMerge.NONE); + builder.write("Text in one cell."); + + builder.insertCell(); + builder.write("Text in another cell."); + builder.endRow(); + builder.endTable(); + + doc.save(getArtifactsDir() + "WorkingWithTables.HorizontalMerge.docx"); + //ExEnd:HorizontalMerge + } + + @Test + public void mergeCellRange() throws Exception { + //ExStart:MergeCellRange + //GistId:4fe6fda3615c0c441401e2131533d93b + Document doc = new Document(getMyDir() + "Table with merged cells.docx"); + + Table table = doc.getFirstSection().getBody().getTables().get(0); + + // We want to merge the range of cells found inbetween these two cells. + Cell cellStartRange = table.getRows().get(0).getCells().get(0); + Cell cellEndRange = table.getRows().get(1).getCells().get(1); + + // Merge all the cells between the two specified cells into one. + mergeCells(cellStartRange, cellEndRange); + + doc.save(getArtifactsDir() + "WorkingWithTables.MergeCellRange.docx"); + //ExEnd:MergeCellRange + } + + @Test + public void printHorizontalAndVerticalMerged() throws Exception { + //ExStart:PrintHorizontalAndVerticalMerged + //GistId:4fe6fda3615c0c441401e2131533d93b + Document doc = new Document(getMyDir() + "Table with merged cells.docx"); + + SpanVisitor visitor = new SpanVisitor(doc); + doc.accept(visitor); + //ExEnd:PrintHorizontalAndVerticalMerged + } + + @Test + public void convertToHorizontallyMergedCells() throws Exception { + //ExStart:ConvertToHorizontallyMergedCells + //GistId:4fe6fda3615c0c441401e2131533d93b + Document doc = new Document(getMyDir() + "Table with merged cells.docx"); + + Table table = doc.getFirstSection().getBody().getTables().get(0); + // Now merged cells have appropriate merge flags. + table.convertToHorizontallyMergedCells(); + //ExEnd:ConvertToHorizontallyMergedCells + } + + //ExStart:MergeCells + //GistId:4fe6fda3615c0c441401e2131533d93b + void mergeCells(Cell startCell, Cell endCell) { + Table parentTable = startCell.getParentRow().getParentTable(); + + // Find the row and cell indices for the start and end cell. + Point startCellPos = new Point(startCell.getParentRow().indexOf(startCell), + parentTable.indexOf(startCell.getParentRow())); + Point endCellPos = new Point(endCell.getParentRow().indexOf(endCell), parentTable.indexOf(endCell.getParentRow())); + + // Create a range of cells to be merged based on these indices. + // Inverse each index if the end cell is before the start cell. + Rectangle mergeRange = new Rectangle(Math.min(startCellPos.x, endCellPos.y), + Math.min(startCellPos.y, endCellPos.y), + Math.abs(endCellPos.x - startCellPos.x) + 1, Math.abs(endCellPos.y - startCellPos.y) + 1); + + for (Row row : parentTable.getRows()) { + for (Cell cell : row.getCells()) { + Point currentPos = new Point(row.indexOf(cell), parentTable.indexOf(row)); + + // Check if the current cell is inside our merge range, then merge it. + if (mergeRange.contains(currentPos)) { + cell.getCellFormat().setHorizontalMerge(currentPos.x == mergeRange.getX() ? CellMerge.FIRST : CellMerge.PREVIOUS); + + cell.getCellFormat().setVerticalMerge(currentPos.y == mergeRange.getY() ? CellMerge.FIRST : CellMerge.PREVIOUS); + } + } + } + } + //ExEnd:MergeCells + + //ExStart:HorizontalAndVerticalMergeHelperClasses + //GistId:4fe6fda3615c0c441401e2131533d93b + /// + /// Helper class that contains collection of rowinfo for each row. + /// + public static class TableInfo { + public ArrayList getRows() { + return mRows; + } + + private ArrayList mRows = new ArrayList<>(); + } + + /// + /// Helper class that contains collection of cellinfo for each cell. + /// + public static class RowInfo { + public ArrayList getCells() { + return mCells; + } + + ; + + private ArrayList mCells = new ArrayList<>(); + } + + /// + /// Helper class that contains info about cell. currently here is only colspan and rowspan. + /// + public static class CellInfo { + public CellInfo(int colSpan, int rowSpan) { + mColSpan = colSpan; + mRowSpan = rowSpan; + } + + public int getColSpan() { + return mColSpan; + } + + ; + + private int mColSpan; + + public int getRowSpan() { + return mRowSpan; + } + + ; + + private int mRowSpan; + } + + public static class SpanVisitor extends DocumentVisitor { + /// + /// Creates new SpanVisitor instance. + /// + /// + /// Is document which we should parse. + /// + public SpanVisitor(Document doc) throws Exception { + mWordTables = doc.getChildNodes(NodeType.TABLE, true); + + // We will parse HTML to determine the rowspan and colspan of each cell. + ByteArrayOutputStream htmlStream = new ByteArrayOutputStream(); + + HtmlSaveOptions options = new HtmlSaveOptions(); + options.setImagesFolder(System.getProperty("java.io.tmpdir")); + + doc.save(htmlStream, options); + + // Load HTML into the XML document. + org.jsoup.nodes.Document document = Jsoup.parse(htmlStream.toString()); + + // Get collection of tables in the HTML document. + Elements tables = document.getElementsByTag("table"); + + for (Element table : tables) { + TableInfo tableInf = new TableInfo(); + + // Get collection of rows in the table. + Elements rows = table.getElementsByTag("tr"); + + for (Element row : rows) { + RowInfo rowInf = new RowInfo(); + + // Get collection of cells. + Elements cells = row.getElementsByTag("td"); + + for (Element cell : cells) { + // Determine row span and colspan of the current cell. + String colSpanAttr = cell.attributes().get("colspan"); + String rowSpanAttr = cell.attributes().get("rowspan"); + + int colSpan = StringUtils.isNotBlank(colSpanAttr) ? Integer.parseInt(colSpanAttr) : 0; + int rowSpan = StringUtils.isNotBlank(rowSpanAttr) ? Integer.parseInt(rowSpanAttr) : 0; + + CellInfo cellInf = new CellInfo(colSpan, rowSpan); + rowInf.getCells().add(cellInf); + } + + tableInf.getRows().add(rowInf); + } + + mTables.add(tableInf); + } + } + + public int visitCellStart(Cell cell) { + int tabIdx = mWordTables.indexOf(cell.getParentRow().getParentTable()); + int rowIdx = cell.getParentRow().getParentTable().indexOf(cell.getParentRow()); + int cellIdx = cell.getParentRow().indexOf(cell); + + int colSpan = 0; + int rowSpan = 0; + if (tabIdx < mTables.size() && + rowIdx < mTables.get(tabIdx).getRows().size() && + cellIdx < mTables.get(tabIdx).getRows().get(rowIdx).getCells().size()) { + colSpan = mTables.get(tabIdx).getRows().get(rowIdx).getCells().get(cellIdx).getColSpan(); + rowSpan = mTables.get(tabIdx).getRows().get(rowIdx).getCells().get(cellIdx).getRowSpan(); + } + + System.out.println(MessageFormat.format("{0}.{1}.{2} colspan={3}\t rowspan={4}", tabIdx, rowIdx, cellIdx, colSpan, rowSpan)); + + return VisitorAction.CONTINUE; + } + + private ArrayList mTables = new ArrayList<>(); + private NodeCollection mWordTables; + } + //ExEnd:HorizontalAndVerticalMergeHelperClasses + + @Test + public void repeatRowsOnSubsequentPages() throws Exception { + //ExStart:RepeatRowsOnSubsequentPages + //GistId:14f5cea1b896ffd04f143627939e0878 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startTable(); + builder.getRowFormat().setHeadingFormat(true); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.getCellFormat().setWidth(100.0); + builder.insertCell(); + builder.writeln("Heading row 1"); + builder.endRow(); + builder.insertCell(); + builder.writeln("Heading row 2"); + builder.endRow(); + + builder.getCellFormat().setWidth(50.0); + builder.getParagraphFormat().clearFormatting(); + + for (int i = 0; i < 50; i++) { + builder.insertCell(); + builder.getRowFormat().setHeadingFormat(false); + builder.write("Column 1 Text"); + builder.insertCell(); + builder.write("Column 2 Text"); + builder.endRow(); + } + + doc.save(getArtifactsDir() + "WorkingWithTables.RepeatRowsOnSubsequentPages.docx"); + //ExEnd:RepeatRowsOnSubsequentPages + } + + @Test + public void autoFitPageWidth() throws Exception { + //ExStart:AutoFitPageWidth + //GistId:1c794bd06eb1e3b67f0368daa6f23b1f + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a table with a width that takes up half the page width. + Table table = builder.startTable(); + + builder.insertCell(); + table.setPreferredWidth(PreferredWidth.fromPercent(50.0)); + builder.writeln("Cell #1"); + + builder.insertCell(); + builder.writeln("Cell #2"); + + builder.insertCell(); + builder.writeln("Cell #3"); + + doc.save(getArtifactsDir() + "WorkingWithTables.AutoFitToPageWidth.docx"); + //ExEnd:AutoFitPageWidth + } + + @Test + public void preferredWidthSettings() throws Exception { + //ExStart:PreferredWidthSettings + //GistId:1c794bd06eb1e3b67f0368daa6f23b1f + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a table row made up of three cells which have different preferred widths. + // Insert an absolute sized cell. + builder.insertCell(); + builder.getCellFormat().setPreferredWidth(PreferredWidth.fromPoints(40.0)); + builder.getCellFormat().getShading().setBackgroundPatternColor(Color.YELLOW); + builder.writeln("Cell at 40 points width"); + + // Insert a relative (percent) sized cell. + builder.insertCell(); + builder.getCellFormat().setPreferredWidth(PreferredWidth.fromPercent(20.0)); + builder.getCellFormat().getShading().setBackgroundPatternColor(Color.BLUE); + builder.writeln("Cell at 20% width"); + + // Insert a auto sized cell. + builder.insertCell(); + builder.getCellFormat().setPreferredWidth(PreferredWidth.AUTO); + builder.getCellFormat().getShading().setBackgroundPatternColor(Color.GREEN); + builder.writeln( + "Cell automatically sized. The size of this cell is calculated from the table preferred width."); + builder.writeln("In this case the cell will fill up the rest of the available space."); + + doc.save(getArtifactsDir() + "WorkingWithTables.PreferredWidthSettings.docx"); + //ExEnd:PreferredWidthSettings + } + + @Test + public void retrievePreferredWidthType() throws Exception { + //ExStart:RetrievePreferredWidthType + //GistId:1c794bd06eb1e3b67f0368daa6f23b1f + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + //ExStart:AllowAutoFit + //GistId:1c794bd06eb1e3b67f0368daa6f23b1f + table.setAllowAutoFit(true); + //ExEnd:AllowAutoFit + + Cell firstCell = table.getFirstRow().getFirstCell(); + int type = firstCell.getCellFormat().getPreferredWidth().getType(); + double value = firstCell.getCellFormat().getPreferredWidth().getValue(); + //ExEnd:RetrievePreferredWidthType + } + + @Test + public void getTablePosition() throws Exception { + //ExStart:GetTablePosition + //GistId:0f235c484e5edae70a542ebdaae40fd8 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + if (table.getTextWrapping() == TextWrapping.AROUND) { + System.out.println(table.getRelativeHorizontalAlignment()); + System.out.println(table.getRelativeVerticalAlignment()); + } else { + System.out.println(table.getAlignment()); + } + //ExEnd:GetTablePosition + } + + @Test + public void getFloatingTablePosition() throws Exception { + //ExStart:GetFloatingTablePosition + //GistId:0f235c484e5edae70a542ebdaae40fd8 + Document doc = new Document(getMyDir() + "Table wrapped by text.docx"); + + for (Table table : doc.getFirstSection().getBody().getTables()) { + // If the table is floating type, then print its positioning properties. + if (table.getTextWrapping() == TextWrapping.AROUND) { + System.out.println(table.getHorizontalAnchor()); + System.out.println(table.getVerticalAnchor()); + System.out.println(table.getAbsoluteHorizontalDistance()); + System.out.println(table.getAbsoluteVerticalDistance()); + System.out.println(table.getAllowOverlap()); + System.out.println(table.getAbsoluteHorizontalDistance()); + System.out.println(table.getRelativeVerticalAlignment()); + System.out.println(".............................."); + } + } + //ExEnd:GetFloatingTablePosition + } + + @Test + public void floatingTablePosition() throws Exception { + //ExStart:FloatingTablePosition + //GistId:0f235c484e5edae70a542ebdaae40fd8 + Document doc = new Document(getMyDir() + "Table wrapped by text.docx"); + + Table table = doc.getFirstSection().getBody().getTables().get(0); + table.setAbsoluteHorizontalDistance(10.0); + table.setRelativeVerticalAlignment(VerticalAlignment.CENTER); + + doc.save(getArtifactsDir() + "WorkingWithTables.FloatingTablePosition.docx"); + //ExEnd:FloatingTablePosition + } + + @Test + public void relativeHorizontalOrVerticalPosition() throws Exception { + //ExStart:RelativeHorizontalOrVerticalPosition + //GistId:0f235c484e5edae70a542ebdaae40fd8 + Document doc = new Document(getMyDir() + "Table wrapped by text.docx"); + + Table table = doc.getFirstSection().getBody().getTables().get(0); + table.setHorizontalAnchor(RelativeHorizontalPosition.COLUMN); + table.setVerticalAnchor(RelativeVerticalPosition.PAGE); + + doc.save(getArtifactsDir() + "WorkingWithTables.RelativeHorizontalOrVerticalPosition.docx"); + //ExEnd:RelativeHorizontalOrVerticalPosition + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Rendering_and_printing/Complex_examples_and_helpers/EnumerateLayoutElements.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Rendering_and_printing/Complex_examples_and_helpers/EnumerateLayoutElements.java new file mode 100644 index 00000000..1e02582b --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Rendering_and_printing/Complex_examples_and_helpers/EnumerateLayoutElements.java @@ -0,0 +1,177 @@ +package DocsExamples.Rendering_and_printing.Complex_examples_and_helpers; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.apache.commons.lang3.StringUtils; +import org.testng.annotations.Test; + +import javax.imageio.ImageIO; +import java.awt.Stroke; +import java.awt.*; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.io.File; +import java.text.MessageFormat; + +@Test +public class EnumerateLayoutElements extends DocsExamplesBase { + @Test + public void getLayoutElements() throws Exception { + Document doc = new Document(getMyDir() + "Document layout.docx"); + + // Enumerator which is used to "walk" the elements of a rendered document. + LayoutEnumerator layoutEnumerator = new LayoutEnumerator(doc); + + // Use the enumerator to write information about each layout element to the console. + LayoutInfoWriter.run(layoutEnumerator); + + // Adds a border around each layout element and saves each page as a JPEG image to the data directory. + OutlineLayoutEntitiesRenderer.run(doc, layoutEnumerator, getArtifactsDir()); + } +} + +class LayoutInfoWriter { + public static void run(LayoutEnumerator layoutEnumerator) throws Exception { + displayLayoutElements(layoutEnumerator, ""); + } + + /// + /// Enumerates forward through each layout element in the document and prints out details of each element. + /// + private static void displayLayoutElements(LayoutEnumerator layoutEnumerator, String padding) throws Exception { + do { + displayEntityInfo(layoutEnumerator, padding); + + if (layoutEnumerator.moveFirstChild()) { + // Recurse into this child element. + displayLayoutElements(layoutEnumerator, addPadding(padding)); + layoutEnumerator.moveParent(); + } + } while (layoutEnumerator.moveNext()); + } + + /// + /// Displays information about the current layout entity to the console. + /// + private static void displayEntityInfo(LayoutEnumerator layoutEnumerator, String padding) throws Exception { + System.out.print(padding + layoutEnumerator.getType() + " - " + layoutEnumerator.getKind()); + + if (layoutEnumerator.getType() == LayoutEntityType.SPAN) + System.out.print(" - " + layoutEnumerator.getText()); + + System.out.println(); + } + + /// + /// Returns a string of spaces for padding purposes. + /// + private static String addPadding(String padding) { + return padding + StringUtils.repeat(' ', 4); + } +} + +class OutlineLayoutEntitiesRenderer { + public static void run(Document doc, LayoutEnumerator layoutEnumerator, String folderPath) throws Exception { + // Make sure the enumerator is at the beginning of the document. + layoutEnumerator.reset(); + + for (int pageIndex = 0; pageIndex < doc.getPageCount(); pageIndex++) { + // Use the document class to find information about the current page. + PageInfo pageInfo = doc.getPageInfo(pageIndex); + + final float RESOLUTION = 150.0f; + Dimension pageSize = pageInfo.getSizeInPixels(1.0f, RESOLUTION); + + BufferedImage image = new BufferedImage(pageSize.width, pageSize.height, BufferedImage.TYPE_INT_ARGB); + + Graphics2D graphics = image.createGraphics(); + try { + // Make the background white. + graphics.setBackground(Color.WHITE); + graphics.clearRect(0, 0, image.getWidth(), image.getHeight()); + + // Render the page to the graphics. + doc.renderToScale(pageIndex, graphics, 0.0f, 0.0f, 1.0f); + + // Add an outline around each element on the page using the graphics object. + addBoundingBoxToElementsOnPage(layoutEnumerator, graphics); + + // Move the enumerator to the next page if there is one. + layoutEnumerator.moveNext(); + + ImageIO.write(image, "png", new File(folderPath + MessageFormat.format("EnumerateLayoutElements.Page_{0}.png", pageIndex + 1))); + } finally { + if (graphics != null) graphics.dispose(); + } + } + } + + /// + /// Adds a colored border around each layout element on the page. + /// + private static void addBoundingBoxToElementsOnPage(LayoutEnumerator layoutEnumerator, Graphics2D graphics) throws Exception { + do { + // Use MoveLastChild and MovePrevious to enumerate from last to the first enumeration is done backward, + // so the lines of child entities are drawn first and don't overlap the parent's lines. + if (layoutEnumerator.moveLastChild()) { + addBoundingBoxToElementsOnPage(layoutEnumerator, graphics); + layoutEnumerator.moveParent(); + } + + Stroke stroke1 = new BasicStroke(1f); + graphics.setColor(getColorFromType(layoutEnumerator.getType())); + graphics.setStroke(stroke1); + + // Convert the rectangle representing the position of the layout entity on the page from points to pixels. + // Draw a line around the layout entity on the page. + Rectangle2D.Float rectF = layoutEnumerator.getRectangle(); + graphics.drawRect((int) rectF.getX(), (int) rectF.getY(), (int) rectF.getWidth(), (int) rectF.getHeight()); + + // Stop after all elements on the page have been processed. + if (layoutEnumerator.getType() == LayoutEntityType.PAGE) + return; + } while (layoutEnumerator.movePrevious()); + } + + /// + /// Returns a different colored pen for each entity type. + /// + private static Color getColorFromType(int type) { + switch (type) { + case LayoutEntityType.CELL: + return Color.PINK; + case LayoutEntityType.COLUMN: + return Color.green; + case LayoutEntityType.COMMENT: + return Color.CYAN; + case LayoutEntityType.ENDNOTE: + return Color.lightGray; + case LayoutEntityType.FOOTNOTE: + return Color.lightGray; + case LayoutEntityType.HEADER_FOOTER: + return Color.DARK_GRAY; + case LayoutEntityType.LINE: + return Color.blue; + case LayoutEntityType.NOTE_SEPARATOR: + return Color.magenta; + case LayoutEntityType.PAGE: + return Color.RED; + case LayoutEntityType.ROW: + return Color.orange; + case LayoutEntityType.SPAN: + return Color.RED; + case LayoutEntityType.TEXT_BOX: + return Color.yellow; + default: + return Color.RED; + } + } + + /// + /// Converts a value in points to pixels. + /// + private static int pointToPixel(float value, double resolution) { + return (int) ConvertUtil.pointToPixel(value, resolution); + } +} + diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Rendering_and_printing/Complex_examples_and_helpers/PageLayoutHelper.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Rendering_and_printing/Complex_examples_and_helpers/PageLayoutHelper.java new file mode 100644 index 00000000..c886a7af --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Rendering_and_printing/Complex_examples_and_helpers/PageLayoutHelper.java @@ -0,0 +1,710 @@ +package DocsExamples.Rendering_and_printing.Complex_examples_and_helpers; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import java.awt.geom.Rectangle2D; +import java.text.MessageFormat; +import java.util.List; +import java.util.*; + +@Test +public class PageLayoutHelper extends DocsExamplesBase { + @Test + public void wrapperToAccessLayoutEntities() throws Exception { + // This sample introduces the RenderedDocument class and other related classes which provide an API wrapper for + // the LayoutEnumerator. This allows you to access the layout entities of a document using a DOM style API. + Document doc = new Document(getMyDir() + "Document layout.docx"); + + RenderedDocument layoutDoc = new RenderedDocument(doc); + + // Get access to the line of the first page and print to the console. + RenderedLine line = layoutDoc.getPages().getItem(0).getColumns().getItem(0).getLines().getItem(2); + System.out.println("Line: " + line.getText()); + + // With a rendered line, the original paragraph in the document object model can be returned. + Paragraph para = line.getParagraph(); + System.out.println("Paragraph text: " + para.getRange().getText()); + + // Retrieve all the text that appears on the first page in plain text format (including headers and footers). + String pageText = layoutDoc.getPages().getItem(0).getText(); + System.out.println(); + + // Loop through each page in the document and print how many lines appear on each page. + for (RenderedPage page : layoutDoc.getPages()) { + LayoutCollection lines = page.getChildEntities(LayoutEntityType.LINE, true); + System.out.println(MessageFormat.format("Page {0} has {1} lines.", page.getPageIndex(), lines.getCount())); + } + + // This method provides a reverse lookup of layout entities for any given node + // (except runs and nodes in the header and footer). + System.out.println(); + System.out.println("The lines of the second paragraph:"); + for (LayoutEntity layoutEntity : layoutDoc.getLayoutEntitiesOfNode( + doc.getFirstSection().getBody().getParagraphs().get(1))) { + RenderedLine paragraphLine = (RenderedLine) layoutEntity; + System.out.println("\"{paragraphLine.Text.Trim()}\""); + System.out.println(paragraphLine.getRectangle().toString()); + System.out.println(); + } + } +} + +/// +/// Provides an API wrapper for the LayoutEnumerator class to access the page layout +/// of a document presented in an object model like the design. +/// +class RenderedDocument extends LayoutEntity { + /// + /// Creates a new instance from the supplied Document class. + /// + /// A document whose page layout model to enumerate. + /// If page layout model of the document hasn't been built the enumerator calls + /// to build it. + /// Whenever document is updated and new page layout model is created, + /// a new RenderedDocument instance must be used to access the changes. + public RenderedDocument(Document doc) throws Exception { + mLayoutCollector = new LayoutCollector(doc); + mEnumerator = new LayoutEnumerator(doc); + + processLayoutElements(this); + linkLayoutMarkersToNodes(doc); + collectLinesAndAddToMarkers(); + } + + /// + /// Provides access to the pages of a document. + /// + public final LayoutCollection getPages() { + return getChildNodes(new RenderedPage()); + } + + /// + /// Returns all the layout entities of the specified node. + /// + /// Note that this method does not work with Run nodes or nodes in the header or footer. + LayoutCollection getLayoutEntitiesOfNode(Node node) { + if (!mLayoutCollector.getDocument().equals(node.getDocument())) + throw new IllegalArgumentException("Node does not belong to the same document which was rendered."); + + if (node.getNodeType() == NodeType.DOCUMENT) + return new LayoutCollection<>(mChildEntities); + + ArrayList entities = new ArrayList(); + + // Retrieve all entities from the layout document (inversion of LayoutEntityType.None). + for (LayoutEntity entity : getChildEntities(~LayoutEntityType.NONE, true)) { + if (entity.getParentNode() == node) + entities.add(entity); + + // There is no table entity in rendered output, so manually check if rows belong to a table node. + if (entity.getType() == LayoutEntityType.ROW) { + RenderedRow row = (RenderedRow) entity; + if (row.getTable() == node) + entities.add(entity); + } + } + + return new LayoutCollection<>(entities); + } + + private void processLayoutElements(LayoutEntity current) throws Exception { + do { + LayoutEntity child = current.addChildEntity(mEnumerator); + + if (mEnumerator.moveFirstChild()) { + current = child; + + processLayoutElements(current); + mEnumerator.moveParent(); + + current = current.getParent(); + } + } while (mEnumerator.moveNext()); + } + + private void collectLinesAndAddToMarkers() { + collectLinesOfMarkersCore(LayoutEntityType.COLUMN); + collectLinesOfMarkersCore(LayoutEntityType.COMMENT); + } + + private void collectLinesOfMarkersCore(int type) { + ArrayList collectedLines = new ArrayList<>(); + + for (RenderedPage page : getPages()) { + for (LayoutEntity story : page.getChildEntities(type, false)) { + for (LayoutEntity le : story.getChildEntities(LayoutEntityType.LINE, true)) { + RenderedLine line = (RenderedLine) le; + collectedLines.add(line); + for (RenderedSpan span : line.getSpans()) { + if (mLayoutToNodeLookup.containsKey(span.getLayoutObject())) { + if ("PARAGRAPH".equals(span.getKind()) || "ROW".equals(span.getKind()) || "CELL".equals(span.getKind()) || + "SECTION".equals(span.getKind())) { + Node node = mLayoutToNodeLookup.get(span.getLayoutObject()); + + if (node.getNodeType() == NodeType.ROW) + node = ((Row) node).getLastCell().getLastParagraph(); + + for (RenderedLine collectedLine : collectedLines) + collectedLine.setParentNode(node); + + collectedLines = new ArrayList<>(); + } else { + span.setParentNode(mLayoutToNodeLookup.get(span.getLayoutObject())); + } + } + } + } + } + } + } + + private void linkLayoutMarkersToNodes(Document doc) throws Exception { + for (Node node : (Iterable) doc.getChildNodes(NodeType.ANY, true)) { + Object entity = mLayoutCollector.getEntity(node); + + if (entity != null) + mLayoutToNodeLookup.put(entity, node); + } + } + + private LayoutCollector mLayoutCollector; + private LayoutEnumerator mEnumerator; + private HashMap mLayoutToNodeLookup = new HashMap<>(); +} + +/// +/// Provides the base class for rendered elements of a document. +/// +abstract class LayoutEntity { + public final int getPageIndex() { + return mPageIndex; + } + + /// + /// Returns bounding rectangle of the entity relative to the page top left corner (in points). + /// + public final Rectangle2D getRectangle() { + return mRectangle; + } + + public final int getType() { + return mType; + } + + /// + /// Exports the contents of the entity into a string in plain text format. + /// + public String getText() { + StringBuilder builder = new StringBuilder(); + for (LayoutEntity entity : mChildEntities) { + builder.append(entity.getText()); + } + + return builder.toString(); + } + + public final LayoutEntity getParent() { + return mParent; + } + + /// + /// Returns the node that corresponds to this layout entity. + /// + /// This property may return null for spans that originate + /// from Run nodes or nodes inside the header or footer. + public Node getParentNode() { + return mParentNode; + } + + /// + /// Internal method separate from ParentNode property to make code autoportable to VB.NET. + /// + public void setParentNode(Node value) { + mParentNode = value; + } + + /// + /// Reserved for internal use. + /// + Object getLayoutObject() { + return mLayoutObject; + } + + void setLayoutObject(Object value) { + mLayoutObject = value; + } + + private Object mLayoutObject; + + /// + /// Reserved for internal use. + /// + LayoutEntity addChildEntity(LayoutEnumerator it) throws Exception { + LayoutEntity child = createLayoutEntityFromType(it); + mChildEntities.add(child); + + return child; + } + + private LayoutEntity createLayoutEntityFromType(LayoutEnumerator it) throws Exception { + LayoutEntity childEntity; + switch (it.getType()) { + case LayoutEntityType.CELL: + childEntity = new RenderedCell(); + break; + case LayoutEntityType.COLUMN: + childEntity = new RenderedColumn(); + break; + case LayoutEntityType.COMMENT: + childEntity = new RenderedComment(); + break; + case LayoutEntityType.ENDNOTE: + childEntity = new RenderedEndnote(); + break; + case LayoutEntityType.FOOTNOTE: + childEntity = new RenderedFootnote(); + break; + case LayoutEntityType.HEADER_FOOTER: + childEntity = new RenderedHeaderFooter(); + break; + case LayoutEntityType.LINE: + childEntity = new RenderedLine(); + break; + case LayoutEntityType.NOTE_SEPARATOR: + childEntity = new RenderedNoteSeparator(); + break; + case LayoutEntityType.PAGE: + childEntity = new RenderedPage(); + break; + case LayoutEntityType.ROW: + childEntity = new RenderedRow(); + break; + case LayoutEntityType.SPAN: + childEntity = new RenderedSpan(it.getText()); + break; + case LayoutEntityType.TEXT_BOX: + childEntity = new RenderedTextBox(); + break; + default: + throw new IllegalStateException("Unknown layout type"); + } + + childEntity.mKind = it.getKind(); + childEntity.mPageIndex = it.getPageIndex(); + childEntity.mRectangle = it.getRectangle(); + childEntity.mType = it.getType(); + childEntity.setLayoutObject(it.getCurrent()); + childEntity.mParent = this; + + return childEntity; + } + + public static Collection makeCollection(Iterable iter) { + Collection list = new java.util.ArrayList(); + for (E item : iter) { + list.add(item); + } + return list; + } + + /// + /// Returns a collection of child entities which match the specified type. + /// + /// Specifies the type of entities to select. + /// True to select from all child entities recursively. + /// False to select only among immediate children + public LayoutCollection getChildEntities(int type, boolean isDeep) { + ArrayList childList = new ArrayList<>(); + + for (LayoutEntity entity : mChildEntities) { + if ((entity.getType() & type) == entity.getType()) + childList.add(entity); + + if (isDeep) + childList.addAll(makeCollection(entity.getChildEntities(type, true))); + } + + return new LayoutCollection<>(childList); + } + + protected LayoutCollection getChildNodes(T t) { + T obj = t; + ArrayList childList = new ArrayList<>(); + + for (LayoutEntity entity : mChildEntities) { + if (entity.getClass() == obj.getClass()) { + System.out.println(obj.getClass()); + childList.add((T) entity); + } + } + + return new LayoutCollection<>(childList); + } + + protected String mKind; + protected int mPageIndex; + protected Node mParentNode; + protected Rectangle2D mRectangle; + protected int mType; + protected LayoutEntity mParent; + protected ArrayList mChildEntities = new ArrayList<>(); +} + +/// +/// Represents a generic collection of layout entity types. +/// +final class LayoutCollection implements Iterable { + /// + /// Reserved for internal use. + /// + LayoutCollection(ArrayList baseList) { + mBaseList = baseList; + } + + /// + /// Provides a simple "foreach" style iteration over the collection of nodes. + /// + public final java.util.Iterator getEnumerator() { + return mBaseList.iterator(); + } + + /// + /// Provides a simple "foreach" style iteration over the collection of nodes. + /// + public Iterator iterator() { + return mBaseList.iterator(); + } + + /// + /// Returns the first entity in the collection. + /// + public final T getFirst() { + if (mBaseList.size() > 0) { + return mBaseList.get(0); + } else { + return null; + } + } + + /// + /// Returns the last entity in the collection. + /// + public final T getLast() { + if (mBaseList.size() > 0) { + return mBaseList.get(mBaseList.size() - 1); + } else { + return null; + } + } + + /// + /// Retrieves the entity at the given index. + /// + /// The index is zero-based. + /// If index is greater than or equal to the number of items in the list, + /// this returns a null reference. + public final T getItem(int index) { + return mBaseList.get(index); + } + + /// + /// Gets the number of entities in the collection. + /// + public final int getCount() { + return mBaseList.size(); + } + + private List mBaseList; +} + +/// +/// Represents an entity that contains lines and rows. +/// +abstract class StoryLayoutEntity extends LayoutEntity { + /// + /// Provides access to the lines of a story. + /// + public final LayoutCollection getLines() { + return getChildNodes(new RenderedLine()); + } + + /// + /// Provides access to the row entities of a table. + /// + public final LayoutCollection getRows() { + return getChildNodes(new RenderedRow()); + } +} + +/// +/// Represents line of characters of text and inline objects. +/// +class RenderedLine extends LayoutEntity { + @Override + public String getText() { + return super.getText() + "\n"; + } + + public final Paragraph getParagraph() { + return (Paragraph) getParentNode(); + } + + /// + /// Provides access to the spans of the line. + /// + public final LayoutCollection getSpans() { + return getChildNodes(new RenderedSpan()); + } +} + +/// +/// Represents one or more characters in a line. +/// This include special characters like field start/end markers, bookmarks, shapes and comments. +/// +class RenderedSpan extends LayoutEntity { + public RenderedSpan() { + } + + RenderedSpan(String text) { + // Assign empty text if the span text is null (this can happen with shape spans). + mText = (text != null ? text : ""); + } + + public final String getKind() { + return mKind; + } + + /// + /// Exports the contents of the entity into a string in plain text format. + /// + @Override + public String getText() { + return mText; + } + + @Override + public Node getParentNode() { + return mParentNode; + } + + private String mText; +} + +/// +/// Represents the header/footer content on a page. +/// +class RenderedHeaderFooter extends StoryLayoutEntity { + /// + /// Returns the type of the header or footer. + /// + public final String getKind() { + return mKind; + } +} + +/// +/// Represents page of a document. +/// +class RenderedPage extends LayoutEntity { + /// + /// Provides access to the columns of the page. + /// + public final LayoutCollection getColumns() { + return getChildNodes(new RenderedColumn()); + } + + public final LayoutCollection getHeaderFooters() { + return getChildNodes(new RenderedHeaderFooter()); + } + + /// + /// Provides access to the comments of the page. + /// + public final LayoutCollection getComments() { + return getChildNodes(new RenderedComment()); + } + + /// + /// Returns the section that corresponds to the layout entity. + /// + public final Section getSection() { + return (Section) getParentNode(); + } + + @Override + public Node getParentNode() { + return getColumns().getFirst().getLines().getFirst().getParagraph().getParentSection(); + } +} + +/// +/// Represents a table row. +/// +class RenderedRow extends LayoutEntity { + public final LayoutCollection getCells() { + return getChildNodes(new RenderedCell()); + } + + /// + /// Returns the row that corresponds to the layout entity. + /// + /// This property may return null for some rows such as those inside the header or footer. + public final Row getRow() { + return (Row) getParentNode(); + } + + public final Table getTable() { + return getRow().getParentTable(); + } + + /// + /// Returns the node that corresponds to this layout entity. + /// + /// This property may return null for nodes that are inside the header or footer. + @Override + public Node getParentNode() { + return getCells().getFirst().getLines().getFirst().getParagraph().getAncestor(NodeType.ROW); + } +} + +/// +/// Represents a column of text on a page. +/// +class RenderedColumn extends StoryLayoutEntity { + public final LayoutCollection getFootnotes() { + return getChildNodes(new RenderedFootnote()); + } + + /// + /// Provides access to the endnotes of the page. + /// + public final LayoutCollection getEndnotes() { + return getChildNodes(new RenderedEndnote()); + } + + /// + /// Provides access to the note separators of the page. + /// + public final LayoutCollection getNoteSeparators() { + return getChildNodes(new RenderedNoteSeparator()); + } + + public final Body getBody() { + return (Body) getParentNode(); + } + + /// + /// Returns the node that corresponds to this layout entity. + /// + @Override + public Node getParentNode() { + return getLines().getFirst().getParagraph().getParentSection().getBody(); + } +} + +/// +/// Represents a table cell. +/// +class RenderedCell extends StoryLayoutEntity { + public final Cell getCell() { + return (Cell) getParentNode(); + } + + /// + /// Returns the cell that corresponds to the layout entity. + /// + /// This property may return null for some cells such as those inside the header or footer. + @Override + public Node getParentNode() { + return getLines().getFirst().getParagraph().getAncestor(NodeType.CELL); + } +} + +/// +/// Represents placeholder for footnote content. +/// +class RenderedFootnote extends StoryLayoutEntity { + public final Footnote getFootnote() { + return (Footnote) getParentNode(); + } + + /// + /// Returns the node that corresponds to this layout entity. + /// + @Override + public Node getParentNode() { + return getLines().getFirst().getParagraph().getAncestor(NodeType.FOOTNOTE); + } +} + +/// +/// Represents placeholder for endnote content. +/// +class RenderedEndnote extends StoryLayoutEntity { + /// + /// Returns the endnote that corresponds to the layout entity. + /// + public final Footnote getEndnote() { + return (Footnote) getParentNode(); + } + + @Override + public Node getParentNode() { + return getLines().getFirst().getParagraph().getAncestor(NodeType.FOOTNOTE); + } +} + +/// +/// Represents text area inside of a shape. +/// +class RenderedTextBox extends StoryLayoutEntity { + /// + /// Returns the Shape or DrawingML that corresponds to the layout entity. + /// + /// This property may return null for some Shapes or DrawingML such as those inside the header or footer. + @Override + public Node getParentNode() { + Node shape = getLines().getFirst().getParagraph().getAncestor(NodeType.SHAPE); + + if (shape != null) { + return shape; + } else + return null; + } +} + +/// +/// Represents placeholder for comment content. +/// +class RenderedComment extends StoryLayoutEntity { + public final Comment getComment() { + return (Comment) getParentNode(); + } + + /// + /// Returns the node that corresponds to this layout entity. + /// + @Override + public Node getParentNode() { + return getLines().getFirst().getParagraph().getAncestor(NodeType.COMMENT); + } +} + +/// +/// Represents footnote/endnote separator. +/// +class RenderedNoteSeparator extends StoryLayoutEntity { + /// + /// Returns the footnote/endnote that corresponds to the layout entity. + /// + public final Footnote getFootnote() { + return (Footnote) getParentNode(); + } + + @Override + public Node getParentNode() { + return getLines().getFirst().getParagraph().getAncestor(NodeType.FOOTNOTE); + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Rendering_and_printing/PrintDocuments.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Rendering_and_printing/PrintDocuments.java new file mode 100644 index 00000000..10d9fa3c --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Rendering_and_printing/PrintDocuments.java @@ -0,0 +1,174 @@ +package DocsExamples.Rendering_and_printing; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Document; +import org.testng.annotations.Test; + +import javax.print.attribute.AttributeSet; +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.print.attribute.standard.PageRanges; +import java.awt.*; +import java.awt.geom.Point2D; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterJob; + +@Test +public class PrintDocuments extends DocsExamplesBase { + @Test(enabled = false, description = "Run only when the printer driver is installed") + public void printMultiplePages() throws Exception { + //ExStart:PrintMultiplePagesOnOneSheet + Document doc = new Document(getMyDir() + "Rendering.docx"); + + //ExStart:PrintDialogSettings + // Create a print job to print our document with. + PrinterJob pj = PrinterJob.getPrinterJob(); + + // Initialize an attribute set with the number of pages in the document. + PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet(); + attributes.add(new PageRanges(1, doc.getPageCount())); + + // Pass the printer settings along with the other parameters to the print document. + MultipagePrintDocument awPrintDoc = new MultipagePrintDocument(doc, 4, true, attributes); + + // Pass the document to be printed using the print job. + pj.setPrintable(awPrintDoc); + + pj.print(); + //ExEnd:PrintMultiplePagesOnOneSheet + } +} + +//ExStart:MultipagePrintDocument +class MultipagePrintDocument implements Printable { + //ExStart:DataAndStaticFields + private final Document mDocument; + private final int mPagesPerSheet; + private final boolean mPrintPageBorders; + private final AttributeSet mAttributeSet; + //ExEnd:DataAndStaticFields + + /// + /// The constructor of the custom PrintDocument class. + /// + //ExStart:MultipagePrintDocumentConstructor + public MultipagePrintDocument(Document document, int pagesPerSheet, boolean printPageBorders, + AttributeSet attributes) { + if (document == null) + throw new IllegalArgumentException("document"); + + mDocument = document; + mPagesPerSheet = pagesPerSheet; + mPrintPageBorders = printPageBorders; + mAttributeSet = attributes; + } + //ExEnd:MultipagePrintDocumentConstructor + + public int print(Graphics g, PageFormat pf, int page) { + // The page start and end indices as defined in the attribute set. + int[][] pageRanges = ((PageRanges) mAttributeSet.get(PageRanges.class)).getMembers(); + int fromPage = pageRanges[0][0] - 1; + int toPage = pageRanges[0][1] - 1; + + Dimension thumbCount = getThumbCount(mPagesPerSheet, pf); + + // Calculate the page index which is to be rendered next. + int pagesOnCurrentSheet = (int) (page * (thumbCount.getWidth() * thumbCount.getHeight())); + + // If the page index is more than the total page range then there is nothing + // more to render. + if (pagesOnCurrentSheet > (toPage - fromPage)) + return Printable.NO_SUCH_PAGE; + + // Calculate the size of each thumbnail placeholder in points. + Point2D.Float thumbSize = new Point2D.Float((float) (pf.getImageableWidth() / thumbCount.getWidth()), + (float) (pf.getImageableHeight() / thumbCount.getHeight())); + + // Calculate the number of the first page to be printed on this sheet of paper. + int startPage = pagesOnCurrentSheet + fromPage; + + // Select the number of the last page to be printed on this sheet of paper. + int pageTo = Math.max(startPage + mPagesPerSheet - 1, toPage); + + // Loop through the selected pages from the stored current page to calculated + // last page. + for (int pageIndex = startPage; pageIndex <= pageTo; pageIndex++) { + // Calculate the column and row indices. + int rowIdx = (int) Math.floor((pageIndex - startPage) / thumbCount.getWidth()); + int columnIdx = (int) Math.floor((pageIndex - startPage) % thumbCount.getWidth()); + + // Define the thumbnail location in world coordinates (points in this case). + float thumbLeft = columnIdx * thumbSize.x; + float thumbTop = rowIdx * thumbSize.y; + + try { + + // Calculate the left and top starting positions. + int leftPos = (int) (thumbLeft + pf.getImageableX()); + int topPos = (int) (thumbTop + pf.getImageableY()); + + // Render the document page to the Graphics object using calculated coordinates + // and thumbnail placeholder size. + // The useful return value is the scale at which the page was rendered. + float scale = mDocument.renderToSize(pageIndex, (Graphics2D) g, leftPos, topPos, (int) thumbSize.x, + (int) thumbSize.y); + + // Draw the page borders (the page thumbnail could be smaller than the thumbnail + // placeholder size). + if (mPrintPageBorders) { + // Get the real 100% size of the page in points. + Point2D.Float pageSize = mDocument.getPageInfo(pageIndex).getSizeInPoints(); + // Draw the border around the scaled page using the known scale factor. + g.setColor(Color.black); + g.drawRect(leftPos, topPos, (int) (pageSize.x * scale), (int) (pageSize.y * scale)); + + // Draw the border around the thumbnail placeholder. + g.setColor(Color.red); + g.drawRect(leftPos, topPos, (int) thumbSize.x, (int) thumbSize.y); + } + } catch (Exception e) { + // If there are any errors that occur during rendering then do nothing. + // This will draw a blank page if there are any errors during rendering. + } + } + + return Printable.PAGE_EXISTS; + } + + private Dimension getThumbCount(int pagesPerSheet, PageFormat pf) { + Dimension size; + // Define the number of the columns and rows on the sheet for the + // Landscape-oriented paper. + switch (pagesPerSheet) { + case 16: + size = new Dimension(4, 4); + break; + case 9: + size = new Dimension(3, 3); + break; + case 8: + size = new Dimension(4, 2); + break; + case 6: + size = new Dimension(3, 2); + break; + case 4: + size = new Dimension(2, 2); + break; + case 2: + size = new Dimension(2, 1); + break; + default: + size = new Dimension(1, 1); + break; + } + // Swap the width and height if the paper is in the Portrait orientation. + if ((pf.getWidth() - pf.getImageableX()) < (pf.getHeight() - pf.getImageableY())) + return new Dimension((int) size.getHeight(), (int) size.getWidth()); + + return size; + } + //ExEnd:MultipagePrintDocument +} + diff --git a/Examples/DocsExamples/Java/src/main/java/DocsExamples/Rendering_and_printing/RenderingShapes.java b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Rendering_and_printing/RenderingShapes.java new file mode 100644 index 00000000..f30bcc02 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/DocsExamples/Rendering_and_printing/RenderingShapes.java @@ -0,0 +1,257 @@ +package DocsExamples.Rendering_and_printing; + +import DocsExamples.DocsExamplesBase; +import com.aspose.words.Shape; +import com.aspose.words.*; +import org.testng.annotations.Test; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileOutputStream; + +@Test +public class RenderingShapes extends DocsExamplesBase { + @Test + public void renderShapeAsEmf() throws Exception { + Document doc = new Document(getMyDir() + "Rendering.docx"); + // Retrieve the target shape from the document. + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + //ExStart:RenderShapeAsEmf + //GistId:7fc867ac8ef1b729b6f70580fbc5b3f9 + ShapeRenderer render = shape.getShapeRenderer(); + ImageSaveOptions imageOptions = new ImageSaveOptions(SaveFormat.EMF); + imageOptions.setScale(1.5f); + + render.save(getArtifactsDir() + "RenderShape.RenderShapeAsEmf.emf", imageOptions); + //ExEnd:RenderShapeAsEmf + } + + @Test + public void renderShapeAsJpeg() throws Exception { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + //ExStart:RenderShapeAsJpeg + //GistId:7fc867ac8ef1b729b6f70580fbc5b3f9 + ShapeRenderer render = new ShapeRenderer(shape); + ImageSaveOptions imageOptions = new ImageSaveOptions(SaveFormat.JPEG); + // Output the image in gray scale + imageOptions.setImageColorMode(ImageColorMode.GRAYSCALE); + // Reduce the brightness a bit (default is 0.5f) + imageOptions.setImageBrightness(0.45f); + + try (FileOutputStream stream = new FileOutputStream(getArtifactsDir() + "RenderShape.RenderShapeAsJpeg.jpg")) { + render.save(stream, imageOptions); + } + //ExEnd:RenderShapeAsJpeg + } + + @Test + //ExStart:RenderShapeToGraphics + //GistId:7fc867ac8ef1b729b6f70580fbc5b3f9 + public void renderShapeToGraphics() throws Exception { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + ShapeRenderer render = shape.getShapeRenderer(); + + // Find the size that the shape will be rendered to at the specified scale and resolution. + Dimension shapeSizeInPixels = render.getSizeInPixels(1.0f, 96.0f); + + // Rotating the shape may result in clipping as the image canvas is too small. Find the longest side + // and make sure that the graphics canvas is large enough to compensate for this. + int maxSide = Math.max(shapeSizeInPixels.width, shapeSizeInPixels.height); + + BufferedImage image = new BufferedImage((int) (maxSide * 1.25), (int) (maxSide * 1.25), BufferedImage.TYPE_INT_ARGB); + + // Rendering to a graphics object means we can specify settings and transformations to be applied to the rendered shape. + // In our case we will rotate the rendered shape. + Graphics2D graphics = (Graphics2D) image.getGraphics(); + try { + // Clear the shape with the background color of the document. + graphics.setBackground(shape.getDocument().getPageColor()); + graphics.clearRect(0, 0, image.getWidth(), image.getHeight()); + // Center the rotation using the translation method below. + graphics.translate(image.getWidth() / 8, image.getHeight() / 2); + // Rotate the image by 45 degrees. + graphics.rotate(45 * Math.PI / 180); + // Undo the translation. + graphics.translate(-image.getWidth() / 8, -image.getHeight() / 2); + + // Render the shape onto the graphics object. + render.renderToSize(graphics, 0, 0, shapeSizeInPixels.width, shapeSizeInPixels.height); + } finally { + if (graphics != null) graphics.dispose(); + } + + ImageIO.write(image, "png", new File(getArtifactsDir() + "RenderShape.RenderShapeToGraphics.png")); + } + //ExEnd:RenderShapeToGraphics + + @Test + public void renderCellToImage() throws Exception { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + //ExStart:RenderCellToImage + Cell cell = (Cell) doc.getChild(NodeType.CELL, 2, true); + Document tmp = convertToImage(doc, cell); + tmp.save(getArtifactsDir() + "RenderShape.RenderCellToImage.png"); + //ExEnd:RenderCellToImage + } + + @Test + public void renderRowToImage() throws Exception { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + //ExStart:RenderRowToImage + Row row = (Row) doc.getChild(NodeType.ROW, 0, true); + Document tmp = convertToImage(doc, row); + tmp.save(getArtifactsDir() + "RenderShape.RenderRowToImage.png"); + //ExEnd:RenderRowToImage + } + + @Test + public void renderParagraphToImage() throws Exception { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + //ExStart:RenderParagraphToImage + Shape textBoxShape = builder.insertShape(ShapeType.TEXT_BOX, 150.0, 100.0); + + builder.moveTo(textBoxShape.getLastParagraph()); + builder.write("Vertical text"); + + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.PNG); + options.setPaperColor(new Color(255, 182, 193)); + + Document tmp = convertToImage(doc, textBoxShape.getLastParagraph()); + tmp.save(getArtifactsDir() + "RenderShape.RenderParagraphToImage.png"); + //ExEnd:RenderParagraphToImage + } + + @Test + public void findShapeSizes() throws Exception { + Document doc = new Document(getMyDir() + "Rendering.docx"); + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + //ExStart:FindShapeSizes + //GistId:7fc867ac8ef1b729b6f70580fbc5b3f9 + Point2D.Float shapeSizeInDocument = shape.getShapeRenderer().getSizeInPoints(); + float width = shapeSizeInDocument.x; // The width of the shape. + float height = shapeSizeInDocument.y; // The height of the shape. + Dimension shapeRenderedSize = shape.getShapeRenderer().getSizeInPixels(1.0f, 96.0f); + + BufferedImage image = new BufferedImage(shapeRenderedSize.width, shapeRenderedSize.height, + BufferedImage.TYPE_INT_RGB); + + Graphics2D graphics = (Graphics2D) image.getGraphics(); + try { + // Render shape onto the graphics object using the RenderToScale + // or RenderToSize methods of ShapeRenderer class. + } finally { + if (graphics != null) graphics.dispose(); + } + //ExEnd:FindShapeSizes + } + + @Test + public void renderShapeImage() throws Exception { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + //ExStart:RenderShapeImage + //GistId:7fc867ac8ef1b729b6f70580fbc5b3f9 + shape.getShapeRenderer().save(getArtifactsDir() + "RenderShape.RenderShapeImage.jpg", new ImageSaveOptions(SaveFormat.JPEG)); + //ExEnd:RenderShapeImage + } + + /// + /// Renders any node in a document into an image. + /// + /// The current document. + /// The node to render. + private static Document convertToImage(Document doc, CompositeNode node) throws Exception { + Document tmp = createTemporaryDocument(doc, node); + appendNodeContent(tmp, node); + adjustDocumentLayout(tmp); + return tmp; + } + + /// + /// Creates a temporary document for further rendering. + /// + private static Document createTemporaryDocument(Document doc, CompositeNode node) { + Document tmp = (Document) doc.deepClone(false); + tmp.getSections().add(tmp.importNode(node.getAncestor(NodeType.SECTION), false, ImportFormatMode.USE_DESTINATION_STYLES)); + tmp.getFirstSection().appendChild(new Body(tmp)); + tmp.getFirstSection().getPageSetup().setTopMargin(0.0); + tmp.getFirstSection().getPageSetup().setBottomMargin(0.0); + + return tmp; + } + + /// + /// Adds a node to a temporary document. + /// + private static void appendNodeContent(Document tmp, CompositeNode node) { + if (node.getNodeType() == NodeType.HEADER_FOOTER) { + for (Node hfNode : node.getChildNodes(NodeType.ANY, false).toArray()) + tmp.getFirstSection().getBody().appendChild(tmp.importNode(hfNode, true, ImportFormatMode.USE_DESTINATION_STYLES)); + } else + appendNonHeaderFooterContent(tmp, node); + } + + private static void appendNonHeaderFooterContent(Document tmp, CompositeNode node) { + Node parentNode = node.getParentNode(); + while (!(parentNode instanceof InlineStory || parentNode instanceof Story || parentNode instanceof ShapeBase)) { + CompositeNode parent = (CompositeNode) parentNode.deepClone(false); + parent.appendChild(node.deepClone(true)); + node = parent; + + parentNode = parentNode.getParentNode(); + } + + tmp.getFirstSection().getBody().appendChild(tmp.importNode(node, true, ImportFormatMode.USE_DESTINATION_STYLES)); + } + + /// + /// Adjusts the layout of the document to fit the content area. + /// + private static void adjustDocumentLayout(Document tmp) throws Exception { + LayoutEnumerator enumerator = new LayoutEnumerator(tmp); + Rectangle2D.Float rect = new Rectangle2D.Float(0f, 0f, 0f, 0f); + rect = calculateVisibleRect(enumerator, rect); + + tmp.getFirstSection().getPageSetup().setPageHeight(rect.getHeight()); + tmp.updatePageLayout(); + } + + /// + /// Calculates the visible area of the content. + /// + private static Rectangle2D.Float calculateVisibleRect(LayoutEnumerator enumerator, Rectangle2D.Float rect) throws Exception { + Rectangle2D.Float result = rect; + do { + if (enumerator.moveFirstChild()) { + if (enumerator.getType() == LayoutEntityType.LINE || enumerator.getType() == LayoutEntityType.SPAN) { + if (result.isEmpty()) + result = enumerator.getRectangle(); + else + Rectangle2D.Float.union(result, enumerator.getRectangle(), result); + } + + result = calculateVisibleRect(enumerator, result); + enumerator.moveParent(); + } + } while (enumerator.moveNext()); + + return result; + } +} + diff --git a/Examples/DocsExamples/Java/src/main/java/TestData/Common.java b/Examples/DocsExamples/Java/src/main/java/TestData/Common.java new file mode 100644 index 00000000..f112c8f5 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/TestData/Common.java @@ -0,0 +1,156 @@ +package TestData; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2024 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import TestData.TestClasses.ClientTestClass; +import TestData.TestClasses.ContractTestClass; +import TestData.TestClasses.ManagerTestClass; + +import java.time.LocalDate; +import java.util.ArrayList; + +public class Common { + private static ArrayList managers = new ArrayList<>(); + private static ArrayList contracts = new ArrayList<>(); + private static ArrayList clients = new ArrayList<>(); + + static { + // -------------------------------------------------- + // First manager + // -------------------------------------------------- + ManagerTestClass firstManager = new ManagerTestClass(); + firstManager.setName("John Smith"); + firstManager.setAge(36); + + ArrayList contracts = new ArrayList<>(); + { + contracts.add(new ContractTestClass()); + { + contracts.get(0).setManager(firstManager); + contracts.get(0).setPrice(1200000f); + contracts.get(0).setDate(LocalDate.of(2017, 1, 1)); + contracts.get(0).setClient(new ClientTestClass("A Company", "Australia", "219-241 Cleveland St STRAWBERRY HILLS NSW 1427")); + } + contracts.add(new ContractTestClass()); + { + contracts.get(1).setManager(firstManager); + contracts.get(1).setPrice(750000f); + contracts.get(1).setDate(LocalDate.of(2017, 4, 1)); + contracts.get(1).setClient(new ClientTestClass("B Ltd.", "Brazil", "Avenida João Jorge, 112, ap. 31 Vila Industrial Campinas - SP 13035-680")); + } + contracts.add(new ContractTestClass()); + { + contracts.get(2).setManager(firstManager); + contracts.get(2).setPrice(350000f); + contracts.get(2).setDate(LocalDate.of(2017, 7, 1)); + contracts.get(2).setClient(new ClientTestClass("C & D", "Canada", "101-3485 RUE DE LA MONTAGNE MONTRÉAL (QUÉBEC) H3G 2A6")); + } + } + + firstManager.setContracts(contracts); + + // -------------------------------------------------- + // Second manager + // -------------------------------------------------- + ManagerTestClass secondManager = new ManagerTestClass(); + secondManager.setName("Tony Anderson"); + secondManager.setAge(37); + + contracts = new ArrayList<>(); + { + contracts.add(new ContractTestClass()); + { + contracts.get(0).setManager(secondManager); + contracts.get(0).setPrice(650000f); + contracts.get(0).setDate(LocalDate.of(2017, 2, 1)); + contracts.get(0).setClient(new ClientTestClass("E Corp.", "445 Mount Eden Road Mount Eden Auckland 1024")); + } + contracts.add(new ContractTestClass()); + { + contracts.get(1).setManager(secondManager); + contracts.get(1).setPrice(550000f); + contracts.get(1).setDate(LocalDate.of(2017, 8, 1)); + contracts.get(1).setClient(new ClientTestClass("F & Partners", "20 Greens Road Tuahiwi Kaiapoi 7691")); + } + } + + secondManager.setContracts(contracts); + + // -------------------------------------------------- + // Third manager + // -------------------------------------------------- + ManagerTestClass thirdManager = new ManagerTestClass(); + thirdManager.setName("July James"); + thirdManager.setAge(38); + + contracts = new ArrayList<>(); + { + contracts.add(new ContractTestClass()); + { + contracts.get(0).setManager(thirdManager); + contracts.get(0).setPrice(350000f); + contracts.get(0).setDate(LocalDate.of(2017, 2, 1)); + contracts.get(0).setClient(new ClientTestClass("G & Co.", "Greece", "Karkisias 6 GR-111 42 ATHINA GRÉCE")); + } + contracts.add(new ContractTestClass()); + { + contracts.get(1).setManager(thirdManager); + contracts.get(1).setPrice(250000f); + contracts.get(1).setDate(LocalDate.of(2017, 5, 1)); + contracts.get(1).setClient(new ClientTestClass("H Group", "Hungary", "Budapest Fiktív utca 82., IV. em./28.2806")); + } + contracts.add(new ContractTestClass()); + { + contracts.get(2).setManager(thirdManager); + contracts.get(2).setPrice(100000f); + contracts.get(2).setDate(LocalDate.of(2017, 7, 1)); + contracts.get(2).setClient(new ClientTestClass("I & Sons", "43 Vogel Street Roslyn Palmerston North 4414")); + } + contracts.add(new ContractTestClass()); + { + contracts.get(3).setManager(thirdManager); + contracts.get(3).setPrice(100000f); + contracts.get(3).setDate(LocalDate.of(2017, 8, 1)); + contracts.get(3).setClient(new ClientTestClass("J Ent.", "Japan", "Hakusan 4-Chōme 3-2 Bunkyō-ku, TŌKYŌ 112-0001 Japan")); + } + } + + thirdManager.setContracts(contracts); + + managers.add(firstManager); + managers.add(secondManager); + managers.add(thirdManager); + } + + public static ArrayList getEmptyManagers() { + return new ArrayList<>(); + } + + public static ArrayList getManagers() { + return managers; + } + + public static ArrayList getClients() { + for (ManagerTestClass manager : getManagers()) { + for (ContractTestClass contract : manager.getContracts()) + clients.add(contract.getClient()); + } + + return clients; + } + + public static ArrayList getContracts() { + for (ManagerTestClass manager : getManagers()) { + for (ContractTestClass contract : manager.getContracts()) + contracts.add(contract); + } + + return contracts; + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/TestData/TestBuilders/ColorItemTestBuilder.java b/Examples/DocsExamples/Java/src/main/java/TestData/TestBuilders/ColorItemTestBuilder.java new file mode 100644 index 00000000..769594b8 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/TestData/TestBuilders/ColorItemTestBuilder.java @@ -0,0 +1,67 @@ +package TestData.TestBuilders; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2024 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import TestData.TestClasses.ColorItemTestClass; + +import java.awt.*; + +public class ColorItemTestBuilder { + private String mName; + private Color mColor; + private int mColorCode; + private double mValue1; + private double mValue2; + private double mValue3; + + public ColorItemTestBuilder() { + mName = "DefaultName"; + mColor = Color.BLACK; + mColorCode = Color.BLACK.getRGB(); + mValue1 = 1.0; + mValue2 = 1.0; + mValue3 = 1.0; + } + + public ColorItemTestBuilder withColor(final String name, final Color color) { + mName = name; + mColor = color; + return this; + } + + public ColorItemTestBuilder withColorCode(final String name, final int colorCode) { + mName = name; + mColorCode = colorCode; + return this; + } + + public ColorItemTestBuilder withColorAndValues(final String name, final Color color, final double value1, + final double value2, final double value3) { + mName = name; + mColor = color; + mValue1 = value1; + mValue2 = value2; + mValue3 = value3; + return this; + } + + public ColorItemTestBuilder withColorCodeAndValues(final String name, final int colorCode, final double value1, + final double value2, final double value3) { + mName = name; + mColorCode = colorCode; + mValue1 = value1; + mValue2 = value2; + mValue3 = value3; + return this; + } + + public ColorItemTestClass build() { + return new ColorItemTestClass(mName, mColor, mColorCode, mValue1, mValue2, mValue3); + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/TestData/TestBuilders/DocumentTestBuilder.java b/Examples/DocsExamples/Java/src/main/java/TestData/TestBuilders/DocumentTestBuilder.java new file mode 100644 index 00000000..6b6d810d --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/TestData/TestBuilders/DocumentTestBuilder.java @@ -0,0 +1,52 @@ +package TestData.TestBuilders; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2024 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import TestData.TestClasses.DocumentTestClass; +import com.aspose.words.Document; + +import java.io.FileInputStream; + +public class DocumentTestBuilder { + private Document mDocument; + private FileInputStream mDocumentStream; + private byte[] mDocumentBytes; + private String mDocumentString; + + public DocumentTestBuilder() throws Exception { + mDocument = new Document(); + mDocumentStream = null; + mDocumentBytes = new byte[0]; + mDocumentString = ""; + } + + public DocumentTestBuilder withDocument(final Document doc) { + mDocument = doc; + return this; + } + + public DocumentTestBuilder withDocumentStream(final FileInputStream stream) { + mDocumentStream = stream; + return this; + } + + public DocumentTestBuilder withDocumentBytes(final byte[] docBytes) { + mDocumentBytes = docBytes; + return this; + } + + public DocumentTestBuilder withDocumentString(final String docUri) { + mDocumentString = docUri; + return this; + } + + public DocumentTestClass build() { + return new DocumentTestClass(mDocument, mDocumentStream, mDocumentBytes, mDocumentString); + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/TestData/TestBuilders/ImageTestBuilder.java b/Examples/DocsExamples/Java/src/main/java/TestData/TestBuilders/ImageTestBuilder.java new file mode 100644 index 00000000..af69d597 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/TestData/TestBuilders/ImageTestBuilder.java @@ -0,0 +1,58 @@ +package TestData.TestBuilders; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2024 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import DocsExamples.DocsExamplesBase; +import TestData.TestClasses.ImageTestClass; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +public class ImageTestBuilder extends DocsExamplesBase { + private BufferedImage mImage; + private FileInputStream mImageStream; + private byte[] mImageBytes; + private String mImageString; + + public ImageTestBuilder() throws Exception { + + mImage = ImageIO.read(new File(getImagesDir() + "Transparent background logo.png")); + + mImageStream = null; + mImageBytes = new byte[0]; + mImageString = ""; + } + + public ImageTestBuilder withImage(final String imagePath) throws IOException { + mImage = ImageIO.read(new File(imagePath)); + return this; + } + + public ImageTestBuilder withImageStream(final FileInputStream imageStream) { + mImageStream = imageStream; + return this; + } + + public ImageTestBuilder withImageBytes(final byte[] imageBytes) { + mImageBytes = imageBytes; + return this; + } + + public ImageTestBuilder withImageString(final String imageString) { + mImageString = imageString; + return this; + } + + public ImageTestClass build() { + return new ImageTestClass(mImage, mImageStream, mImageBytes, mImageString); + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/TestData/TestBuilders/NumericTestBuilder.java b/Examples/DocsExamples/Java/src/main/java/TestData/TestBuilders/NumericTestBuilder.java new file mode 100644 index 00000000..847ec2ca --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/TestData/TestBuilders/NumericTestBuilder.java @@ -0,0 +1,61 @@ +package TestData.TestBuilders; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2024 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import TestData.TestClasses.NumericTestClass; + +import java.time.LocalDate; + +public class NumericTestBuilder { + private Integer mValue1; + private double mValue2; + private Integer mValue3; + private Integer mValue4; + private boolean mLogical; + private LocalDate mDate; + + public NumericTestBuilder() { + mValue1 = 1; + mValue2 = 1.0; + mValue3 = 1; + mValue4 = 1; + mLogical = false; + mDate = LocalDate.of(2018, 1, 1); + } + + public NumericTestBuilder withValuesAndDate(final Integer value1, final double value2, final Integer value3, + final Integer value4, final LocalDate dateTime) { + mValue1 = value1; + mValue2 = value2; + mValue3 = value3; + mValue4 = value4; + mDate = dateTime; + return this; + } + + public NumericTestBuilder withValuesAndLogical(final Integer value1, final double value2, final Integer value3, + final Integer value4, final boolean logical) { + mValue1 = value1; + mValue2 = value2; + mValue3 = value3; + mValue4 = value4; + mLogical = logical; + return this; + } + + public NumericTestBuilder withValues(final Integer value1, double value2) { + mValue1 = value1; + mValue2 = value2; + return this; + } + + public NumericTestClass build() { + return new NumericTestClass(mValue1, mValue2, mValue3, mValue4, mLogical, mDate); + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/ClientTestClass.java b/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/ClientTestClass.java new file mode 100644 index 00000000..61afd9c0 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/ClientTestClass.java @@ -0,0 +1,53 @@ +package TestData.TestClasses; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2024 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +public class ClientTestClass { + private String mName; + private String mCountry; + private String mLocalAddress; + + public ClientTestClass() { + } + + public ClientTestClass(final String name, final String localAddress) { + setName(name); + setLocalAddress(localAddress); + } + + public ClientTestClass(final String name, final String country, final String localAddress) { + setName(name); + setCountry(country); + setLocalAddress(localAddress); + } + + public void setName(final String value) { + mName = value; + } + + public void setCountry(final String value) { + mCountry = value; + } + + public void setLocalAddress(final String value) { + mLocalAddress = value; + } + + public String getName() { + return mName; + } + + public String getCountry() { + return mCountry; + } + + public String getLocalAddress() { + return mLocalAddress; + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/ColorItemTestClass.java b/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/ColorItemTestClass.java new file mode 100644 index 00000000..a89d5e39 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/ColorItemTestClass.java @@ -0,0 +1,81 @@ +package TestData.TestClasses; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2024 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import java.awt.*; + +public class ColorItemTestClass { + private String mName; + private Color mColor; + private int mColorCode; + private double mValue1; + private double mValue2; + private double mValue3; + + public ColorItemTestClass() { + } + + public ColorItemTestClass(final String name, final Color color, final int colorCode, final double value1, + final double value2, final double value3) { + setName(name); + setColor(color); + setColorCode(colorCode); + setValue1(value1); + setValue2(value2); + setValue3(value3); + } + + public void setName(final String value) { + mName = value; + } + + public void setColor(final Color value) { + mColor = value; + } + + public void setColorCode(final int value) { + mColorCode = value; + } + + public void setValue1(final double value) { + mValue1 = value; + } + + public void setValue2(final double value) { + mValue2 = value; + } + + public void setValue3(final double value) { + mValue3 = value; + } + + public String getName() { + return mName; + } + + public Color getColor() { + return mColor; + } + + public int getColorCode() { + return mColorCode; + } + + public double getValue1() { + return mValue1; + } + + public double getValue2() { + return mValue2; + } + + public double getValue3() { + return mValue3; + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/ContractTestClass.java b/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/ContractTestClass.java new file mode 100644 index 00000000..eacf97a8 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/ContractTestClass.java @@ -0,0 +1,62 @@ +package TestData.TestClasses; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2024 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import java.time.LocalDate; + +public class ContractTestClass { + private ManagerTestClass mManager; + private ClientTestClass mClient; + private float mPrice; + private LocalDate mDate; + + public ContractTestClass() { + } + + public ContractTestClass(final ManagerTestClass manager, final ClientTestClass client, final float price, final LocalDate date) { + setManager(manager); + setClient(client); + setPrice(price); + setDate(date); + } + + public void setManager(final ManagerTestClass value) { + mManager = value; + } + + public void setClient(final ClientTestClass value) { + mClient = value; + } + + public void setPrice(final float value) { + mPrice = value; + } + + public void setDate(final LocalDate value) { + mDate = value; + } + + public ManagerTestClass getManager() { + return mManager; + } + + public ClientTestClass getClient() { + return mClient; + } + + public float getPrice() { + return mPrice; + } + + public LocalDate getDate() { + return mDate; + } + + +} diff --git a/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/DocumentTestClass.java b/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/DocumentTestClass.java new file mode 100644 index 00000000..b9e6cddd --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/DocumentTestClass.java @@ -0,0 +1,62 @@ +package TestData.TestClasses; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2024 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import com.aspose.words.Document; + +import java.io.FileInputStream; + +public class DocumentTestClass { + private Document mDocument; + private FileInputStream mDocumentStream; + private byte[] mDocumentBytes; + private String mDocumentString; + + public DocumentTestClass() { + } + + public DocumentTestClass(final Document doc, final FileInputStream docStream, final byte[] docBytes, final String docString) { + setDocument(doc); + setDocumentStream(docStream); + setDocumentBytes(docBytes); + setDocumentString(docString); + } + + public void setDocument(final Document value) { + mDocument = value; + } + + public void setDocumentStream(final FileInputStream value) { + mDocumentStream = value; + } + + public void setDocumentBytes(final byte[] value) { + mDocumentBytes = value; + } + + public void setDocumentString(final String value) { + mDocumentString = value; + } + + public Document getDocument() { + return mDocument; + } + + public FileInputStream getDocumentStream() { + return mDocumentStream; + } + + public byte[] getDocumentBytes() { + return mDocumentBytes; + } + + public String getDocumentString() { + return mDocumentString; + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/ImageTestClass.java b/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/ImageTestClass.java new file mode 100644 index 00000000..2297a046 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/ImageTestClass.java @@ -0,0 +1,61 @@ +package TestData.TestClasses; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2024 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import java.awt.image.BufferedImage; +import java.io.FileInputStream; + +public class ImageTestClass { + private BufferedImage mImage; + private FileInputStream mImageStream; + private byte[] mImageBytes; + private String mImageString; + + public ImageTestClass() { + } + + public ImageTestClass(final BufferedImage image, final FileInputStream imageStream, final byte[] imageBytes, final String imageString) { + setImage(image); + setImageStream(imageStream); + setImageBytes(imageBytes); + setImageString(imageString); + } + + public void setImage(final BufferedImage value) { + mImage = value; + } + + public void setImageStream(final FileInputStream value) { + mImageStream = value; + } + + public void setImageBytes(final byte[] value) { + mImageBytes = value; + } + + public void setImageString(final String value) { + mImageString = value; + } + + public BufferedImage getImage() { + return mImage; + } + + public FileInputStream getImageStream() { + return mImageStream; + } + + public byte[] getImageBytes() { + return mImageBytes; + } + + public String getImageString() { + return mImageString; + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/ManagerTestClass.java b/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/ManagerTestClass.java new file mode 100644 index 00000000..aca2c1e0 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/ManagerTestClass.java @@ -0,0 +1,75 @@ +package TestData.TestClasses; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2024 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import DocsExamples.DocsExamplesBase; +import org.apache.commons.io.FileUtils; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; + +public class ManagerTestClass extends DocsExamplesBase { + private String mName; + private int mAge; + private byte[] mPhoto; + private ArrayList mContracts; + + public ManagerTestClass() { + } + + public ManagerTestClass(final String name, final int age, final ArrayList contracts) throws IOException { + setName(name); + setAge(age); + setPhoto(FileUtils.readFileToByteArray(new File(getImagesDir() + "Logo.jpg"))); + setContracts(contracts); + } + + public void setName(final String value) { + mName = value; + } + + public void setAge(final int value) { + mAge = value; + } + + public void setPhoto(byte[] value) { + mPhoto = value; + } + + public void setContracts(final ArrayList value) { + mContracts = value; + } + + public String getName() { + return mName; + } + + public int getAge() { + return mAge; + } + + public byte[] getPhoto() { + return mPhoto; + } + + public ArrayList getContracts() { + return mContracts; + } + + public int getContractsSum() { + int contractsSum = 0; + + for (ContractTestClass contract : getContracts()) { + contractsSum = (int) (contractsSum + contract.getPrice()); + } + + return contractsSum; + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/MessageTestClass.java b/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/MessageTestClass.java new file mode 100644 index 00000000..2519e481 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/MessageTestClass.java @@ -0,0 +1,38 @@ +package TestData.TestClasses; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2024 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +public class MessageTestClass { + private String mName; + private String mMessage; + + public MessageTestClass() { + } + + public MessageTestClass(final String name, final String message) { + setName(name); + setMessage(message); + } + + public void setName(final String name) { + mName = name; + } + + public String getName() { + return mName; + } + + public void setMessage(final String message) { + mMessage = message; + } + + public String getMessage() { + return mMessage; + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/NumericTestClass.java b/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/NumericTestClass.java new file mode 100644 index 00000000..27cd054f --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/NumericTestClass.java @@ -0,0 +1,86 @@ +package TestData.TestClasses; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2024 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import java.time.LocalDate; + +public class NumericTestClass { + private Integer mValue1; + private double mValue2; + private Integer mValue3; + private Integer mValue4; + private boolean mLogical; + private LocalDate mDate; + + public NumericTestClass() { + } + + public NumericTestClass(final Integer value1, final double value2, final Integer value3, final Integer value4, + final boolean logical, final LocalDate dateTime) { + setValue1(value1); + setValue2(value2); + setValue3(value3); + setValue4(value4); + setLogical(logical); + setDate(dateTime); + } + + public void setValue1(final Integer value) { + mValue1 = value; + } + + public void setValue2(final double value) { + mValue2 = value; + } + + public void setValue3(final Integer value) { + mValue3 = value; + } + + public void setValue4(final Integer value) { + mValue4 = value; + } + + public void setLogical(final boolean value) { + mLogical = value; + } + + public void setDate(final LocalDate value) { + mDate = value; + } + + public Integer getValue1() { + return mValue1; + } + + public double getValue2() { + return mValue2; + } + + public Integer getValue3() { + return mValue3; + } + + public Integer getValue4() { + return mValue4; + } + + public boolean getLogical() { + return mLogical; + } + + public LocalDate getDate() { + return mDate; + } + + public int sum(final int value1, final int value2) { + int result = value1 + value2; + return result; + } +} diff --git a/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/SenderTestClass.java b/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/SenderTestClass.java new file mode 100644 index 00000000..e48499c2 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/SenderTestClass.java @@ -0,0 +1,24 @@ +package TestData.TestClasses; + +//ExStart:Sender +public class SenderTestClass { + private String mName; + private String mMessage; + + public String getName() { + return mName; + } + + public String getMessage() { + return mMessage; + } + + public void setName(String value) { + mName = value; + } + + public void setMessage(String value) { + mMessage = value; + } +} +//ExEnd:Sender diff --git a/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/SignPersonTestClass.java b/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/SignPersonTestClass.java new file mode 100644 index 00000000..c7e2ed36 --- /dev/null +++ b/Examples/DocsExamples/Java/src/main/java/TestData/TestClasses/SignPersonTestClass.java @@ -0,0 +1,60 @@ +package TestData.TestClasses; + +////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2001-2024 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +import java.util.UUID; + +public class SignPersonTestClass { + private UUID mPersonId; + private String mName; + private String mPosition; + private byte[] mImage; + + public SignPersonTestClass() { + } + + public SignPersonTestClass(final UUID guid, final String name, final String position, final byte[] image) { + setPersonId(guid); + setName(name); + setPosition(position); + setImage(image); + } + + public void setPersonId(final UUID value) { + mPersonId = value; + } + + public void setName(final String value) { + mName = value; + } + + public void setPosition(final String value) { + mPosition = value; + } + + public void setImage(final byte[] value) { + mImage = value; + } + + public UUID getPersonId() { + return mPersonId; + } + + public String getName() { + return mName; + } + + public String getPosition() { + return mPosition; + } + + public byte[] getImage() { + return mImage; + } +} diff --git a/Examples/DocsExamples/JavaPorting/AI-powered_Features/WorkingWithAI.java b/Examples/DocsExamples/JavaPorting/AI-powered_Features/WorkingWithAI.java new file mode 100644 index 00000000..2fcca174 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/AI-powered_Features/WorkingWithAI.java @@ -0,0 +1,80 @@ +package DocsExamples.AI_powered_Features; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.ms.System.Environment; +import com.aspose.words.AiModel; +import com.aspose.words.OpenAiModel; +import com.aspose.words.AiModelType; +import com.aspose.words.SummarizeOptions; +import com.aspose.words.SummaryLength; +import com.aspose.words.GoogleAiModel; +import com.aspose.words.Language; +import com.aspose.words.CheckGrammarOptions; + + +public class Working_with_AI extends DocsExamplesBase +{ + @Test (enabled = false, description = "This test should be run manually to manage API requests amount") + public void aiSummarize() throws Exception + { + //ExStart:AiSummarize + //GistId:1e379bedb2b759c1be24c64aad54d13d + Document firstDoc = new Document(getMyDir() + "Big document.docx"); + Document secondDoc = new Document(getMyDir() + "Document.docx"); + + String apiKey = System.getenv("API_KEY"); + // Use OpenAI or Google generative language models. + AiModel model = ((OpenAiModel)AiModel.create(AiModelType.GPT_4_O_MINI).withApiKey(apiKey)).withOrganization("Organization").withProject("Project"); + + SummarizeOptions options = new SummarizeOptions(); + + options.setSummaryLength(SummaryLength.SHORT); + Document oneDocumentSummary = model.summarize(firstDoc, options); + oneDocumentSummary.save(getArtifactsDir() + "AI.AiSummarize.One.docx"); + + options.setSummaryLength(SummaryLength.LONG); + Document multiDocumentSummary = model.summarize(new Document[] { firstDoc, secondDoc }, options); + multiDocumentSummary.save(getArtifactsDir() + "AI.AiSummarize.Multi.docx"); + //ExEnd:AiSummarize + } + + @Test (enabled = false, description = "This test should be run manually to manage API requests amount") + public void aiTranslate() throws Exception + { + //ExStart:AiTranslate + //GistId:ea14b3e44c0233eecd663f783a21c4f6 + Document doc = new Document(getMyDir() + "Document.docx"); + + String apiKey = System.getenv("API_KEY"); + // Use Google generative language models. + AiModel model = (GoogleAiModel)AiModel.create(AiModelType.GEMINI_15_FLASH).withApiKey(apiKey); + + Document translatedDoc = model.translate(doc, Language.ARABIC); + translatedDoc.save(getArtifactsDir() + "AI.AiTranslate.docx"); + //ExEnd:AiTranslate + } + + @Test (enabled = false, description = "This test should be run manually to manage API requests amount") + public void aiGrammar() throws Exception + { + //ExStart:AiGrammar + //GistId:98a646d19cd7708ed0cd3d97b993a053 + Document doc = new Document(getMyDir() + "Big document.docx"); + + String apiKey = System.getenv("API_KEY"); + // Use OpenAI generative language models. + AiModel model = AiModel.create(AiModelType.GPT_4_O_MINI).withApiKey(apiKey); + + CheckGrammarOptions grammarOptions = new CheckGrammarOptions(); + grammarOptions.setImproveStylistics(true); + + Document proofedDoc = model.checkGrammar(doc, grammarOptions); + proofedDoc.save(getArtifactsDir() + "AI.AiGrammar.docx"); + //ExEnd:AiGrammar + } +} + diff --git a/Examples/DocsExamples/JavaPorting/CsPorterConfig.xml b/Examples/DocsExamples/JavaPorting/CsPorterConfig.xml new file mode 100644 index 00000000..35ac43ee --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/CsPorterConfig.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/DocsExamples/JavaPorting/CsPorterReport.xml b/Examples/DocsExamples/JavaPorting/CsPorterReport.xml new file mode 100644 index 00000000..7ed64fc4 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/CsPorterReport.xml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/DocsExamples/JavaPorting/DocsExamplesBase.java b/Examples/DocsExamples/JavaPorting/DocsExamplesBase.java new file mode 100644 index 00000000..46e3e6e5 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/DocsExamplesBase.java @@ -0,0 +1,144 @@ +package DocsExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import com.aspose.ms.System.msUri; +import org.testng.annotations.BeforeTest; +import com.aspose.ms.System.Threading.CurrentThread; +import com.aspose.ms.System.Globalization.msCultureInfo; +import com.aspose.ms.System.IO.Directory; +import org.testng.annotations.BeforeMethod; +import com.aspose.ms.System.msConsole; +import org.testng.annotations.AfterTest; +import com.aspose.ms.System.IO.Path; +import com.aspose.ms.System.IO.File; +import com.aspose.words.License; +import com.aspose.barcode.License; + + +public class DocsExamplesBase +{ + + @BeforeTest + public static void oneTimeSetUp() throws Exception + { + CurrentThread.setCurrentCulture(msCultureInfo.getInvariantCulture()); + + setUnlimitedLicense(); + + if (!Directory.exists(getArtifactsDir())) + Directory.createDirectory(getArtifactsDir()); + } + + @BeforeMethod (alwaysRun = true) + public static void setUp() + { + System.out.println("Clr: {RuntimeInformation.FrameworkDescription}\n"); + } + + @AfterTest + public static void oneTimeTearDown() throws Exception + { + if (Directory.exists(getArtifactsDir())) + Directory.delete(getArtifactsDir(), true); + } + + static void setUnlimitedLicense() throws Exception + { + // This is where the test license is on my development machine. + String testLicenseFileName = Path.combine(getLicenseDir(), "Aspose.Total.NET.lic"); + + if (File.exists(testLicenseFileName)) + { + // This shows how to use an Aspose.Words license when you have purchased one. + // You don't have to specify full path as shown here. You can specify just the + // file name if you copy the license file into the same folder as your application + // binaries or you add the license to your project as an embedded resource. + License wordsLicense = new License(); + wordsLicense.setLicense(testLicenseFileName); + + License barcodeLicense = new License(); + barcodeLicense.setLicense(testLicenseFileName); + + } + } + + /// + /// Returns the code-base directory. + /// + static String getCodeBaseDir(Assembly assembly) throws Exception + { + msUri uri = new msUri(assembly.Location); + String mainFolder = Path.getDirectoryName(uri.getLocalPath()) + ?.Substring(0, uri.LocalPath.IndexOf("DocsExamples", StringComparison.Ordinal)); + + return mainFolder; + } + + /// + /// Gets the path to the codebase directory. + /// + static String getMainDataDir() { return mMainDataDir; }; + + private static String mMainDataDir; + + /// + /// Gets the path to the documents used by the code examples. + /// + public static String getMyDir() { return mMyDir; }; + + private static String mMyDir; + + /// + /// Gets the path to the images used by the code examples. + /// + static String getImagesDir() { return mImagesDir; }; + + private static String mImagesDir; + + /// + /// Gets the path of the demo database. + /// + static String getDatabaseDir() { return mDatabaseDir; }; + + private static String mDatabaseDir; + + /// + /// Gets the path to the license used by the code examples. + /// + static String getLicenseDir() { return mLicenseDir; }; + + private static String mLicenseDir; + + /// + /// Gets the path to the artifacts used by the code examples. + /// + static String getArtifactsDir() { return mArtifactsDir; }; + + private static String mArtifactsDir; + + /// + /// Gets the path of the free fonts. Ends with a back slash. + /// + static String getFontsDir() { return mFontsDir; }; + + private static String mFontsDir; + static/* DocsExamplesBase()*/ + { + /*JAVA-added try/catch to wrap a checked exception into unchecked one*/ + try + { + mMainDataDir = getCodeBaseDir(Assembly.GetExecutingAssembly()); + mArtifactsDir = new msUri(new msUri(getMainDataDir()), "Data/Artifacts/").getLocalPath(); + mMyDir = new msUri(new msUri(getMainDataDir()), "Data/").getLocalPath(); + mImagesDir = new msUri(new msUri(getMainDataDir()), "Data/Images/").getLocalPath(); + mLicenseDir = new msUri(new msUri(getMainDataDir()), "Data/License/").getLocalPath(); + mDatabaseDir = new msUri(new msUri(getMainDataDir()), "Data/Database/").getLocalPath(); + mFontsDir = new msUri(new msUri(getMainDataDir()), "Data/MyFonts/").getLocalPath(); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/BaseConversions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/BaseConversions.java new file mode 100644 index 00000000..b300cff4 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/BaseConversions.java @@ -0,0 +1,335 @@ +package DocsExamples.File_Formats_and_Conversions; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.ms.System.IO.Stream; +import java.io.FileInputStream; +import com.aspose.ms.System.IO.File; +import com.aspose.ms.System.IO.MemoryStream; +import com.aspose.words.SaveFormat; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.FindReplaceOptions; +import com.aspose.words.XlsxSaveOptions; +import com.aspose.words.CompressionLevel; +import com.aspose.ms.System.msConsole; +import java.awt.image.BufferedImage; +import javax.imageio.ImageIO; +import com.aspose.words.BreakType; +import com.aspose.words.PageSetup; +import com.aspose.words.ConvertUtil; +import com.aspose.words.RelativeHorizontalPosition; +import com.aspose.words.RelativeVerticalPosition; +import com.aspose.words.WrapType; + + +public class BaseConversions extends DocsExamplesBase +{ + @Test + public void docToDocx() throws Exception + { + //ExStart:LoadAndSave + //GistId:7ee438947078cf070c5bc36a4e45a18c + //ExStart:OpenDocument + Document doc = new Document(getMyDir() + "Document.doc"); + //ExEnd:OpenDocument + + doc.save(getArtifactsDir() + "BaseConversions.DocToDocx.docx"); + //ExEnd:LoadAndSave + } + + @Test + public void docxToRtf() throws Exception + { + //ExStart:LoadAndSaveToStream + //GistId:7ee438947078cf070c5bc36a4e45a18c + //ExStart:OpenFromStream + //GistId:1d626c7186a318d22d022dc96dd91d55 + // Read only access is enough for Aspose.Words to load a document. + Document doc; + Stream stream = new FileInputStream(getMyDir() + "Document.docx"); + try /*JAVA: was using*/ + { + doc = new Document(stream); + } + finally { if (stream != null) stream.close(); } + //ExEnd:OpenFromStream + + // ... do something with the document. + + // Convert the document to a different format and save to stream. + MemoryStream dstStream = new MemoryStream(); + try /*JAVA: was using*/ + { + doc.save(dstStream, SaveFormat.RTF); + // Rewind the stream position back to zero so it is ready for the next reader. + dstStream.setPosition(0); + + File.writeAllBytes(getArtifactsDir() + "BaseConversions.DocxToRtf.rtf", dstStream.toArray()); + } + finally { if (dstStream != null) dstStream.close(); } + //ExEnd:LoadAndSaveToStream + } + + @Test + public void docxToPdf() throws Exception + { + //ExStart:DocxToPdf + //GistId:a53bdaad548845275c1b9556ee21ae65 + Document doc = new Document(getMyDir() + "Document.docx"); + + doc.save(getArtifactsDir() + "BaseConversions.DocxToPdf.pdf"); + //ExEnd:DocxToPdf + } + + @Test + public void docxToByte() throws Exception + { + //ExStart:DocxToByte + //GistId:f8a622f8bc1cf3c2fa8a7a9be359faa2 + Document doc = new Document(getMyDir() + "Document.docx"); + + MemoryStream outStream = new MemoryStream(); + doc.save(outStream, SaveFormat.DOCX); + + byte[] docBytes = outStream.toArray(); + MemoryStream inStream = new MemoryStream(docBytes); + + Document docFromBytes = new Document(inStream); + //ExEnd:DocxToByte + } + + @Test + public void docxToEpub() throws Exception + { + //ExStart:DocxToEpub + Document doc = new Document(getMyDir() + "Document.docx"); + + doc.save(getArtifactsDir() + "BaseConversions.DocxToEpub.epub"); + //ExEnd:DocxToEpub + } + + @Test + public void docxToHtml() throws Exception + { + //ExStart:DocxToHtml + //GistId:c0df00d37081f41a7683339fd7ef66c1 + Document doc = new Document(getMyDir() + "Document.docx"); + + doc.save(getArtifactsDir() + "BaseConversions.DocxToHtml.html"); + //ExEnd:DocxToHtml + } + + @Test (enabled = false, description = "Only for example") + public void docxToMhtml() throws Exception + { + //ExStart:DocxToMhtml + //GistId:537e7d4e2ddd23fa701dc4bf315064b9 + Document doc = new Document(getMyDir() + "Document.docx"); + + Stream stream = new MemoryStream(); + doc.save(stream, SaveFormat.MHTML); + + // Rewind the stream to the beginning so Aspose.Email can read it. + stream.setPosition(0); + + // Create an Aspose.Email MIME email message from the stream. + MailMessage message = MailMessage.Load(stream, new MhtmlLoadOptions()); + message.From = "your_from@email.com"; + message.To = "your_to@email.com"; + message.Subject = "Aspose.Words + Aspose.Email MHTML Test Message"; + + // Send the message using Aspose.Email. + SmtpClient client = new SmtpClient(); + client.Host = "your_smtp.com"; + client.Send(message); + //ExEnd:DocxToMhtml + } + + @Test + public void docxToMarkdown() throws Exception + { + //ExStart:DocxToMarkdown + //GistId:51b4cb9c451832f23527892e19c7bca6 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Some text!"); + + doc.save(getArtifactsDir() + "BaseConversions.DocxToMarkdown.md"); + //ExEnd:DocxToMarkdown + } + + @Test + public void docxToTxt() throws Exception + { + //ExStart:DocxToTxt + //GistId:1f94e59ea4838ffac2f0edf921f67060 + Document doc = new Document(getMyDir() + "Document.docx"); + doc.save(getArtifactsDir() + "BaseConversions.DocxToTxt.txt"); + //ExEnd:DocxToTxt + } + + @Test + public void docxToXlsx() throws Exception + { + //ExStart:DocxToXlsx + //GistId:f5a08835e924510d3809e41c3b8b81a2 + Document doc = new Document(getMyDir() + "Document.docx"); + doc.save(getArtifactsDir() + "BaseConversions.DocxToXlsx.xlsx"); + //ExEnd:DocxToXlsx + } + + @Test + public void txtToDocx() throws Exception + { + //ExStart:TxtToDocx + // The encoding of the text file is automatically detected. + Document doc = new Document(getMyDir() + "English text.txt"); + + doc.save(getArtifactsDir() + "BaseConversions.TxtToDocx.docx"); + //ExEnd:TxtToDocx + } + + @Test + public void pdfToJpeg() throws Exception + { + //ExStart:PdfToJpeg + //GistId:ebbb90d74ef57db456685052a18f8e86 + Document doc = new Document(getMyDir() + "Pdf Document.pdf"); + + doc.save(getArtifactsDir() + "BaseConversions.PdfToJpeg.jpeg"); + //ExEnd:PdfToJpeg + } + + @Test + public void pdfToDocx() throws Exception + { + //ExStart:PdfToDocx + //GistId:a0d52b62c1643faa76a465a41537edfc + Document doc = new Document(getMyDir() + "Pdf Document.pdf"); + + doc.save(getArtifactsDir() + "BaseConversions.PdfToDocx.docx"); + //ExEnd:PdfToDocx + } + + @Test + public void pdfToXlsx() throws Exception + { + //ExStart:PdfToXlsx + //GistId:a50652f28531278511605e0fd778bbdf + Document doc = new Document(getMyDir() + "Pdf Document.pdf"); + + doc.save(getArtifactsDir() + "BaseConversions.PdfToXlsx.xlsx"); + //ExEnd:PdfToXlsx + } + + @Test + public void findReplaceXlsx() throws Exception + { + //ExStart:FindReplaceXlsx + //GistId:a50652f28531278511605e0fd778bbdf + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Ruby bought a ruby necklace."); + + // We can use a "FindReplaceOptions" object to modify the find-and-replace process. + FindReplaceOptions options = new FindReplaceOptions(); + + // Set the "MatchCase" flag to "true" to apply case sensitivity while finding strings to replace. + // Set the "MatchCase" flag to "false" to ignore character case while searching for text to replace. + options.setMatchCase(true); + + doc.getRange().replace("Ruby", "Jade", options); + + doc.save(getArtifactsDir() + "BaseConversions.FindReplaceXlsx.xlsx"); + //ExEnd:FindReplaceXlsx + } + + @Test + public void compressXlsx() throws Exception + { + //ExStart:CompressXlsx + //GistId:a50652f28531278511605e0fd778bbdf + Document doc = new Document(getMyDir() + "Document.docx"); + + XlsxSaveOptions saveOptions = new XlsxSaveOptions(); + saveOptions.setCompressionLevel(CompressionLevel.MAXIMUM); + + doc.save(getArtifactsDir() + "BaseConversions.CompressXlsx.xlsx", saveOptions); + //ExEnd:CompressXlsx + } + + @Test + public void imagesToPdf() throws Exception + { + //ExStart:ImageToPdf + //GistId:a53bdaad548845275c1b9556ee21ae65 + convertImageToPdf(getImagesDir() + "Logo.jpg", getArtifactsDir() + "BaseConversions.JpgToPdf.pdf"); + convertImageToPdf(getImagesDir() + "Transparent background logo.png", getArtifactsDir() + "BaseConversions.PngToPdf.pdf"); + convertImageToPdf(getImagesDir() + "Windows MetaFile.wmf", getArtifactsDir() + "BaseConversions.WmfToPdf.pdf"); + convertImageToPdf(getImagesDir() + "Tagged Image File Format.tiff", getArtifactsDir() + "BaseConversions.TiffToPdf.pdf"); + convertImageToPdf(getImagesDir() + "Graphics Interchange Format.gif", getArtifactsDir() + "BaseConversions.GifToPdf.pdf"); + //ExEnd:ImageToPdf + } + + //ExStart:ConvertImageToPdf + //GistId:a53bdaad548845275c1b9556ee21ae65 + /// + /// Converts an image to PDF using Aspose.Words for .NET. + /// + /// File name of input image file. + /// Output PDF file name. + public void convertImageToPdf(String inputFileName, String outputFileName) throws Exception + { + System.out.println("Converting " + inputFileName + " to PDF ...."); + + + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Read the image from file, ensure it is disposed. + BufferedImage image = ImageIO.read(inputFileName); + try /*JAVA: was using*/ + { + // Find which dimension the frames in this image represent. For example + // the frames of a BMP or TIFF are "page dimension" whereas frames of a GIF image are "time dimension". + FrameDimension dimension = new FrameDimension(image.FrameDimensionsList[0]); + + int framesCount = image.GetFrameCount(dimension); + + for (int frameIdx = 0; frameIdx < framesCount; frameIdx++) + { + // Insert a section break before each new page, in case of a multi-frame TIFF. + if (frameIdx != 0) + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + + image.SelectActiveFrame(dimension, frameIdx); + + // We want the size of the page to be the same as the size of the image. + // Convert pixels to points to size the page to the actual image size. + PageSetup ps = builder.getPageSetup(); + ps.setPageWidth(ConvertUtil.pixelToPoint(image.getWidth(), image.HorizontalResolution)); + ps.setPageHeight(ConvertUtil.pixelToPoint(image.getHeight(), image.VerticalResolution)); + + // Insert the image into the document and position it at the top left corner of the page. + builder.insertImage( + image, + RelativeHorizontalPosition.PAGE, + 0.0, + RelativeVerticalPosition.PAGE, + 0.0, + ps.getPageWidth(), + ps.getPageHeight(), + WrapType.NONE); + } + } + finally { if (image != null) image.flush(); } + + doc.save(outputFileName); + } + //ExEnd:ConvertImageToPdf +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Complex_examples_and_helpers/WorkingWithDocumentInDatabase.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Complex_examples_and_helpers/WorkingWithDocumentInDatabase.java new file mode 100644 index 00000000..67e0c2a2 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Complex_examples_and_helpers/WorkingWithDocumentInDatabase.java @@ -0,0 +1,95 @@ +package DocsExamples.File_Formats_and_Conversions.Complex_examples_and_helpers; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.ms.System.IO.MemoryStream; +import com.aspose.words.SaveFormat; +import com.aspose.ms.System.IO.Path; +import com.aspose.words.net.System.Data.DataTable; + + +public class WorkingWithDocumentInDatabase extends DocsExamplesBase +{ + @Test (groups = "IgnoreOnJenkins") + public void loadAndSaveDocToDatabase() throws Exception + { + Document doc = new Document(getMyDir() + "Document.docx"); + //ExStart:OpenDatabaseConnection + //GistId:f8a622f8bc1cf3c2fa8a7a9be359faa2 + String connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + getDatabaseDir() + "Northwind.accdb"; + + OleDbConnection connection = new OleDbConnection(connString); + connection.Open(); + //ExEnd:OpenDatabaseConnection + + //ExStart:OpenRetrieveAndDelete + //GistId:f8a622f8bc1cf3c2fa8a7a9be359faa2 + storeToDatabase(doc, connection); + + Document dbDoc = readFromDatabase("Document.docx", connection); + dbDoc.save(getArtifactsDir() + "WorkingWithDocumentInDatabase.LoadAndSaveDocToDatabase.docx"); + + deleteFromDatabase("Document.docx", connection); + + connection.Close(); + //ExEnd:OpenRetrieveAndDelete + } + + //ExStart:StoreToDatabase + //GistId:f8a622f8bc1cf3c2fa8a7a9be359faa2 + public void storeToDatabase(Document doc, OleDbConnection connection) throws Exception + { + MemoryStream stream = new MemoryStream(); + doc.save(stream, SaveFormat.DOCX); + + String fileName = Path.getFileName(doc.getOriginalFileName()); + String commandString = "INSERT INTO Documents (Name, Data) VALUES('" + fileName + "', @Doc)"; + + OleDbCommand command = new OleDbCommand(commandString, connection); + command.Parameters.AddWithValue("Doc", stream.toArray()); + command.ExecuteNonQuery(); + } + //ExEnd:StoreToDatabase + + //ExStart:ReadFromDatabase + //GistId:f8a622f8bc1cf3c2fa8a7a9be359faa2 + public Document readFromDatabase(String fileName, OleDbConnection connection) throws Exception + { + String commandString = "SELECT * FROM Documents WHERE Name='" + fileName + "'"; + + OleDbCommand command = new OleDbCommand(commandString, connection); + OleDbDataAdapter adapter = new OleDbDataAdapter(command); + + DataTable dataTable = new DataTable(); + adapter.Fill(dataTable); + + if (dataTable.getRows().getCount() == 0) + throw new IllegalArgumentException( + $"Could not find any record matching the document \"{fileName}\" in the database."); + + // The document is stored in byte form in the FileContent column. + // Retrieve these bytes of the first matching record to a new buffer. + byte[] buffer = (byte[]) dataTable.getRows().get(0).get("Data"); + + MemoryStream newStream = new MemoryStream(buffer); + + Document doc = new Document(newStream); + + return doc; + } + //ExEnd:ReadFromDatabase + + //ExStart:DeleteFromDatabase + //GistId:f8a622f8bc1cf3c2fa8a7a9be359faa2 + public void deleteFromDatabase(String fileName, OleDbConnection connection) + { + String commandString = "DELETE * FROM Documents WHERE Name='" + fileName + "'"; + + OleDbCommand command = new OleDbCommand(commandString, connection); + command.ExecuteNonQuery(); + } + //ExEnd:DeleteFromDatabase +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Load_options/WorkingWithHtmlLoadOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Load_options/WorkingWithHtmlLoadOptions.java new file mode 100644 index 00000000..db705e37 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Load_options/WorkingWithHtmlLoadOptions.java @@ -0,0 +1,30 @@ +package DocsExamples.File_Formats_and_Conversions.Load_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.HtmlLoadOptions; +import com.aspose.words.HtmlControlType; +import com.aspose.words.Document; +import com.aspose.ms.System.IO.MemoryStream; +import com.aspose.ms.System.Text.Encoding; +import com.aspose.words.SaveFormat; + + +public class WorkingWithHtmlLoadOptions extends DocsExamplesBase +{ + @Test + public void preferredControlType() throws Exception + { + //ExStart:LoadHtmlElementsWithPreferredControlType + final String HTML = "\n \n \n \n "; + + HtmlLoadOptions loadOptions = new HtmlLoadOptions(); { loadOptions.setPreferredControlType(HtmlControlType.STRUCTURED_DOCUMENT_TAG); } + + Document doc = new Document(new MemoryStream(Encoding.getUTF8().getBytes(HTML)), loadOptions); + + doc.save(getArtifactsDir() + "WorkingWithHtmlLoadOptions.PreferredControlType.docx", SaveFormat.DOCX); + //ExEnd:LoadHtmlElementsWithPreferredControlType + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Load_options/WorkingWithLoadOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Load_options/WorkingWithLoadOptions.java new file mode 100644 index 00000000..9f9b68c7 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Load_options/WorkingWithLoadOptions.java @@ -0,0 +1,229 @@ +package DocsExamples.File_Formats_and_Conversions.Load_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.LoadOptions; +import com.aspose.words.Document; +import com.aspose.words.OdtSaveOptions; +import org.testng.Assert; +import com.aspose.words.IncorrectPasswordException; +import com.aspose.words.SaveFormat; +import com.aspose.words.MsWordVersion; +import com.aspose.words.IWarningCallback; +import com.aspose.words.WarningInfo; +import com.aspose.ms.System.msConsole; +import com.aspose.words.IResourceLoadingCallback; +import com.aspose.words.ResourceLoadingAction; +import com.aspose.words.ResourceLoadingArgs; +import com.aspose.words.ResourceType; +import java.awt.image.BufferedImage; +import javax.imageio.ImageIO; +import com.aspose.ms.System.Text.Encoding; +import com.aspose.words.PdfLoadOptions; + + +public class WorkingWithLoadOptions extends DocsExamplesBase +{ + @Test + public void updateDirtyFields() throws Exception + { + //ExStart:UpdateDirtyFields + //GistId:08db64c4d86842c4afd1ecb925ed07c4 + LoadOptions loadOptions = new LoadOptions(); { loadOptions.setUpdateDirtyFields(true); } + + Document doc = new Document(getMyDir() + "Dirty field.docx", loadOptions); + + doc.save(getArtifactsDir() + "WorkingWithLoadOptions.UpdateDirtyFields.docx"); + //ExEnd:UpdateDirtyFields + } + + @Test + public void loadEncryptedDocument() throws Exception + { + //ExStart:LoadSaveEncryptedDocument + //GistId:af95c7a408187bb25cf9137465fe5ce6 + //ExStart:OpenEncryptedDocument + //GistId:40be8275fc43f78f5e5877212e4e1bf3 + Document doc = new Document(getMyDir() + "Encrypted.docx", new LoadOptions("docPassword")); + //ExEnd:OpenEncryptedDocument + + doc.save(getArtifactsDir() + "WorkingWithLoadOptions.LoadSaveEncryptedDocument.odt", new OdtSaveOptions("newPassword")); + //ExEnd:LoadSaveEncryptedDocument + } + + @Test + public void loadEncryptedDocumentWithoutPassword() throws Exception + { + //ExStart:LoadEncryptedDocumentWithoutPassword + //GistId:af95c7a408187bb25cf9137465fe5ce6 + // We will not be able to open this document with Microsoft Word or + // Aspose.Words without providing the correct password. + Assert.Throws(() => + new Document(getMyDir() + "Encrypted.docx")); + //ExEnd:LoadEncryptedDocumentWithoutPassword + } + + @Test + public void convertShapeToOfficeMath() throws Exception + { + //ExStart:ConvertShapeToOfficeMath + //GistId:ad463bf5f128fe6e6c1485df3c046a4c + LoadOptions loadOptions = new LoadOptions(); { loadOptions.setConvertShapeToOfficeMath(true); } + + Document doc = new Document(getMyDir() + "Office math.docx", loadOptions); + + doc.save(getArtifactsDir() + "WorkingWithLoadOptions.ConvertShapeToOfficeMath.docx", SaveFormat.DOCX); + //ExEnd:ConvertShapeToOfficeMath + } + + @Test + public void setMsWordVersion() throws Exception + { + //ExStart:SetMsWordVersion + //GistId:40be8275fc43f78f5e5877212e4e1bf3 + // Create a new LoadOptions object, which will load documents according to MS Word 2019 specification by default + // and change the loading version to Microsoft Word 2010. + LoadOptions loadOptions = new LoadOptions(); { loadOptions.setMswVersion(MsWordVersion.WORD_2010); } + + Document doc = new Document(getMyDir() + "Document.docx", loadOptions); + + doc.save(getArtifactsDir() + "WorkingWithLoadOptions.SetMsWordVersion.docx"); + //ExEnd:SetMsWordVersion + } + + @Test + public void tempFolder() throws Exception + { + //ExStart:TempFolder + //GistId:40be8275fc43f78f5e5877212e4e1bf3 + LoadOptions loadOptions = new LoadOptions(); { loadOptions.setTempFolder(getArtifactsDir()); } + + Document doc = new Document(getMyDir() + "Document.docx", loadOptions); + //ExEnd:TempFolder + } + + @Test + public void warningCallback() throws Exception + { + //ExStart:WarningCallback + //GistId:40be8275fc43f78f5e5877212e4e1bf3 + LoadOptions loadOptions = new LoadOptions(); { loadOptions.setWarningCallback(new DocumentLoadingWarningCallback()); } + + Document doc = new Document(getMyDir() + "Document.docx", loadOptions); + //ExEnd:WarningCallback + } + + //ExStart:IWarningCallback + //GistId:40be8275fc43f78f5e5877212e4e1bf3 + public static class DocumentLoadingWarningCallback implements IWarningCallback + { + public void warning(WarningInfo info) + { + // Prints warnings and their details as they arise during document loading. + System.out.println("WARNING: {info.WarningType}, source: {info.Source}"); + System.out.println("\tDescription: {info.Description}"); + } + } + //ExEnd:IWarningCallback + + @Test + public void resourceLoadingCallback() throws Exception + { + //ExStart:ResourceLoadingCallback + //GistId:40be8275fc43f78f5e5877212e4e1bf3 + LoadOptions loadOptions = new LoadOptions(); { loadOptions.setResourceLoadingCallback(new HtmlLinkedResourceLoadingCallback()); } + + // When we open an Html document, external resources such as references to CSS stylesheet files + // and external images will be handled customarily by the loading callback as the document is loaded. + Document doc = new Document(getMyDir() + "Images.html", loadOptions); + + doc.save(getArtifactsDir() + "WorkingWithLoadOptions.ResourceLoadingCallback.pdf"); + //ExEnd:ResourceLoadingCallback + } + + //ExStart:IResourceLoadingCallback + //GistId:40be8275fc43f78f5e5877212e4e1bf3 + private static class HtmlLinkedResourceLoadingCallback implements IResourceLoadingCallback + { + public /*ResourceLoadingAction*/int resourceLoading(ResourceLoadingArgs args) + { + switch (args.getResourceType()) + { + case ResourceType.CSS_STYLE_SHEET: + { + System.out.println("External CSS Stylesheet found upon loading: {args.OriginalUri}"); + + // CSS file will don't used in the document. + return ResourceLoadingAction.SKIP; + } + case ResourceType.IMAGE: + { + // Replaces all images with a substitute. + BufferedImage newImage = ImageIO.read(getImagesDir() + "Logo.jpg"); + + ImageConverter converter = new ImageConverter(); + byte[] imageBytes = (byte[])converter.ConvertTo(newImage, byte[].class); + + args.setData(imageBytes); + + // New images will be used instead of presented in the document. + return ResourceLoadingAction.USER_PROVIDED; + } + case ResourceType.DOCUMENT: + { + System.out.println("External document found upon loading: {args.OriginalUri}"); + + // Will be used as usual. + return ResourceLoadingAction.DEFAULT; + } + default: + throw new IllegalStateException("Unexpected ResourceType value."); + } + } + } + //ExEnd:IResourceLoadingCallback + + @Test + public void loadWithEncoding() throws Exception + { + //ExStart:LoadWithEncoding + //GistId:40be8275fc43f78f5e5877212e4e1bf3 + LoadOptions loadOptions = new LoadOptions(); { loadOptions.setEncoding(Encoding.getASCII()); } + + // Load the document while passing the LoadOptions object, then verify the document's contents. + Document doc = new Document(getMyDir() + "English text.txt", loadOptions); + //ExEnd:LoadWithEncoding + } + + @Test + public void skipPdfImages() throws Exception + { + //ExStart:SkipPdfImages + PdfLoadOptions loadOptions = new PdfLoadOptions(); { loadOptions.setSkipPdfImages(true); } + + Document doc = new Document(getMyDir() + "Pdf Document.pdf", loadOptions); + //ExEnd:SkipPdfImages + } + + @Test + public void convertMetafilesToPng() throws Exception + { + //ExStart:ConvertMetafilesToPng + LoadOptions loadOptions = new LoadOptions(); { loadOptions.setConvertMetafilesToPng(true); } + + Document doc = new Document(getMyDir() + "WMF with image.docx", loadOptions); + //ExEnd:ConvertMetafilesToPng + } + + @Test + public void loadChm() throws Exception + { + //ExStart:LoadCHM + LoadOptions loadOptions = new LoadOptions(); { loadOptions.setEncoding(Encoding.getEncoding("windows-1251")); } + + Document doc = new Document(getMyDir() + "HTML help.chm", loadOptions); + //ExEnd:LoadCHM + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Load_options/WorkingWithPdfLoadOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Load_options/WorkingWithPdfLoadOptions.java new file mode 100644 index 00000000..af75379b --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Load_options/WorkingWithPdfLoadOptions.java @@ -0,0 +1,49 @@ +package DocsExamples.File_Formats_and_Conversions.Load_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.PdfSaveOptions; +import com.aspose.words.PdfEncryptionDetails; +import com.aspose.words.PdfLoadOptions; +import com.aspose.words.LoadFormat; + + +public class WorkingWithPdfLoadOptions extends DocsExamplesBase +{ + @Test + public void loadEncryptedPdf() throws Exception + { + //ExStart:LoadEncryptedPdf + Document doc = new Document(getMyDir() + "Pdf Document.pdf"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + { + saveOptions.setEncryptionDetails(new PdfEncryptionDetails("Aspose", null)); + } + + doc.save(getArtifactsDir() + "WorkingWithPdfLoadOptions.LoadEncryptedPdf.pdf", saveOptions); + + PdfLoadOptions loadOptions = new PdfLoadOptions(); { loadOptions.setPassword("Aspose"); loadOptions.setLoadFormat(LoadFormat.PDF); } + + doc = new Document(getArtifactsDir() + "WorkingWithPdfLoadOptions.LoadEncryptedPdf.pdf", loadOptions); + //ExEnd:LoadEncryptedPdf + } + + @Test + public void loadPageRangeOfPdf() throws Exception + { + //ExStart:LoadPageRangeOfPdf + PdfLoadOptions loadOptions = new PdfLoadOptions(); { loadOptions.setPageIndex(0); loadOptions.setPageCount(1); } + + //ExStart:LoadPDF + Document doc = new Document(getMyDir() + "Pdf Document.pdf", loadOptions); + + doc.save(getArtifactsDir() + "WorkingWithPdfLoadOptions.LoadPageRangeOfPdf.pdf"); + //ExEnd:LoadPDF + //ExEnd:LoadPageRangeOfPdf + } +} + diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Load_options/WorkingWithRtfLoadOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Load_options/WorkingWithRtfLoadOptions.java new file mode 100644 index 00000000..c9a8744b --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Load_options/WorkingWithRtfLoadOptions.java @@ -0,0 +1,24 @@ +package DocsExamples.File_Formats_and_Conversions.Load_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.RtfLoadOptions; +import com.aspose.words.Document; + + +public class WorkingWithRtfLoadOptions extends DocsExamplesBase +{ + @Test + public void recognizeUtf8Text() throws Exception + { + //ExStart:RecognizeUtf8Text + RtfLoadOptions loadOptions = new RtfLoadOptions(); { loadOptions.setRecognizeUtf8Text(true); } + + Document doc = new Document(getMyDir() + "UTF-8 characters.rtf", loadOptions); + + doc.save(getArtifactsDir() + "WorkingWithRtfLoadOptions.RecognizeUtf8Text.rtf"); + //ExEnd:RecognizeUtf8Text + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Load_options/WorkingWithTxtLoadOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Load_options/WorkingWithTxtLoadOptions.java new file mode 100644 index 00000000..22d667ac --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Load_options/WorkingWithTxtLoadOptions.java @@ -0,0 +1,144 @@ +package DocsExamples.File_Formats_and_Conversions.Load_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.TxtLoadOptions; +import com.aspose.words.Document; +import com.aspose.ms.System.IO.MemoryStream; +import com.aspose.ms.System.Text.Encoding; +import com.aspose.words.TxtLeadingSpacesOptions; +import com.aspose.words.TxtTrailingSpacesOptions; +import com.aspose.words.DocumentDirection; +import com.aspose.words.Paragraph; +import com.aspose.ms.System.msConsole; +import com.aspose.words.HeaderFooter; +import com.aspose.words.HeaderFooterType; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.BreakType; +import com.aspose.words.TxtSaveOptions; +import com.aspose.words.SaveFormat; +import com.aspose.words.TxtExportHeadersFootersMode; + + +public class WorkingWithTxtLoadOptions extends DocsExamplesBase +{ + @Test + public void detectNumberingWithWhitespaces() throws Exception + { + //ExStart:DetectNumberingWithWhitespaces + //GistId:ddafc3430967fb4f4f70085fa577d01a + // Create a plaintext document in the form of a string with parts that may be interpreted as lists. + // Upon loading, the first three lists will always be detected by Aspose.Words, + // and List objects will be created for them after loading. + final String TEXT_DOC = "Full stop delimiters:\n" + + "1. First list item 1\n" + + "2. First list item 2\n" + + "3. First list item 3\n\n" + + "Right bracket delimiters:\n" + + "1) Second list item 1\n" + + "2) Second list item 2\n" + + "3) Second list item 3\n\n" + + "Bullet delimiters:\n" + + "• Third list item 1\n" + + "• Third list item 2\n" + + "• Third list item 3\n\n" + + "Whitespace delimiters:\n" + + "1 Fourth list item 1\n" + + "2 Fourth list item 2\n" + + "3 Fourth list item 3"; + + // The fourth list, with whitespace inbetween the list number and list item contents, + // will only be detected as a list if "DetectNumberingWithWhitespaces" in a LoadOptions object is set to true, + // to avoid paragraphs that start with numbers being mistakenly detected as lists. + TxtLoadOptions loadOptions = new TxtLoadOptions(); { loadOptions.setDetectNumberingWithWhitespaces(true); } + + // Load the document while applying LoadOptions as a parameter and verify the result. + Document doc = new Document(new MemoryStream(Encoding.getUTF8().getBytes(TEXT_DOC)), loadOptions); + + doc.save(getArtifactsDir() + "WorkingWithTxtLoadOptions.DetectNumberingWithWhitespaces.docx"); + //ExEnd:DetectNumberingWithWhitespaces + } + + @Test + public void handleSpacesOptions() throws Exception + { + //ExStart:HandleSpacesOptions + //GistId:ddafc3430967fb4f4f70085fa577d01a + final String TEXT_DOC = " Line 1 \n" + + " Line 2 \n" + + " Line 3 "; + + TxtLoadOptions loadOptions = new TxtLoadOptions(); + { + loadOptions.setLeadingSpacesOptions(TxtLeadingSpacesOptions.TRIM); + loadOptions.setTrailingSpacesOptions(TxtTrailingSpacesOptions.TRIM); + } + + Document doc = new Document(new MemoryStream(Encoding.getUTF8().getBytes(TEXT_DOC)), loadOptions); + + doc.save(getArtifactsDir() + "WorkingWithTxtLoadOptions.HandleSpacesOptions.docx"); + //ExEnd:HandleSpacesOptions + } + + @Test + public void documentTextDirection() throws Exception + { + //ExStart:DocumentTextDirection + //GistId:ddafc3430967fb4f4f70085fa577d01a + TxtLoadOptions loadOptions = new TxtLoadOptions(); { loadOptions.setDocumentDirection(DocumentDirection.AUTO); } + + Document doc = new Document(getMyDir() + "Hebrew text.txt", loadOptions); + + Paragraph paragraph = doc.getFirstSection().getBody().getFirstParagraph(); + msConsole.writeLine(paragraph.getParagraphFormat().getBidi()); + + doc.save(getArtifactsDir() + "WorkingWithTxtLoadOptions.DocumentTextDirection.docx"); + //ExEnd:DocumentTextDirection + } + + @Test + public void exportHeadersFootersMode() throws Exception + { + //ExStart:ExportHeadersFootersMode + //GistId:ddafc3430967fb4f4f70085fa577d01a + Document doc = new Document(); + + // Insert even and primary headers/footers into the document. + // The primary header/footers will override the even headers/footers. + doc.getFirstSection().getHeadersFooters().add(new HeaderFooter(doc, HeaderFooterType.HEADER_EVEN)); + doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.HEADER_EVEN).appendParagraph("Even header"); + doc.getFirstSection().getHeadersFooters().add(new HeaderFooter(doc, HeaderFooterType.FOOTER_EVEN)); + doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_EVEN).appendParagraph("Even footer"); + doc.getFirstSection().getHeadersFooters().add(new HeaderFooter(doc, HeaderFooterType.HEADER_PRIMARY)); + doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.HEADER_PRIMARY).appendParagraph("Primary header"); + doc.getFirstSection().getHeadersFooters().add(new HeaderFooter(doc, HeaderFooterType.FOOTER_PRIMARY)); + doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY).appendParagraph("Primary footer"); + + // Insert pages to display these headers and footers. + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Page 1"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 2"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.write("Page 3"); + + TxtSaveOptions options = new TxtSaveOptions(); + options.setSaveFormat(SaveFormat.TEXT); + + // All headers and footers are placed at the very end of the output document. + options.setExportHeadersFootersMode(TxtExportHeadersFootersMode.ALL_AT_END); + doc.save(getArtifactsDir() + "WorkingWithTxtLoadOptions.HeadersFootersMode.AllAtEnd.txt", options); + + // Only primary headers and footers are exported at the beginning and end of each section. + options.setExportHeadersFootersMode(TxtExportHeadersFootersMode.PRIMARY_ONLY); + doc.save(getArtifactsDir() + "WorkingWithTxtLoadOptions.HeadersFootersMode.PrimaryOnly.txt", options); + + // No headers and footers are exported. + options.setExportHeadersFootersMode(TxtExportHeadersFootersMode.NONE); + doc.save(getArtifactsDir() + "WorkingWithTxtLoadOptions.HeadersFootersMode.None.txt", options); + //ExEnd:ExportHeadersFootersMode + } +} + diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with DocSaveOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with DocSaveOptions.java new file mode 100644 index 00000000..5d097be5 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with DocSaveOptions.java @@ -0,0 +1,52 @@ +package DocsExamples.File_Formats_and_Conversions.Save_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.DocSaveOptions; + + +public class WorkingWithDocSaveOptions extends DocsExamplesBase +{ + @Test + public void encryptDocumentWithPassword() throws Exception + { + //ExStart:EncryptDocumentWithPassword + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Hello world!"); + + DocSaveOptions saveOptions = new DocSaveOptions(); { saveOptions.setPassword("password"); } + + doc.save(getArtifactsDir() + "WorkingWithDocSaveOptions.EncryptDocumentWithPassword.docx", saveOptions); + //ExEnd:EncryptDocumentWithPassword + } + + @Test + public void doNotCompressSmallMetafiles() throws Exception + { + //ExStart:DoNotCompressSmallMetafiles + Document doc = new Document(getMyDir() + "Microsoft equation object.docx"); + + DocSaveOptions saveOptions = new DocSaveOptions(); { saveOptions.setAlwaysCompressMetafiles(false); } + + doc.save(getArtifactsDir() + "WorkingWithDocSaveOptions.NotCompressSmallMetafiles.docx", saveOptions); + //ExEnd:DoNotCompressSmallMetafiles + } + + @Test + public void doNotSavePictureBullet() throws Exception + { + //ExStart:DoNotSavePictureBullet + Document doc = new Document(getMyDir() + "Image bullet points.docx"); + + DocSaveOptions saveOptions = new DocSaveOptions(); { saveOptions.setSavePictureBullet(false); } + + doc.save(getArtifactsDir() + "WorkingWithDocSaveOptions.DoNotSavePictureBullet.docx", saveOptions); + //ExEnd:DoNotSavePictureBullet + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with HtmlFixedSaveOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with HtmlFixedSaveOptions.java new file mode 100644 index 00000000..b945ff57 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with HtmlFixedSaveOptions.java @@ -0,0 +1,38 @@ +package DocsExamples.File_Formats_and_Conversions.Save_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.HtmlFixedSaveOptions; + + +public class WorkingWithHtmlFixedSaveOptions extends DocsExamplesBase +{ + @Test + public void useFontFromTargetMachine() throws Exception + { + //ExStart:UseFontFromTargetMachine + Document doc = new Document(getMyDir() + "Bullet points with alternative font.docx"); + + HtmlFixedSaveOptions saveOptions = new HtmlFixedSaveOptions(); { saveOptions.setUseTargetMachineFonts(true); } + + doc.save(getArtifactsDir() + "WorkingWithHtmlFixedSaveOptions.UseFontFromTargetMachine.html", saveOptions); + //ExEnd:UseFontFromTargetMachine + } + + @Test + public void writeAllCssRulesInSingleFile() throws Exception + { + //ExStart:WriteAllCssRulesInSingleFile + Document doc = new Document(getMyDir() + "Document.docx"); + + // Setting this property to true restores the old behavior (separate files) for compatibility with legacy code. + // All CSS rules are written into single file "styles.css. + HtmlFixedSaveOptions saveOptions = new HtmlFixedSaveOptions(); { saveOptions.setSaveFontFaceCssSeparately(false); } + + doc.save(getArtifactsDir() + "WorkingWithHtmlFixedSaveOptions.WriteAllCssRulesInSingleFile.html", saveOptions); + //ExEnd:WriteAllCssRulesInSingleFile + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with HtmlSaveOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with HtmlSaveOptions.java new file mode 100644 index 00000000..918eab77 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with HtmlSaveOptions.java @@ -0,0 +1,163 @@ +package DocsExamples.File_Formats_and_Conversions.Save_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.HtmlSaveOptions; +import com.aspose.words.CssStyleSheetType; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.HtmlMetafileFormat; +import com.aspose.words.SaveFormat; +import com.aspose.ms.System.IO.Path; +import com.aspose.ms.System.IO.Directory; + + +public class WorkingWithHtmlSaveOptions extends DocsExamplesBase +{ + @Test + public void exportRoundtripInformation() throws Exception + { + //ExStart:ExportRoundtripInformation + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); { saveOptions.setExportRoundtripInformation(true); } + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ExportRoundtripInformation.html", saveOptions); + //ExEnd:ExportRoundtripInformation + } + + @Test + public void exportFontsAsBase64() throws Exception + { + //ExStart:ExportFontsAsBase64 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); { saveOptions.setExportFontsAsBase64(true); } + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ExportFontsAsBase64.html", saveOptions); + //ExEnd:ExportFontsAsBase64 + } + + @Test + public void exportResources() throws Exception + { + //ExStart:ExportResources + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + { + saveOptions.setCssStyleSheetType(CssStyleSheetType.EXTERNAL); + saveOptions.setExportFontResources(true); + saveOptions.setResourceFolder(getArtifactsDir() + "Resources"); + saveOptions.setResourceFolderAlias("http://example.com/resources"); + } + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ExportResources.html", saveOptions); + //ExEnd:ExportResources + } + + @Test + public void convertMetafilesToEmfOrWmf() throws Exception + { + //ExStart:ConvertMetafilesToEmfOrWmf + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Here is an image as is: "); + builder.insertHtml( + "\"Red"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); { saveOptions.setMetafileFormat(HtmlMetafileFormat.EMF_OR_WMF); } + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ConvertMetafilesToEmfOrWmf.html", saveOptions); + //ExEnd:ConvertMetafilesToEmfOrWmf + } + + @Test + public void convertMetafilesToSvg() throws Exception + { + //ExStart:ConvertMetafilesToSvg + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Here is an SVG image: "); + builder.insertHtml( + "\r\n \r\n "); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); { saveOptions.setMetafileFormat(HtmlMetafileFormat.SVG); } + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ConvertMetafilesToSvg.html", saveOptions); + //ExEnd:ConvertMetafilesToSvg + } + + @Test + public void addCssClassNamePrefix() throws Exception + { + //ExStart:AddCssClassNamePrefix + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + { + saveOptions.setCssStyleSheetType(CssStyleSheetType.EXTERNAL); saveOptions.setCssClassNamePrefix("pfx_"); + } + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.AddCssClassNamePrefix.html", saveOptions); + //ExEnd:AddCssClassNamePrefix + } + + @Test + public void exportCidUrlsForMhtmlResources() throws Exception + { + //ExStart:ExportCidUrlsForMhtmlResources + Document doc = new Document(getMyDir() + "Content-ID.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(SaveFormat.MHTML); + { + saveOptions.setPrettyFormat(true); saveOptions.setExportCidUrlsForMhtmlResources(true); + } + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ExportCidUrlsForMhtmlResources.mhtml", saveOptions); + //ExEnd:ExportCidUrlsForMhtmlResources + } + + @Test + public void resolveFontNames() throws Exception + { + //ExStart:ResolveFontNames + Document doc = new Document(getMyDir() + "Missing font.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(SaveFormat.HTML); + { + saveOptions.setPrettyFormat(true); saveOptions.setResolveFontNames(true); + } + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ResolveFontNames.html", saveOptions); + //ExEnd:ResolveFontNames + } + + @Test + public void exportTextInputFormFieldAsText() throws Exception + { + //ExStart:ExportTextInputFormFieldAsText + Document doc = new Document(getMyDir() + "Rendering.docx"); + + String imagesDir = Path.combine(getArtifactsDir(), "Images"); + + // The folder specified needs to exist and should be empty. + if (Directory.exists(imagesDir)) + Directory.delete(imagesDir, true); + + Directory.createDirectory(imagesDir); + + // Set an option to export form fields as plain text, not as HTML input elements. + HtmlSaveOptions saveOptions = new HtmlSaveOptions(SaveFormat.HTML); + { + saveOptions.setExportTextInputFormFieldAsText(true); saveOptions.setImagesFolder(imagesDir); + } + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ExportTextInputFormFieldAsText.html", saveOptions); + //ExEnd:ExportTextInputFormFieldAsText + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with ImageSaveOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with ImageSaveOptions.java new file mode 100644 index 00000000..8924a14f --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with ImageSaveOptions.java @@ -0,0 +1,125 @@ +package DocsExamples.File_Formats_and_Conversions.Save_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.ImageSaveOptions; +import com.aspose.words.SaveFormat; +import com.aspose.words.TiffCompression; +import com.aspose.words.ImageColorMode; +import com.aspose.words.ImageBinarizationMethod; +import com.aspose.words.PageSet; +import com.aspose.words.PageRange; +import com.aspose.words.ImagePixelFormat; +import com.aspose.words.IPageSavingCallback; +import com.aspose.words.PageSavingArgs; +import java.text.MessageFormat; + + +public class WorkingWithImageSaveOptions extends DocsExamplesBase +{ + @Test + public void exposeThresholdControlForTiffBinarization() throws Exception + { + //ExStart:ExposeThresholdControlForTiffBinarization + Document doc = new Document(getMyDir() + "Rendering.docx"); + + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.TIFF); + { + saveOptions.setTiffCompression(TiffCompression.CCITT_3); + saveOptions.setImageColorMode(ImageColorMode.GRAYSCALE); + saveOptions.setTiffBinarizationMethod(ImageBinarizationMethod.FLOYD_STEINBERG_DITHERING); + saveOptions.setThresholdForFloydSteinbergDithering((byte) 254); + } + + doc.save(getArtifactsDir() + "WorkingWithImageSaveOptions.ExposeThresholdControlForTiffBinarization.tiff", saveOptions); + //ExEnd:ExposeThresholdControlForTiffBinarization + } + + @Test + public void getTiffPageRange() throws Exception + { + //ExStart:GetTiffPageRange + Document doc = new Document(getMyDir() + "Rendering.docx"); + //ExStart:SaveAsTIFF + doc.save(getArtifactsDir() + "WorkingWithImageSaveOptions.MultipageTiff.tiff"); + //ExEnd:SaveAsTIFF + + //ExStart:SaveAsTIFFUsingImageSaveOptions + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.TIFF); + { + saveOptions.setPageSet(new PageSet(new PageRange(0, 1))); saveOptions.setTiffCompression(TiffCompression.CCITT_4); saveOptions.setResolution(160f); + } + + doc.save(getArtifactsDir() + "WorkingWithImageSaveOptions.GetTiffPageRange.tiff", saveOptions); + //ExEnd:SaveAsTIFFUsingImageSaveOptions + //ExEnd:GetTiffPageRange + } + + @Test + public void format1BppIndexed() throws Exception + { + //ExStart:Format1BppIndexed + Document doc = new Document(getMyDir() + "Rendering.docx"); + + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.PNG); + { + saveOptions.setPageSet(new PageSet(1)); + saveOptions.setImageColorMode(ImageColorMode.BLACK_AND_WHITE); + saveOptions.setPixelFormat(ImagePixelFormat.FORMAT_1_BPP_INDEXED); + } + + doc.save(getArtifactsDir() + "WorkingWithImageSaveOptions.Format1BppIndexed.Png", saveOptions); + //ExEnd:Format1BppIndexed + } + + @Test + public void getJpegPageRange() throws Exception + { + //ExStart:GetJpegPageRange + Document doc = new Document(getMyDir() + "Rendering.docx"); + + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.JPEG); + + // Set the "PageSet" to "0" to convert only the first page of a document. + options.setPageSet(new PageSet(0)); + + // Change the image's brightness and contrast. + // Both are on a 0-1 scale and are at 0.5 by default. + options.setImageBrightness(0.3f); + options.setImageContrast(0.7f); + + // Change the horizontal resolution. + // The default value for these properties is 96.0, for a resolution of 96dpi. + options.setHorizontalResolution(72f); + + doc.save(getArtifactsDir() + "WorkingWithImageSaveOptions.GetJpegPageRange.jpeg", options); + //ExEnd:GetJpegPageRange + } + + @Test + //ExStart:PageSavingCallback + public static void pageSavingCallback() throws Exception + { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + ImageSaveOptions imageSaveOptions = new ImageSaveOptions(SaveFormat.PNG); + { + imageSaveOptions.setPageSet(new PageSet(new PageRange(0, doc.getPageCount() - 1))); + imageSaveOptions.setPageSavingCallback(new HandlePageSavingCallback()); + } + + doc.save(getArtifactsDir() + "WorkingWithImageSaveOptions.PageSavingCallback.png", imageSaveOptions); + } + + private static class HandlePageSavingCallback implements IPageSavingCallback + { + public void pageSaving(PageSavingArgs args) + { + args.setPageFileName(MessageFormat.format(getArtifactsDir() + "Page_{0}.png", args.getPageIndex())); + } + } + //ExEnd:PageSavingCallback +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with MarkdownSaveOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with MarkdownSaveOptions.java new file mode 100644 index 00000000..f348a661 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with MarkdownSaveOptions.java @@ -0,0 +1,67 @@ +package DocsExamples.File_Formats_and_Conversions.Save_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.ParagraphAlignment; +import com.aspose.words.MarkdownSaveOptions; +import com.aspose.words.TableContentAlignment; +import com.aspose.ms.System.IO.MemoryStream; + + +public class WorkingWithMarkdownSaveOptions extends DocsExamplesBase +{ + @Test + public void exportIntoMarkdownWithTableContentAlignment() throws Exception + { + //ExStart:ExportIntoMarkdownWithTableContentAlignment + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertCell(); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.RIGHT); + builder.write("Cell1"); + builder.insertCell(); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.write("Cell2"); + + // Makes all paragraphs inside the table to be aligned. + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + { + saveOptions.setTableContentAlignment(TableContentAlignment.LEFT); + } + doc.save(getArtifactsDir() + "WorkingWithMarkdownSaveOptions.LeftTableContentAlignment.md", saveOptions); + + saveOptions.setTableContentAlignment(TableContentAlignment.RIGHT); + doc.save(getArtifactsDir() + "WorkingWithMarkdownSaveOptions.RightTableContentAlignment.md", saveOptions); + + saveOptions.setTableContentAlignment(TableContentAlignment.CENTER); + doc.save(getArtifactsDir() + "WorkingWithMarkdownSaveOptions.CenterTableContentAlignment.md", saveOptions); + + // The alignment in this case will be taken from the first paragraph in corresponding table column. + saveOptions.setTableContentAlignment(TableContentAlignment.AUTO); + doc.save(getArtifactsDir() + "WorkingWithMarkdownSaveOptions.AutoTableContentAlignment.md", saveOptions); + //ExEnd:ExportIntoMarkdownWithTableContentAlignment + } + + @Test + public void setImagesFolder() throws Exception + { + //ExStart:SetImagesFolder + Document doc = new Document(getMyDir() + "Image bullet points.docx"); + + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); { saveOptions.setImagesFolder(getArtifactsDir() + "Images"); } + + MemoryStream stream = new MemoryStream(); + try /*JAVA: was using*/ + { + doc.save(stream, saveOptions); + } + finally { if (stream != null) stream.close(); } + //ExEnd:SetImagesFolder + } +} + diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with OdtSaveOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with OdtSaveOptions.java new file mode 100644 index 00000000..a127ec48 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with OdtSaveOptions.java @@ -0,0 +1,27 @@ +package DocsExamples.File_Formats_and_Conversions.Save_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.OdtSaveOptions; +import com.aspose.words.OdtSaveMeasureUnit; + + +public class WorkingWithOdtSaveOptions extends DocsExamplesBase +{ + @Test + public void measureUnit() throws Exception + { + //ExStart:MeasureUnit + Document doc = new Document(getMyDir() + "Document.docx"); + + // Open Office uses centimeters when specifying lengths, widths and other measurable formatting + // and content properties in documents whereas MS Office uses inches. + OdtSaveOptions saveOptions = new OdtSaveOptions(); { saveOptions.setMeasureUnit(OdtSaveMeasureUnit.INCHES); } + + doc.save(getArtifactsDir() + "WorkingWithOdtSaveOptions.MeasureUnit.odt", saveOptions); + //ExEnd:MeasureUnit + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with OoxmlSaveOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with OoxmlSaveOptions.java new file mode 100644 index 00000000..71e90cef --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with OoxmlSaveOptions.java @@ -0,0 +1,78 @@ +package DocsExamples.File_Formats_and_Conversions.Save_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.OoxmlSaveOptions; +import com.aspose.words.MsWordVersion; +import com.aspose.words.OoxmlCompliance; +import com.aspose.words.SaveFormat; +import com.aspose.words.CompressionLevel; + + +public class WorkingWithOoxmlSaveOptions extends DocsExamplesBase +{ + @Test + public void encryptDocxWithPassword() throws Exception + { + //ExStart:EncryptDocxWithPassword + Document doc = new Document(getMyDir() + "Document.docx"); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setPassword("password"); } + + doc.save(getArtifactsDir() + "WorkingWithOoxmlSaveOptions.EncryptDocxWithPassword.docx", saveOptions); + //ExEnd:EncryptDocxWithPassword + } + + @Test + public void ooxmlComplianceIso29500_2008_Strict() throws Exception + { + //ExStart:OoxmlComplianceIso29500_2008_Strict + Document doc = new Document(getMyDir() + "Document.docx"); + + doc.getCompatibilityOptions().optimizeFor(MsWordVersion.WORD_2016); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setCompliance(OoxmlCompliance.ISO_29500_2008_STRICT); } + + doc.save(getArtifactsDir() + "WorkingWithOoxmlSaveOptions.OoxmlComplianceIso29500_2008_Strict.docx", saveOptions); + //ExEnd:OoxmlComplianceIso29500_2008_Strict + } + + @Test + public void updateLastSavedTimeProperty() throws Exception + { + //ExStart:UpdateLastSavedTimeProperty + Document doc = new Document(getMyDir() + "Document.docx"); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setUpdateLastSavedTimeProperty(true); } + + doc.save(getArtifactsDir() + "WorkingWithOoxmlSaveOptions.UpdateLastSavedTimeProperty.docx", saveOptions); + //ExEnd:UpdateLastSavedTimeProperty + } + + @Test + public void keepLegacyControlChars() throws Exception + { + //ExStart:KeepLegacyControlChars + Document doc = new Document(getMyDir() + "Legacy control character.doc"); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(SaveFormat.FLAT_OPC); { saveOptions.setKeepLegacyControlChars(true); } + + doc.save(getArtifactsDir() + "WorkingWithOoxmlSaveOptions.KeepLegacyControlChars.docx", saveOptions); + //ExEnd:KeepLegacyControlChars + } + + @Test + public void setCompressionLevel() throws Exception + { + //ExStart:SetCompressionLevel + Document doc = new Document(getMyDir() + "Document.docx"); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setCompressionLevel(CompressionLevel.SUPER_FAST); } + + doc.save(getArtifactsDir() + "WorkingWithOoxmlSaveOptions.SetCompressionLevel.docx", saveOptions); + //ExEnd:SetCompressionLevel + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with PclSaveOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with PclSaveOptions.java new file mode 100644 index 00000000..6c2e1973 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with PclSaveOptions.java @@ -0,0 +1,28 @@ +package DocsExamples.File_Formats_and_Conversions.Save_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.PclSaveOptions; +import com.aspose.words.SaveFormat; + + +public class WorkingWithPclSaveOptions extends DocsExamplesBase +{ + @Test + public void rasterizeTransformedElements() throws Exception + { + //ExStart:RasterizeTransformedElements + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PclSaveOptions saveOptions = new PclSaveOptions(); + { + saveOptions.setSaveFormat(SaveFormat.PCL); saveOptions.setRasterizeTransformedElements(false); + } + + doc.save(getArtifactsDir() + "WorkingWithPclSaveOptions.RasterizeTransformedElements.pcl", saveOptions); + //ExEnd:RasterizeTransformedElements + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with PdfSaveOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with PdfSaveOptions.java new file mode 100644 index 00000000..0e799996 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with PdfSaveOptions.java @@ -0,0 +1,373 @@ +package DocsExamples.File_Formats_and_Conversions.Save_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.PdfSaveOptions; +import com.aspose.words.MetafileRenderingOptions; +import com.aspose.words.MetafileRenderingMode; +import com.aspose.words.WarningInfo; +import com.aspose.ms.System.msConsole; +import com.aspose.words.IWarningCallback; +import com.aspose.words.WarningType; +import com.aspose.words.WarningInfoCollection; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.PdfDigitalSignatureDetails; +import com.aspose.words.CertificateHolder; +import java.util.Date; +import com.aspose.ms.System.DateTime; +import com.aspose.words.PdfFontEmbeddingMode; +import com.aspose.words.HeaderFooterBookmarksExportMode; +import com.aspose.words.PdfCompliance; +import com.aspose.words.PdfCustomPropertiesExport; +import com.aspose.words.PdfImageCompression; +import com.aspose.words.PdfImageColorSpaceExportMode; +import com.aspose.words.Dml3DEffectsRenderingMode; + + +public class WorkingWithPdfSaveOptions extends DocsExamplesBase +{ + @Test + public void displayDocTitleInWindowTitlebar() throws Exception + { + //ExStart:DisplayDocTitleInWindowTitlebar + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setDisplayDocTitle(true); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.DisplayDocTitleInWindowTitlebar.pdf", saveOptions); + //ExEnd:DisplayDocTitleInWindowTitlebar + } + + @Test + //ExStart:PdfRenderWarnings + public void pdfRenderWarnings() throws Exception + { + Document doc = new Document(getMyDir() + "WMF with image.docx"); + + MetafileRenderingOptions metafileRenderingOptions = new MetafileRenderingOptions(); + { + metafileRenderingOptions.setEmulateRasterOperations(false); metafileRenderingOptions.setRenderingMode(MetafileRenderingMode.VECTOR_WITH_FALLBACK); + } + + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setMetafileRenderingOptions(metafileRenderingOptions); } + + // If Aspose.Words cannot correctly render some of the metafile records + // to vector graphics then Aspose.Words renders this metafile to a bitmap. + HandleDocumentWarnings callback = new HandleDocumentWarnings(); + doc.setWarningCallback(callback); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.PdfRenderWarnings.pdf", saveOptions); + + // While the file saves successfully, rendering warnings that occurred during saving are collected here. + for (WarningInfo warningInfo : callback.mWarnings) + { + System.out.println(warningInfo.getDescription()); + } + } + + //ExStart:RenderMetafileToBitmap + public static class HandleDocumentWarnings implements IWarningCallback + { + /// + /// Our callback only needs to implement the "Warning" method. This method is called whenever there is a + /// potential issue during document processing. The callback can be set to listen for warnings generated during + /// document load and/or document save. + /// + public void warning(WarningInfo info) + { + // For now type of warnings about unsupported metafile records changed + // from DataLoss/UnexpectedContent to MinorFormattingLoss. + if (info.getWarningType() == WarningType.MINOR_FORMATTING_LOSS) + { + System.out.println("Unsupported operation: " + info.getDescription()); + mWarnings.warning(info); + } + } + + public WarningInfoCollection mWarnings = new WarningInfoCollection(); + } + //ExEnd:RenderMetafileToBitmap + //ExEnd:PdfRenderWarnings + + @Test + public void digitallySignedPdfUsingCertificateHolder() throws Exception + { + //ExStart:DigitallySignedPdfUsingCertificateHolder + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Test Signed PDF."); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + { + saveOptions.setDigitalSignatureDetails(new PdfDigitalSignatureDetails( + CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"), "reason", "location", + new Date())); + } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.DigitallySignedPdfUsingCertificateHolder.pdf", saveOptions); + //ExEnd:DigitallySignedPdfUsingCertificateHolder + } + + @Test + public void embeddedAllFonts() throws Exception + { + //ExStart:EmbeddAllFonts + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // The output PDF will be embedded with all fonts found in the document. + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setEmbedFullFonts(true); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.EmbeddedFontsInPdf.pdf", saveOptions); + //ExEnd:EmbeddAllFonts + } + + @Test + public void embeddedSubsetFonts() throws Exception + { + //ExStart:EmbeddSubsetFonts + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // The output PDF will contain subsets of the fonts in the document. + // Only the glyphs used in the document are included in the PDF fonts. + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setEmbedFullFonts(false); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.EmbeddSubsetFonts.pdf", saveOptions); + //ExEnd:EmbeddSubsetFonts + } + + @Test + public void disableEmbedWindowsFonts() throws Exception + { + //ExStart:DisableEmbedWindowsFonts + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // The output PDF will be saved without embedding standard windows fonts. + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setFontEmbeddingMode(PdfFontEmbeddingMode.EMBED_NONE); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.DisableEmbedWindowsFonts.pdf", saveOptions); + //ExEnd:DisableEmbedWindowsFonts + } + + @Test + public void skipEmbeddedArialAndTimesRomanFonts() throws Exception + { + //ExStart:SkipEmbeddedArialAndTimesRomanFonts + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setFontEmbeddingMode(PdfFontEmbeddingMode.EMBED_ALL); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.SkipEmbeddedArialAndTimesRomanFonts.pdf", saveOptions); + //ExEnd:SkipEmbeddedArialAndTimesRomanFonts + } + + @Test + public void avoidEmbeddingCoreFonts() throws Exception + { + //ExStart:AvoidEmbeddingCoreFonts + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // The output PDF will not be embedded with core fonts such as Arial, Times New Roman etc. + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setUseCoreFonts(true); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.AvoidEmbeddingCoreFonts.pdf", saveOptions); + //ExEnd:AvoidEmbeddingCoreFonts + } + + @Test + public void escapeUri() throws Exception + { + //ExStart:EscapeUri + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertHyperlink("Testlink", + "https://www.google.com/search?q=%2Fthe%20test", false); + builder.writeln(); + builder.insertHyperlink("https://www.google.com/search?q=%2Fthe%20test", + "https://www.google.com/search?q=%2Fthe%20test", false); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.EscapeUri.pdf"); + //ExEnd:EscapeUri + } + + @Test + public void exportHeaderFooterBookmarks() throws Exception + { + //ExStart:ExportHeaderFooterBookmarks + Document doc = new Document(getMyDir() + "Bookmarks in headers and footers.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.getOutlineOptions().setDefaultBookmarksOutlineLevel(1); + saveOptions.setHeaderFooterBookmarksExportMode(HeaderFooterBookmarksExportMode.FIRST); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.ExportHeaderFooterBookmarks.pdf", saveOptions); + //ExEnd:ExportHeaderFooterBookmarks + } + + @Test + public void scaleWmfFontsToMetafileSize() throws Exception + { + //ExStart:ScaleWmfFontsToMetafileSize + Document doc = new Document(getMyDir() + "WMF with text.docx"); + + MetafileRenderingOptions metafileRenderingOptions = new MetafileRenderingOptions(); + { + metafileRenderingOptions.setScaleWmfFontsToMetafileSize(false); + } + + // If Aspose.Words cannot correctly render some of the metafile records to vector graphics + // then Aspose.Words renders this metafile to a bitmap. + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setMetafileRenderingOptions(metafileRenderingOptions); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.ScaleWmfFontsToMetafileSize.pdf", saveOptions); + //ExEnd:ScaleWmfFontsToMetafileSize + } + + @Test + public void additionalTextPositioning() throws Exception + { + //ExStart:AdditionalTextPositioning + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setAdditionalTextPositioning(true); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.AdditionalTextPositioning.pdf", saveOptions); + //ExEnd:AdditionalTextPositioning + } + + @Test + public void conversionToPdf17() throws Exception + { + //ExStart:ConversionToPDF17 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setCompliance(PdfCompliance.PDF_17); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.ConversionToPdf17.pdf", saveOptions); + //ExEnd:ConversionToPDF17 + } + + @Test + public void downsamplingImages() throws Exception + { + //ExStart:DownsamplingImages + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // We can set a minimum threshold for downsampling. + // This value will prevent the second image in the input document from being downsampled. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + { + saveOptions.setDownsampleOptions({ saveOptions.getDownsampleOptions().setResolution(36); saveOptions.getDownsampleOptions().setResolutionThreshold(128); }); + } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.DownsamplingImages.pdf", saveOptions); + //ExEnd:DownsamplingImages + } + + @Test + public void setOutlineOptions() throws Exception + { + //ExStart:SetOutlineOptions + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.getOutlineOptions().setHeadingsOutlineLevels(3); + saveOptions.getOutlineOptions().setExpandedOutlineLevels(1); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.SetOutlineOptions.pdf", saveOptions); + //ExEnd:SetOutlineOptions + } + + @Test + public void customPropertiesExport() throws Exception + { + //ExStart:CustomPropertiesExport + Document doc = new Document(); + doc.getCustomDocumentProperties().add("Company", "Aspose"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setCustomPropertiesExport(PdfCustomPropertiesExport.STANDARD); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.CustomPropertiesExport.pdf", saveOptions); + //ExEnd:CustomPropertiesExport + } + + @Test + public void exportDocumentStructure() throws Exception + { + //ExStart:ExportDocumentStructure + Document doc = new Document(getMyDir() + "Paragraphs.docx"); + + // The file size will be increased and the structure will be visible in the "Content" navigation pane + // of Adobe Acrobat Pro, while editing the .pdf. + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setExportDocumentStructure(true); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.ExportDocumentStructure.pdf", saveOptions); + //ExEnd:ExportDocumentStructure + } + + @Test + public void pdfImageComppression() throws Exception + { + //ExStart:PdfImageComppression + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + { + saveOptions.setImageCompression(PdfImageCompression.JPEG); saveOptions.setPreserveFormFields(true); + } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.PdfImageCompression.pdf", saveOptions); + + PdfSaveOptions saveOptionsA1B = new PdfSaveOptions(); + { + saveOptionsA1B.setCompliance(PdfCompliance.PDF_A_1_B); + saveOptionsA1B.setImageCompression(PdfImageCompression.JPEG); + saveOptionsA1B.setJpegQuality(100); // Use JPEG compression at 50% quality to reduce file size. + saveOptionsA1B.setImageColorSpaceExportMode(PdfImageColorSpaceExportMode.SIMPLE_CMYK); + } + + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.PdfImageCompression.Pdf_A1b.pdf", saveOptionsA1B); + //ExEnd:PdfImageComppression + } + + @Test + public void updateLastPrintedProperty() throws Exception + { + //ExStart:UpdateIfLastPrinted + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setUpdateLastPrintedProperty(true); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.UpdateIfLastPrinted.pdf", saveOptions); + //ExEnd:UpdateIfLastPrinted + } + + @Test + public void dml3DEffectsRendering() throws Exception + { + //ExStart:Dml3DEffectsRendering + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setDml3DEffectsRenderingMode(Dml3DEffectsRenderingMode.ADVANCED); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.Dml3DEffectsRendering.pdf", saveOptions); + //ExEnd:Dml3DEffectsRendering + } + + @Test + public void interpolateImages() throws Exception + { + //ExStart:SetImageInterpolation + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setInterpolateImages(true); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.InterpolateImages.pdf", saveOptions); + //ExEnd:SetImageInterpolation + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with RtfSaveOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with RtfSaveOptions.java new file mode 100644 index 00000000..fafbe7e6 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with RtfSaveOptions.java @@ -0,0 +1,24 @@ +package DocsExamples.File_Formats_and_Conversions.Save_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.RtfSaveOptions; + + +public class WorkingWithRtfSaveOptions extends DocsExamplesBase +{ + @Test + public void savingImagesAsWmf() throws Exception + { + //ExStart:SavingImagesAsWmf + Document doc = new Document(getMyDir() + "Document.docx"); + + RtfSaveOptions saveOptions = new RtfSaveOptions(); { saveOptions.setSaveImagesAsWmf(true); } + + doc.save(getArtifactsDir() + "WorkingWithRtfSaveOptions.SavingImagesAsWmf.rtf", saveOptions); + //ExEnd:SavingImagesAsWmf + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with TxtSaveOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with TxtSaveOptions.java new file mode 100644 index 00000000..a04ef33d --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/Working with TxtSaveOptions.java @@ -0,0 +1,77 @@ +package DocsExamples.File_Formats_and_Conversions.Save_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.TxtSaveOptions; + + +public class WorkingWithTxtSaveOptions extends DocsExamplesBase +{ + @Test + public void addBidiMarks() throws Exception + { + //ExStart:AddBidiMarks + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + builder.getParagraphFormat().setBidi(true); + builder.writeln("שלום עולם!"); + builder.writeln("مرحبا بالعالم!"); + + TxtSaveOptions saveOptions = new TxtSaveOptions(); { saveOptions.setAddBidiMarks(true); } + + doc.save(getArtifactsDir() + "WorkingWithTxtSaveOptions.AddBidiMarks.txt", saveOptions); + //ExEnd:AddBidiMarks + } + + @Test + public void useTabCharacterPerLevelForListIndentation() throws Exception + { + //ExStart:UseTabCharacterPerLevelForListIndentation + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a list with three levels of indentation. + builder.getListFormat().applyNumberDefault(); + builder.writeln("Item 1"); + builder.getListFormat().listIndent(); + builder.writeln("Item 2"); + builder.getListFormat().listIndent(); + builder.write("Item 3"); + + TxtSaveOptions saveOptions = new TxtSaveOptions(); + saveOptions.getListIndentation().setCount(1); + saveOptions.getListIndentation().setCharacter('\t'); + + doc.save(getArtifactsDir() + "WorkingWithTxtSaveOptions.UseTabCharacterPerLevelForListIndentation.txt", saveOptions); + //ExEnd:UseTabCharacterPerLevelForListIndentation + } + + @Test + public void useSpaceCharacterPerLevelForListIndentation() throws Exception + { + //ExStart:UseSpaceCharacterPerLevelForListIndentation + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a list with three levels of indentation. + builder.getListFormat().applyNumberDefault(); + builder.writeln("Item 1"); + builder.getListFormat().listIndent(); + builder.writeln("Item 2"); + builder.getListFormat().listIndent(); + builder.write("Item 3"); + + TxtSaveOptions saveOptions = new TxtSaveOptions(); + saveOptions.getListIndentation().setCount(3); + saveOptions.getListIndentation().setCharacter(' '); + + doc.save(getArtifactsDir() + "WorkingWithTxtSaveOptions.UseSpaceCharacterPerLevelForListIndentation.txt", saveOptions); + //ExEnd:UseSpaceCharacterPerLevelForListIndentation + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithDocSaveOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithDocSaveOptions.java new file mode 100644 index 00000000..522099d2 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithDocSaveOptions.java @@ -0,0 +1,53 @@ +package DocsExamples.File_Formats_and_Conversions.Save_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.DocSaveOptions; + + +public class WorkingWithDocSaveOptions extends DocsExamplesBase +{ + @Test + public void encryptDocumentWithPassword() throws Exception + { + //ExStart:EncryptDocumentWithPassword + //GistId:af95c7a408187bb25cf9137465fe5ce6 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Hello world!"); + + DocSaveOptions saveOptions = new DocSaveOptions(); { saveOptions.setPassword("password"); } + + doc.save(getArtifactsDir() + "WorkingWithDocSaveOptions.EncryptDocumentWithPassword.docx", saveOptions); + //ExEnd:EncryptDocumentWithPassword + } + + @Test + public void doNotCompressSmallMetafiles() throws Exception + { + //ExStart:DoNotCompressSmallMetafiles + Document doc = new Document(getMyDir() + "Microsoft equation object.docx"); + + DocSaveOptions saveOptions = new DocSaveOptions(); { saveOptions.setAlwaysCompressMetafiles(false); } + + doc.save(getArtifactsDir() + "WorkingWithDocSaveOptions.NotCompressSmallMetafiles.docx", saveOptions); + //ExEnd:DoNotCompressSmallMetafiles + } + + @Test + public void doNotSavePictureBullet() throws Exception + { + //ExStart:DoNotSavePictureBullet + Document doc = new Document(getMyDir() + "Image bullet points.docx"); + + DocSaveOptions saveOptions = new DocSaveOptions(); { saveOptions.setSavePictureBullet(false); } + + doc.save(getArtifactsDir() + "WorkingWithDocSaveOptions.DoNotSavePictureBullet.docx", saveOptions); + //ExEnd:DoNotSavePictureBullet + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithHtmlFixedSaveOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithHtmlFixedSaveOptions.java new file mode 100644 index 00000000..7b60af2d --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithHtmlFixedSaveOptions.java @@ -0,0 +1,38 @@ +package DocsExamples.File_Formats_and_Conversions.Save_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.HtmlFixedSaveOptions; + + +public class WorkingWithHtmlFixedSaveOptions extends DocsExamplesBase +{ + @Test + public void useFontFromTargetMachine() throws Exception + { + //ExStart:UseFontFromTargetMachine + Document doc = new Document(getMyDir() + "Bullet points with alternative font.docx"); + + HtmlFixedSaveOptions saveOptions = new HtmlFixedSaveOptions(); { saveOptions.setUseTargetMachineFonts(true); } + + doc.save(getArtifactsDir() + "WorkingWithHtmlFixedSaveOptions.UseFontFromTargetMachine.html", saveOptions); + //ExEnd:UseFontFromTargetMachine + } + + @Test + public void writeAllCssRulesInSingleFile() throws Exception + { + //ExStart:WriteAllCssRulesInSingleFile + Document doc = new Document(getMyDir() + "Document.docx"); + + // Setting this property to true restores the old behavior (separate files) for compatibility with legacy code. + // All CSS rules are written into single file "styles.css. + HtmlFixedSaveOptions saveOptions = new HtmlFixedSaveOptions(); { saveOptions.setSaveFontFaceCssSeparately(false); } + + doc.save(getArtifactsDir() + "WorkingWithHtmlFixedSaveOptions.WriteAllCssRulesInSingleFile.html", saveOptions); + //ExEnd:WriteAllCssRulesInSingleFile + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithHtmlSaveOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithHtmlSaveOptions.java new file mode 100644 index 00000000..b306cedb --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithHtmlSaveOptions.java @@ -0,0 +1,173 @@ +package DocsExamples.File_Formats_and_Conversions.Save_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.HtmlSaveOptions; +import com.aspose.words.CssStyleSheetType; +import com.aspose.words.HtmlLoadOptions; +import com.aspose.ms.System.IO.MemoryStream; +import com.aspose.ms.System.Text.Encoding; +import com.aspose.words.HtmlMetafileFormat; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.SaveFormat; +import com.aspose.ms.System.IO.Path; +import com.aspose.ms.System.IO.Directory; + + +public class WorkingWithHtmlSaveOptions extends DocsExamplesBase +{ + @Test + public void exportRoundtripInformation() throws Exception + { + //ExStart:ExportRoundtripInformation + //GistId:c0df00d37081f41a7683339fd7ef66c1 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); { saveOptions.setExportRoundtripInformation(true); } + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ExportRoundtripInformation.html", saveOptions); + //ExEnd:ExportRoundtripInformation + } + + @Test + public void exportFontsAsBase64() throws Exception + { + //ExStart:ExportFontsAsBase64 + //GistId:c0df00d37081f41a7683339fd7ef66c1 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); { saveOptions.setExportFontsAsBase64(true); } + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ExportFontsAsBase64.html", saveOptions); + //ExEnd:ExportFontsAsBase64 + } + + @Test + public void exportResources() throws Exception + { + //ExStart:ExportResources + //GistId:c0df00d37081f41a7683339fd7ef66c1 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + { + saveOptions.setCssStyleSheetType(CssStyleSheetType.EXTERNAL); + saveOptions.setExportFontResources(true); + saveOptions.setResourceFolder(getArtifactsDir() + "Resources"); + saveOptions.setResourceFolderAlias("http://example.com/resources"); + } + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ExportResources.html", saveOptions); + //ExEnd:ExportResources + } + + @Test + public void convertMetafilesToPng() throws Exception + { + //ExStart:ConvertMetafilesToPng + String html = + "\n \n Hello world!\n \n "; + + // Use 'ConvertSvgToEmf' to turn back the legacy behavior + // where all SVG images loaded from an HTML document were converted to EMF. + // Now SVG images are loaded without conversion + // if the MS Word version specified in load options supports SVG images natively. + HtmlLoadOptions loadOptions = new HtmlLoadOptions(); { loadOptions.setConvertSvgToEmf(true); } + Document doc = new Document(new MemoryStream(Encoding.getUTF8().getBytes(html)), loadOptions); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); { saveOptions.setMetafileFormat(HtmlMetafileFormat.PNG); } + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ConvertMetafilesToPng.html", saveOptions); + //ExEnd:ConvertMetafilesToPng + } + + @Test + public void convertMetafilesToSvg() throws Exception + { + //ExStart:ConvertMetafilesToSvg + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Here is an SVG image: "); + builder.insertHtml( + "\r\n \r\n "); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); { saveOptions.setMetafileFormat(HtmlMetafileFormat.SVG); } + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ConvertMetafilesToSvg.html", saveOptions); + //ExEnd:ConvertMetafilesToSvg + } + + @Test + public void addCssClassNamePrefix() throws Exception + { + //ExStart:AddCssClassNamePrefix + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + { + saveOptions.setCssStyleSheetType(CssStyleSheetType.EXTERNAL); saveOptions.setCssClassNamePrefix("pfx_"); + } + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.AddCssClassNamePrefix.html", saveOptions); + //ExEnd:AddCssClassNamePrefix + } + + @Test + public void exportCidUrlsForMhtmlResources() throws Exception + { + //ExStart:ExportCidUrlsForMhtmlResources + Document doc = new Document(getMyDir() + "Content-ID.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(SaveFormat.MHTML); + { + saveOptions.setPrettyFormat(true); saveOptions.setExportCidUrlsForMhtmlResources(true); + } + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ExportCidUrlsForMhtmlResources.mhtml", saveOptions); + //ExEnd:ExportCidUrlsForMhtmlResources + } + + @Test + public void resolveFontNames() throws Exception + { + //ExStart:ResolveFontNames + Document doc = new Document(getMyDir() + "Missing font.docx"); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(SaveFormat.HTML); + { + saveOptions.setPrettyFormat(true); saveOptions.setResolveFontNames(true); + } + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ResolveFontNames.html", saveOptions); + //ExEnd:ResolveFontNames + } + + @Test + public void exportTextInputFormFieldAsText() throws Exception + { + //ExStart:ExportTextInputFormFieldAsText + //GistId:83e5c469d0e72b5114fb8a05a1d01977 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + String imagesDir = Path.combine(getArtifactsDir(), "Images"); + + // The folder specified needs to exist and should be empty. + if (Directory.exists(imagesDir)) + Directory.delete(imagesDir, true); + + Directory.createDirectory(imagesDir); + + // Set an option to export form fields as plain text, not as HTML input elements. + HtmlSaveOptions saveOptions = new HtmlSaveOptions(SaveFormat.HTML); + { + saveOptions.setExportTextInputFormFieldAsText(true); saveOptions.setImagesFolder(imagesDir); + } + + doc.save(getArtifactsDir() + "WorkingWithHtmlSaveOptions.ExportTextInputFormFieldAsText.html", saveOptions); + //ExEnd:ExportTextInputFormFieldAsText + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithImageSaveOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithImageSaveOptions.java new file mode 100644 index 00000000..990d4fb9 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithImageSaveOptions.java @@ -0,0 +1,169 @@ +package DocsExamples.File_Formats_and_Conversions.Save_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.ImageSaveOptions; +import com.aspose.words.SaveFormat; +import com.aspose.words.TiffCompression; +import com.aspose.words.ImageColorMode; +import com.aspose.words.ImageBinarizationMethod; +import com.aspose.words.PageSet; +import com.aspose.words.PageRange; +import com.aspose.words.ImagePixelFormat; +import com.aspose.words.IPageSavingCallback; +import com.aspose.words.PageSavingArgs; +import java.text.MessageFormat; +import com.aspose.words.MultiPageLayout; +import com.aspose.ms.System.Drawing.msColor; +import java.awt.Color; + + +public class WorkingWithImageSaveOptions extends DocsExamplesBase +{ + @Test + public void exposeThresholdControl() throws Exception + { + //ExStart:ExposeThresholdControl + //GistId:b20a0ec0e1ff0556aa20d12f486e1963 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.TIFF); + { + saveOptions.setTiffCompression(TiffCompression.CCITT_3); + saveOptions.setImageColorMode(ImageColorMode.GRAYSCALE); + saveOptions.setTiffBinarizationMethod(ImageBinarizationMethod.FLOYD_STEINBERG_DITHERING); + saveOptions.setThresholdForFloydSteinbergDithering((byte) 254); + } + + doc.save(getArtifactsDir() + "WorkingWithImageSaveOptions.ExposeThresholdControl.tiff", saveOptions); + //ExEnd:ExposeThresholdControl + } + + @Test + public void getTiffPageRange() throws Exception + { + //ExStart:GetTiffPageRange + //GistId:b20a0ec0e1ff0556aa20d12f486e1963 + Document doc = new Document(getMyDir() + "Rendering.docx"); + //ExStart:SaveAsTiff + //GistId:b20a0ec0e1ff0556aa20d12f486e1963 + doc.save(getArtifactsDir() + "WorkingWithImageSaveOptions.MultipageTiff.tiff"); + //ExEnd:SaveAsTiff + + //ExStart:SaveAsTIFFUsingImageSaveOptions + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.TIFF); + { + saveOptions.setPageSet(new PageSet(new PageRange(0, 1))); saveOptions.setTiffCompression(TiffCompression.CCITT_4); saveOptions.setResolution(160f); + } + + doc.save(getArtifactsDir() + "WorkingWithImageSaveOptions.GetTiffPageRange.tiff", saveOptions); + //ExEnd:SaveAsTIFFUsingImageSaveOptions + //ExEnd:GetTiffPageRange + } + + @Test + public void format1BppIndexed() throws Exception + { + //ExStart:Format1BppIndexed + //GistId:83e5c469d0e72b5114fb8a05a1d01977 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + ImageSaveOptions saveOptions = new ImageSaveOptions(SaveFormat.PNG); + { + saveOptions.setPageSet(new PageSet(1)); + saveOptions.setImageColorMode(ImageColorMode.BLACK_AND_WHITE); + saveOptions.setPixelFormat(ImagePixelFormat.FORMAT_1_BPP_INDEXED); + } + + doc.save(getArtifactsDir() + "WorkingWithImageSaveOptions.Format1BppIndexed.Png", saveOptions); + //ExEnd:Format1BppIndexed + } + + @Test + public void getJpegPageRange() throws Exception + { + //ExStart:GetJpegPageRange + //GistId:ebbb90d74ef57db456685052a18f8e86 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.JPEG); + + // Set the "PageSet" to "0" to convert only the first page of a document. + options.setPageSet(new PageSet(0)); + + // Change the image's brightness and contrast. + // Both are on a 0-1 scale and are at 0.5 by default. + options.setImageBrightness(0.3f); + options.setImageContrast(0.7f); + + // Change the horizontal resolution. + // The default value for these properties is 96.0, for a resolution of 96dpi. + options.setHorizontalResolution(72f); + + doc.save(getArtifactsDir() + "WorkingWithImageSaveOptions.GetJpegPageRange.jpeg", options); + //ExEnd:GetJpegPageRange + } + + @Test + //ExStart:PageSavingCallback + public static void pageSavingCallback() throws Exception + { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + ImageSaveOptions imageSaveOptions = new ImageSaveOptions(SaveFormat.PNG); + { + imageSaveOptions.setPageSet(new PageSet(new PageRange(0, doc.getPageCount() - 1))); + imageSaveOptions.setPageSavingCallback(new HandlePageSavingCallback()); + } + + doc.save(getArtifactsDir() + "WorkingWithImageSaveOptions.PageSavingCallback.png", imageSaveOptions); + } + + private static class HandlePageSavingCallback implements IPageSavingCallback + { + public void pageSaving(PageSavingArgs args) + { + args.setPageFileName(MessageFormat.format(getArtifactsDir() + "Page_{0}.png", args.getPageIndex())); + } + } + //ExEnd:PageSavingCallback + + @Test + public void horizontalLayout() throws Exception + { + //ExStart:HorizontalLayout + //GistId:8eeaafcfcc55d78505f0f378ad8c6907 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.JPEG); + options.setPageLayout(MultiPageLayout.horizontal(10f)); + + doc.save(getArtifactsDir() + "WorkingWithImageSaveOptions.HorizontalLayout.jpg", options); + //ExEnd:HorizontalLayout + } + + @Test + public void gridLayout() throws Exception + { + //ExStart:GridLayout + //GistId:8eeaafcfcc55d78505f0f378ad8c6907 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.JPEG); + // Set up a grid layout with: + // - 3 columns per row. + // - 10pts spacing between pages (horizontal and vertical). + options.setPageLayout(MultiPageLayout.grid(3, 10f, 10f)); + + // Customize the background and border. + options.getPageLayout().setBackColor(msColor.getLightGray()); + options.getPageLayout().setBorderColor(Color.BLUE); + options.getPageLayout().setBorderWidth(2f); + + doc.save(getArtifactsDir() + "ImageSaveOptions.GridLayout.jpg", options); + //ExEnd:GridLayout + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithMarkdownSaveOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithMarkdownSaveOptions.java new file mode 100644 index 00000000..15de5603 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithMarkdownSaveOptions.java @@ -0,0 +1,69 @@ +package DocsExamples.File_Formats_and_Conversions.Save_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.ParagraphAlignment; +import com.aspose.words.MarkdownSaveOptions; +import com.aspose.words.TableContentAlignment; +import com.aspose.ms.System.IO.MemoryStream; + + +public class WorkingWithMarkdownSaveOptions extends DocsExamplesBase +{ + @Test + public void markdownTableContentAlignment() throws Exception + { + //ExStart:MarkdownTableContentAlignment + //GistId:19de942ef8827201c1dca99f76c59133 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertCell(); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.RIGHT); + builder.write("Cell1"); + builder.insertCell(); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.write("Cell2"); + + // Makes all paragraphs inside the table to be aligned. + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); + { + saveOptions.setTableContentAlignment(TableContentAlignment.LEFT); + } + doc.save(getArtifactsDir() + "WorkingWithMarkdownSaveOptions.LeftTableContentAlignment.md", saveOptions); + + saveOptions.setTableContentAlignment(TableContentAlignment.RIGHT); + doc.save(getArtifactsDir() + "WorkingWithMarkdownSaveOptions.RightTableContentAlignment.md", saveOptions); + + saveOptions.setTableContentAlignment(TableContentAlignment.CENTER); + doc.save(getArtifactsDir() + "WorkingWithMarkdownSaveOptions.CenterTableContentAlignment.md", saveOptions); + + // The alignment in this case will be taken from the first paragraph in corresponding table column. + saveOptions.setTableContentAlignment(TableContentAlignment.AUTO); + doc.save(getArtifactsDir() + "WorkingWithMarkdownSaveOptions.AutoTableContentAlignment.md", saveOptions); + //ExEnd:MarkdownTableContentAlignment + } + + @Test + public void imagesFolder() throws Exception + { + //ExStart:ImagesFolder + //GistId:51b4cb9c451832f23527892e19c7bca6 + Document doc = new Document(getMyDir() + "Image bullet points.docx"); + + MarkdownSaveOptions saveOptions = new MarkdownSaveOptions(); { saveOptions.setImagesFolder(getArtifactsDir() + "Images"); } + + MemoryStream stream = new MemoryStream(); + try /*JAVA: was using*/ + { + doc.save(stream, saveOptions); + } + finally { if (stream != null) stream.close(); } + //ExEnd:ImagesFolder + } +} + diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithOdtSaveOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithOdtSaveOptions.java new file mode 100644 index 00000000..939ed541 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithOdtSaveOptions.java @@ -0,0 +1,27 @@ +package DocsExamples.File_Formats_and_Conversions.Save_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.OdtSaveOptions; +import com.aspose.words.OdtSaveMeasureUnit; + + +public class WorkingWithOdtSaveOptions extends DocsExamplesBase +{ + @Test + public void measureUnit() throws Exception + { + //ExStart:MeasureUnit + Document doc = new Document(getMyDir() + "Document.docx"); + + // Open Office uses centimeters when specifying lengths, widths and other measurable formatting + // and content properties in documents whereas MS Office uses inches. + OdtSaveOptions saveOptions = new OdtSaveOptions(); { saveOptions.setMeasureUnit(OdtSaveMeasureUnit.INCHES); } + + doc.save(getArtifactsDir() + "WorkingWithOdtSaveOptions.MeasureUnit.odt", saveOptions); + //ExEnd:MeasureUnit + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithOoxmlSaveOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithOoxmlSaveOptions.java new file mode 100644 index 00000000..7e199af7 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithOoxmlSaveOptions.java @@ -0,0 +1,79 @@ +package DocsExamples.File_Formats_and_Conversions.Save_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.OoxmlSaveOptions; +import com.aspose.words.MsWordVersion; +import com.aspose.words.OoxmlCompliance; +import com.aspose.words.SaveFormat; +import com.aspose.words.CompressionLevel; + + +public class WorkingWithOoxmlSaveOptions extends DocsExamplesBase +{ + @Test + public void encryptDocxWithPassword() throws Exception + { + //ExStart:EncryptDocxWithPassword + Document doc = new Document(getMyDir() + "Document.docx"); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setPassword("password"); } + + doc.save(getArtifactsDir() + "WorkingWithOoxmlSaveOptions.EncryptDocxWithPassword.docx", saveOptions); + //ExEnd:EncryptDocxWithPassword + } + + @Test + public void ooxmlComplianceIso29500_2008_Strict() throws Exception + { + //ExStart:OoxmlComplianceIso29500_2008_Strict + Document doc = new Document(getMyDir() + "Document.docx"); + + doc.getCompatibilityOptions().optimizeFor(MsWordVersion.WORD_2016); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setCompliance(OoxmlCompliance.ISO_29500_2008_STRICT); } + + doc.save(getArtifactsDir() + "WorkingWithOoxmlSaveOptions.OoxmlComplianceIso29500_2008_Strict.docx", saveOptions); + //ExEnd:OoxmlComplianceIso29500_2008_Strict + } + + @Test + public void updateLastSavedTime() throws Exception + { + //ExStart:UpdateLastSavedTime + //GistId:83e5c469d0e72b5114fb8a05a1d01977 + Document doc = new Document(getMyDir() + "Document.docx"); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setUpdateLastSavedTimeProperty(true); } + + doc.save(getArtifactsDir() + "WorkingWithOoxmlSaveOptions.UpdateLastSavedTime.docx", saveOptions); + //ExEnd:UpdateLastSavedTime + } + + @Test + public void keepLegacyControlChars() throws Exception + { + //ExStart:KeepLegacyControlChars + Document doc = new Document(getMyDir() + "Legacy control character.doc"); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(SaveFormat.FLAT_OPC); { saveOptions.setKeepLegacyControlChars(true); } + + doc.save(getArtifactsDir() + "WorkingWithOoxmlSaveOptions.KeepLegacyControlChars.docx", saveOptions); + //ExEnd:KeepLegacyControlChars + } + + @Test + public void setCompressionLevel() throws Exception + { + //ExStart:SetCompressionLevel + Document doc = new Document(getMyDir() + "Document.docx"); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(); { saveOptions.setCompressionLevel(CompressionLevel.SUPER_FAST); } + + doc.save(getArtifactsDir() + "WorkingWithOoxmlSaveOptions.SetCompressionLevel.docx", saveOptions); + //ExEnd:SetCompressionLevel + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithPclSaveOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithPclSaveOptions.java new file mode 100644 index 00000000..78018465 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithPclSaveOptions.java @@ -0,0 +1,29 @@ +package DocsExamples.File_Formats_and_Conversions.Save_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.PclSaveOptions; +import com.aspose.words.SaveFormat; + + +public class WorkingWithPclSaveOptions extends DocsExamplesBase +{ + @Test + public void rasterizeTransformedElements() throws Exception + { + //ExStart:RasterizeTransformedElements + //GistId:7ee438947078cf070c5bc36a4e45a18c + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PclSaveOptions saveOptions = new PclSaveOptions(); + { + saveOptions.setSaveFormat(SaveFormat.PCL); saveOptions.setRasterizeTransformedElements(false); + } + + doc.save(getArtifactsDir() + "WorkingWithPclSaveOptions.RasterizeTransformedElements.pcl", saveOptions); + //ExEnd:RasterizeTransformedElements + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithPdfSaveOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithPdfSaveOptions.java new file mode 100644 index 00000000..fbd6479a --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithPdfSaveOptions.java @@ -0,0 +1,423 @@ +package DocsExamples.File_Formats_and_Conversions.Save_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.PdfSaveOptions; +import com.aspose.words.MetafileRenderingOptions; +import com.aspose.words.MetafileRenderingMode; +import com.aspose.words.WarningInfo; +import com.aspose.ms.System.msConsole; +import com.aspose.words.IWarningCallback; +import com.aspose.words.WarningType; +import com.aspose.words.WarningInfoCollection; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.PdfDigitalSignatureDetails; +import com.aspose.words.CertificateHolder; +import java.util.Date; +import com.aspose.ms.System.DateTime; +import com.aspose.words.PdfFontEmbeddingMode; +import com.aspose.words.HeaderFooterBookmarksExportMode; +import com.aspose.words.PdfCompliance; +import com.aspose.words.PdfCustomPropertiesExport; +import com.aspose.words.PdfImageCompression; +import com.aspose.words.Dml3DEffectsRenderingMode; +import com.aspose.words.FieldHyperlink; + + +public class WorkingWithPdfSaveOptions extends DocsExamplesBase +{ + @Test + public void displayDocTitleInWindowTitlebar() throws Exception + { + //ExStart:DisplayDocTitleInWindowTitlebar + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setDisplayDocTitle(true); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.DisplayDocTitleInWindowTitlebar.pdf", saveOptions); + //ExEnd:DisplayDocTitleInWindowTitlebar + } + + @Test + //ExStart:PdfRenderWarnings + //GistId:f9c5250f94e595ea3590b3be679475ba + public void pdfRenderWarnings() throws Exception + { + Document doc = new Document(getMyDir() + "WMF with image.docx"); + + MetafileRenderingOptions metafileRenderingOptions = new MetafileRenderingOptions(); + { + metafileRenderingOptions.setEmulateRasterOperations(false); metafileRenderingOptions.setRenderingMode(MetafileRenderingMode.VECTOR_WITH_FALLBACK); + } + + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setMetafileRenderingOptions(metafileRenderingOptions); } + + // If Aspose.Words cannot correctly render some of the metafile records + // to vector graphics then Aspose.Words renders this metafile to a bitmap. + HandleDocumentWarnings callback = new HandleDocumentWarnings(); + doc.setWarningCallback(callback); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.PdfRenderWarnings.pdf", saveOptions); + + // While the file saves successfully, rendering warnings that occurred during saving are collected here. + for (WarningInfo warningInfo : callback.mWarnings) + { + System.out.println(warningInfo.getDescription()); + } + } + + public static class HandleDocumentWarnings implements IWarningCallback + { + /// + /// Our callback only needs to implement the "Warning" method. This method is called whenever there is a + /// potential issue during document processing. The callback can be set to listen for warnings generated during + /// document load and/or document save. + /// + public void warning(WarningInfo info) + { + // For now type of warnings about unsupported metafile records changed + // from DataLoss/UnexpectedContent to MinorFormattingLoss. + if (info.getWarningType() == WarningType.MINOR_FORMATTING_LOSS) + { + System.out.println("Unsupported operation: " + info.getDescription()); + mWarnings.warning(info); + } + } + + public WarningInfoCollection mWarnings = new WarningInfoCollection(); + } + //ExEnd:PdfRenderWarnings + + @Test + public void digitallySignedPdfUsingCertificateHolder() throws Exception + { + //ExStart:DigitallySignedPdfUsingCertificateHolder + //GistId:bdc15a6de6b25d9d4e66f2ce918fc01b + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Test Signed PDF."); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + { + saveOptions.setDigitalSignatureDetails(new PdfDigitalSignatureDetails( + CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"), "reason", "location", + new Date)); + } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.DigitallySignedPdfUsingCertificateHolder.pdf", saveOptions); + //ExEnd:DigitallySignedPdfUsingCertificateHolder + } + + @Test + public void embeddedAllFonts() throws Exception + { + //ExStart:EmbeddedAllFonts + //GistId:6debb84fc15c7e5b8e35384d9c116215 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // The output PDF will be embedded with all fonts found in the document. + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setEmbedFullFonts(true); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.EmbeddedAllFonts.pdf", saveOptions); + //ExEnd:EmbeddedAllFonts + } + + @Test + public void embeddedSubsetFonts() throws Exception + { + //ExStart:EmbeddedSubsetFonts + //GistId:6debb84fc15c7e5b8e35384d9c116215 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // The output PDF will contain subsets of the fonts in the document. + // Only the glyphs used in the document are included in the PDF fonts. + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setEmbedFullFonts(false); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.EmbeddedSubsetFonts.pdf", saveOptions); + //ExEnd:EmbeddedSubsetFonts + } + + @Test + public void disableEmbedWindowsFonts() throws Exception + { + //ExStart:DisableEmbedWindowsFonts + //GistId:6debb84fc15c7e5b8e35384d9c116215 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // The output PDF will be saved without embedding standard windows fonts. + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setFontEmbeddingMode(PdfFontEmbeddingMode.EMBED_NONE); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.DisableEmbedWindowsFonts.pdf", saveOptions); + //ExEnd:DisableEmbedWindowsFonts + } + + @Test + public void skipEmbeddedArialAndTimesRomanFonts() throws Exception + { + //ExStart:SkipEmbeddedArialAndTimesRomanFonts + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setFontEmbeddingMode(PdfFontEmbeddingMode.EMBED_ALL); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.SkipEmbeddedArialAndTimesRomanFonts.pdf", saveOptions); + //ExEnd:SkipEmbeddedArialAndTimesRomanFonts + } + + @Test + public void avoidEmbeddingCoreFonts() throws Exception + { + //ExStart:AvoidEmbeddingCoreFonts + //GistId:6debb84fc15c7e5b8e35384d9c116215 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // The output PDF will not be embedded with core fonts such as Arial, Times New Roman etc. + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setUseCoreFonts(true); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.AvoidEmbeddingCoreFonts.pdf", saveOptions); + //ExEnd:AvoidEmbeddingCoreFonts + } + + @Test + public void escapeUri() throws Exception + { + //ExStart:EscapeUri + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertHyperlink("Testlink", + "https://www.google.com/search?q= aspose", false); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.EscapeUri.pdf"); + //ExEnd:EscapeUri + } + + @Test + public void exportHeaderFooterBookmarks() throws Exception + { + //ExStart:ExportHeaderFooterBookmarks + //GistId:6debb84fc15c7e5b8e35384d9c116215 + Document doc = new Document(getMyDir() + "Bookmarks in headers and footers.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.getOutlineOptions().setDefaultBookmarksOutlineLevel(1); + saveOptions.setHeaderFooterBookmarksExportMode(HeaderFooterBookmarksExportMode.FIRST); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.ExportHeaderFooterBookmarks.pdf", saveOptions); + //ExEnd:ExportHeaderFooterBookmarks + } + + @Test + public void emulateRenderingToSizeOnPage() throws Exception + { + //ExStart:EmulateRenderingToSizeOnPage + Document doc = new Document(getMyDir() + "WMF with text.docx"); + + MetafileRenderingOptions metafileRenderingOptions = new MetafileRenderingOptions(); + { + metafileRenderingOptions.setEmulateRenderingToSizeOnPage(false); + } + + // If Aspose.Words cannot correctly render some of the metafile records to vector graphics + // then Aspose.Words renders this metafile to a bitmap. + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setMetafileRenderingOptions(metafileRenderingOptions); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.EmulateRenderingToSizeOnPage.pdf", saveOptions); + //ExEnd:EmulateRenderingToSizeOnPage + } + + @Test + public void additionalTextPositioning() throws Exception + { + //ExStart:AdditionalTextPositioning + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setAdditionalTextPositioning(true); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.AdditionalTextPositioning.pdf", saveOptions); + //ExEnd:AdditionalTextPositioning + } + + @Test + public void conversionToPdf17() throws Exception + { + //ExStart:ConversionToPdf17 + //GistId:a53bdaad548845275c1b9556ee21ae65 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setCompliance(PdfCompliance.PDF_17); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.ConversionToPdf17.pdf", saveOptions); + //ExEnd:ConversionToPdf17 + } + + @Test + public void downsamplingImages() throws Exception + { + //ExStart:DownsamplingImages + //GistId:6debb84fc15c7e5b8e35384d9c116215 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // We can set a minimum threshold for downsampling. + // This value will prevent the second image in the input document from being downsampled. + PdfSaveOptions saveOptions = new PdfSaveOptions(); + { + saveOptions.setDownsampleOptions({ saveOptions.getDownsampleOptions().setResolution(36); saveOptions.getDownsampleOptions().setResolutionThreshold(128); }); + } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.DownsamplingImages.pdf", saveOptions); + //ExEnd:DownsamplingImages + } + + @Test + public void outlineOptions() throws Exception + { + //ExStart:OutlineOptions + //GistId:6debb84fc15c7e5b8e35384d9c116215 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.getOutlineOptions().setHeadingsOutlineLevels(3); + saveOptions.getOutlineOptions().setExpandedOutlineLevels(1); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.OutlineOptions.pdf", saveOptions); + //ExEnd:OutlineOptions + } + + @Test + public void customPropertiesExport() throws Exception + { + //ExStart:CustomPropertiesExport + //GistId:6debb84fc15c7e5b8e35384d9c116215 + Document doc = new Document(); + doc.getCustomDocumentProperties().add("Company", "Aspose"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setCustomPropertiesExport(PdfCustomPropertiesExport.STANDARD); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.CustomPropertiesExport.pdf", saveOptions); + //ExEnd:CustomPropertiesExport + } + + @Test + public void exportDocumentStructure() throws Exception + { + //ExStart:ExportDocumentStructure + //GistId:6debb84fc15c7e5b8e35384d9c116215 + Document doc = new Document(getMyDir() + "Paragraphs.docx"); + + // The file size will be increased and the structure will be visible in the "Content" navigation pane + // of Adobe Acrobat Pro, while editing the .pdf. + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setExportDocumentStructure(true); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.ExportDocumentStructure.pdf", saveOptions); + //ExEnd:ExportDocumentStructure + } + + @Test + public void imageCompression() throws Exception + { + //ExStart:ImageCompression + //GistId:6debb84fc15c7e5b8e35384d9c116215 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + { + saveOptions.setImageCompression(PdfImageCompression.JPEG); saveOptions.setPreserveFormFields(true); + } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.ImageCompression.pdf", saveOptions); + + PdfSaveOptions saveOptionsA2U = new PdfSaveOptions(); + { + saveOptionsA2U.setCompliance(PdfCompliance.PDF_A_2_U); + saveOptionsA2U.setImageCompression(PdfImageCompression.JPEG); + saveOptionsA2U.setJpegQuality(100); // Use JPEG compression at 50% quality to reduce file size. + } + + + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.ImageCompression_A2u.pdf", saveOptionsA2U); + //ExEnd:ImageCompression + } + + @Test + public void updateLastPrinted() throws Exception + { + //ExStart:UpdateLastPrinted + //GistId:83e5c469d0e72b5114fb8a05a1d01977 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setUpdateLastPrintedProperty(true); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.UpdateLastPrinted.pdf", saveOptions); + //ExEnd:UpdateLastPrinted + } + + @Test + public void dml3DEffectsRendering() throws Exception + { + //ExStart:Dml3DEffectsRendering + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setDml3DEffectsRenderingMode(Dml3DEffectsRenderingMode.ADVANCED); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.Dml3DEffectsRendering.pdf", saveOptions); + //ExEnd:Dml3DEffectsRendering + } + + @Test + public void interpolateImages() throws Exception + { + //ExStart:SetImageInterpolation + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setInterpolateImages(true); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.InterpolateImages.pdf", saveOptions); + //ExEnd:SetImageInterpolation + } + + @Test + public void optimizeOutput() throws Exception + { + //ExStart:OptimizeOutput + //GistId:a53bdaad548845275c1b9556ee21ae65 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); { saveOptions.setOptimizeOutput(true); } + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.OptimizeOutput.pdf", saveOptions); + //ExEnd:OptimizeOutput + } + + @Test + public void updateScreenTip() throws Exception + { + //ExStart:UpdateScreenTip + //GistId:8b0ab362f95040ada1255a0473acefe2 + Document doc = new Document(getMyDir() + "Table of contents.docx"); + + var tocHyperLinks = doc.getRange().getFields() + .Where(f => f.Type == FieldType.FieldHyperlink) + .Cast() + .Where(f => f.SubAddress.StartsWith("#_Toc")); + + for (FieldHyperlink link : (Iterable) tocHyperLinks) + link.setScreenTip(link.getDisplayResult()); + + PdfSaveOptions saveOptions = new PdfSaveOptions(); + { + saveOptions.setCompliance(PdfCompliance.PDF_UA_1); + saveOptions.setDisplayDocTitle(true); + saveOptions.setExportDocumentStructure(true); + } + saveOptions.getOutlineOptions().setHeadingsOutlineLevels(3); + saveOptions.getOutlineOptions().setCreateMissingOutlineLevels(true); + + doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.UpdateScreenTip.pdf", saveOptions); + //ExEnd:UpdateScreenTip + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithRtfSaveOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithRtfSaveOptions.java new file mode 100644 index 00000000..af975596 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithRtfSaveOptions.java @@ -0,0 +1,25 @@ +package DocsExamples.File_Formats_and_Conversions.Save_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.RtfSaveOptions; + + +public class WorkingWithRtfSaveOptions extends DocsExamplesBase +{ + @Test + public void savingImagesAsWmf() throws Exception + { + //ExStart:SavingImagesAsWmf + //GistId:6f849e51240635a6322ab0460938c922 + Document doc = new Document(getMyDir() + "Document.docx"); + + RtfSaveOptions saveOptions = new RtfSaveOptions(); { saveOptions.setSaveImagesAsWmf(true); } + + doc.save(getArtifactsDir() + "WorkingWithRtfSaveOptions.SavingImagesAsWmf.rtf", saveOptions); + //ExEnd:SavingImagesAsWmf + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithTxtSaveOptions.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithTxtSaveOptions.java new file mode 100644 index 00000000..94168d9f --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/Save_options/WorkingWithTxtSaveOptions.java @@ -0,0 +1,80 @@ +package DocsExamples.File_Formats_and_Conversions.Save_Options; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.TxtSaveOptions; + + +public class WorkingWithTxtSaveOptions extends DocsExamplesBase +{ + @Test + public void addBidiMarks() throws Exception + { + //ExStart:AddBidiMarks + //GistId:ddafc3430967fb4f4f70085fa577d01a + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello world!"); + builder.getParagraphFormat().setBidi(true); + builder.writeln("שלום עולם!"); + builder.writeln("مرحبا بالعالم!"); + + TxtSaveOptions saveOptions = new TxtSaveOptions(); { saveOptions.setAddBidiMarks(true); } + + doc.save(getArtifactsDir() + "WorkingWithTxtSaveOptions.AddBidiMarks.txt", saveOptions); + //ExEnd:AddBidiMarks + } + + @Test + public void useTabForListIndentation() throws Exception + { + //ExStart:UseTabForListIndentation + //GistId:ddafc3430967fb4f4f70085fa577d01a + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a list with three levels of indentation. + builder.getListFormat().applyNumberDefault(); + builder.writeln("Item 1"); + builder.getListFormat().listIndent(); + builder.writeln("Item 2"); + builder.getListFormat().listIndent(); + builder.write("Item 3"); + + TxtSaveOptions saveOptions = new TxtSaveOptions(); + saveOptions.getListIndentation().setCount(1); + saveOptions.getListIndentation().setCharacter('\t'); + + doc.save(getArtifactsDir() + "WorkingWithTxtSaveOptions.UseTabForListIndentation.txt", saveOptions); + //ExEnd:UseTabForListIndentation + } + + @Test + public void useSpaceForListIndentation() throws Exception + { + //ExStart:UseSpaceForListIndentation + //GistId:ddafc3430967fb4f4f70085fa577d01a + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a list with three levels of indentation. + builder.getListFormat().applyNumberDefault(); + builder.writeln("Item 1"); + builder.getListFormat().listIndent(); + builder.writeln("Item 2"); + builder.getListFormat().listIndent(); + builder.write("Item 3"); + + TxtSaveOptions saveOptions = new TxtSaveOptions(); + saveOptions.getListIndentation().setCount(3); + saveOptions.getListIndentation().setCharacter(' '); + + doc.save(getArtifactsDir() + "WorkingWithTxtSaveOptions.UseSpaceForListIndentation.txt", saveOptions); + //ExEnd:UseSpaceForListIndentation + } +} diff --git a/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/WorkingWithFileFormat.java b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/WorkingWithFileFormat.java new file mode 100644 index 00000000..dcdcfa3f --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/File_formats_and_conversions/WorkingWithFileFormat.java @@ -0,0 +1,146 @@ +package DocsExamples.File_Formats_and_Conversions; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.ms.System.IO.Directory; +import com.aspose.ms.System.IO.Path; +import com.aspose.ms.System.msConsole; +import com.aspose.words.FileFormatInfo; +import com.aspose.words.FileFormatUtil; +import com.aspose.words.LoadFormat; +import com.aspose.ms.System.IO.File; + + +public class WorkingWithFileFormat extends DocsExamplesBase +{ + @Test + public void detectFileFormat() throws Exception + { + //ExStart:CheckFormatCompatibility + //GistId:7fe3fc4004f081628a63608db70332b3 + String supportedDir = getArtifactsDir() + "Supported"; + String unknownDir = getArtifactsDir() + "Unknown"; + String encryptedDir = getArtifactsDir() + "Encrypted"; + String pre97Dir = getArtifactsDir() + "Pre97"; + + // Create the directories if they do not already exist. + if (Directory.exists(supportedDir) == false) + Directory.createDirectory(supportedDir); + if (Directory.exists(unknownDir) == false) + Directory.createDirectory(unknownDir); + if (Directory.exists(encryptedDir) == false) + Directory.createDirectory(encryptedDir); + if (Directory.exists(pre97Dir) == false) + Directory.createDirectory(pre97Dir); + + //ExStart:GetFiles + //GistId:7fe3fc4004f081628a63608db70332b3 + Iterable fileList = Directory.getFiles(getMyDir()).Where(name => !name.EndsWith("Corrupted document.docx")); + //ExEnd:GetFiles + for (String fileName : fileList) + { + String nameOnly = Path.getFileName(fileName); + + msConsole.write(nameOnly); + FileFormatInfo info = FileFormatUtil.detectFileFormat(fileName); + + // Display the document type + switch (info.getLoadFormat()) + { + case LoadFormat.DOC: + System.out.println("\tMicrosoft Word 97-2003 document."); + break; + case LoadFormat.DOT: + System.out.println("\tMicrosoft Word 97-2003 template."); + break; + case LoadFormat.DOCX: + System.out.println("\tOffice Open XML WordprocessingML Macro-Free Document."); + break; + case LoadFormat.DOCM: + System.out.println("\tOffice Open XML WordprocessingML Macro-Enabled Document."); + break; + case LoadFormat.DOTX: + System.out.println("\tOffice Open XML WordprocessingML Macro-Free Template."); + break; + case LoadFormat.DOTM: + System.out.println("\tOffice Open XML WordprocessingML Macro-Enabled Template."); + break; + case LoadFormat.FLAT_OPC: + System.out.println("\tFlat OPC document."); + break; + case LoadFormat.RTF: + System.out.println("\tRTF format."); + break; + case LoadFormat.WORD_ML: + System.out.println("\tMicrosoft Word 2003 WordprocessingML format."); + break; + case LoadFormat.HTML: + System.out.println("\tHTML format."); + break; + case LoadFormat.MHTML: + System.out.println("\tMHTML (Web archive) format."); + break; + case LoadFormat.ODT: + System.out.println("\tOpenDocument Text."); + break; + case LoadFormat.OTT: + System.out.println("\tOpenDocument Text Template."); + break; + case LoadFormat.DOC_PRE_WORD_60: + System.out.println("\tMS Word 6 or Word 95 format."); + break; + case LoadFormat.UNKNOWN: + System.out.println("\tUnknown format."); + break; + } + + if (info.isEncrypted()) + { + System.out.println("\tAn encrypted document."); + File.copy(fileName, Path.combine(encryptedDir, nameOnly), true); + } + else + { + switch (info.getLoadFormat()) + { + case LoadFormat.DOC_PRE_WORD_60: + File.copy(fileName, Path.combine(pre97Dir, nameOnly), true); + break; + case LoadFormat.UNKNOWN: + File.copy(fileName, Path.combine(unknownDir, nameOnly), true); + break; + default: + File.copy(fileName, Path.combine(supportedDir, nameOnly), true); + break; + } + } + } + //ExEnd:CheckFormatCompatibility + } + + @Test + public void detectDocumentSignatures() throws Exception + { + //ExStart:DetectDocumentSignatures + //GistId:bdc15a6de6b25d9d4e66f2ce918fc01b + FileFormatInfo info = FileFormatUtil.detectFileFormat(getMyDir() + "Digitally signed.docx"); + + if (info.hasDigitalSignature()) + { + System.out.println("Document {Path.GetFileName(MyDir + "); + } + //ExEnd:DetectDocumentSignatures + } + + @Test + public void verifyEncryptedDocument() throws Exception + { + //ExStart:VerifyEncryptedDocument + //GistId:af95c7a408187bb25cf9137465fe5ce6 + FileFormatInfo info = FileFormatUtil.detectFileFormat(getMyDir() + "Encrypted.docx"); + msConsole.writeLine(info.isEncrypted()); + //ExEnd:VerifyEncryptedDocument + } +} diff --git a/Examples/DocsExamples/JavaPorting/Getting_started/ApplyLicense.java b/Examples/DocsExamples/JavaPorting/Getting_started/ApplyLicense.java new file mode 100644 index 00000000..efa40efe --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Getting_started/ApplyLicense.java @@ -0,0 +1,84 @@ +package DocsExamples.Programming_with_Documents; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.License; +import com.aspose.ms.System.msConsole; +import com.aspose.ms.System.IO.MemoryStream; +import com.aspose.ms.System.IO.File; +import com.aspose.words.Metered; +import com.aspose.words.Document; + + +class ApplyLicense extends DocsExamplesBase +{ + @Test + public void applyLicenseFromFile() throws Exception + { + //ExStart:ApplyLicenseFromFile + //GistId:c762ebd027c53ed61fce5bc5ccac1ca7 + License license = new License(); + + // This line attempts to set a license from several locations relative to the executable and Aspose.Words.dll. + // You can also use the additional overload to load a license from a stream, this is useful, + // for instance, when the license is stored as an embedded resource. + try + { + license.setLicense("Aspose.Words.lic"); + + System.out.println("License set successfully."); + } + catch (Exception e) + { + // We do not ship any license with this example, + // visit the Aspose site to obtain either a temporary or permanent license. + System.out.println("\nThere was an error setting the license: " + e.getMessage()); + } + //ExEnd:ApplyLicenseFromFile + } + + @Test + public void applyLicenseFromStream() throws Exception + { + //ExStart:ApplyLicenseFromStream + //GistId:c762ebd027c53ed61fce5bc5ccac1ca7 + License license = new License(); + + try + { + license.setLicenseInternal(new MemoryStream(File.readAllBytes("Aspose.Words.lic"))); + + System.out.println("License set successfully."); + } + catch (Exception e) + { + // We do not ship any license with this example, + // visit the Aspose site to obtain either a temporary or permanent license. + System.out.println("\nThere was an error setting the license: " + e.getMessage()); + } + //ExEnd:ApplyLicenseFromStream + } + + @Test + public void applyMeteredLicense() throws Exception + { + //ExStart:ApplyMeteredLicense + //GistId:c762ebd027c53ed61fce5bc5ccac1ca7 + try + { + Metered metered = new Metered(); + metered.setMeteredKey("*****", "*****"); + + Document doc = new Document(getMyDir() + "Document.docx"); + + msConsole.writeLine(doc.getPageCount()); + } + catch (Exception e) + { + System.out.println("\nThere was an error setting the license: " + e.getMessage()); + } + //ExEnd:ApplyMeteredLicense + } +} diff --git a/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/BaseOperations.java b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/BaseOperations.java new file mode 100644 index 00000000..374bd38e --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/BaseOperations.java @@ -0,0 +1,95 @@ +package DocsExamples.LINQ_Reporting_Engine; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import DocsExamples.LINQ_Reporting_Engine.Helpers.Data_Source_Objects.Sender; +import com.aspose.words.ReportingEngine; +import java.util.ArrayList; +import DocsExamples.LINQ_Reporting_Engine.Helpers.Data_Source_Objects.BackgroundColor; +import java.awt.Color; +import com.aspose.ms.System.Drawing.msColor; + + +public class BaseOperations extends DocsExamplesBase +{ + @Test + public void helloWorld() throws Exception + { + //ExStart:HelloWorld + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("<<[sender.Name]>> says: <<[sender.Message]>>"); + + Sender sender = new Sender(); { sender.setName("LINQ Reporting Engine"); sender.setMessage("Hello World"); } + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, sender, "sender"); + + doc.save(getArtifactsDir() + "ReportingEngine.HelloWorld.docx"); + //ExEnd:HelloWorld + } + + @Test + public void singleRow() throws Exception + { + //ExStart:SingleRow + Document doc = new Document(getMyDir() + "Reporting engine template - Table row.docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, Common.getManagers(), "Managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.SingleRow.docx"); + //ExEnd:SingleRow + } + + @Test + public void commonMasterDetail() throws Exception + { + //ExStart:CommonMasterDetail + Document doc = new Document(getMyDir() + "Reporting engine template - Common master detail.docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, Common.getManagers(), "managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.CommonMasterDetail.docx"); + //ExEnd:CommonMasterDetail + } + + @Test + public void conditionalBlocks() throws Exception + { + //ExStart:ConditionalBlocks + Document doc = new Document(getMyDir() + "Reporting engine template - Table row conditional blocks.docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, Common.getClients(), "clients"); + + doc.save(getArtifactsDir() + "ReportingEngine.ConditionalBlock.docx"); + //ExEnd:ConditionalBlocks + } + + @Test + public void settingBackgroundColor() throws Exception + { + //ExStart:SettingBackgroundColor + Document doc = new Document(getMyDir() + "Reporting engine template - Background color.docx"); + + ArrayList colors = new ArrayList(); + { + colors.add(new BackgroundColor()); {((BackgroundColor)colors.get(0)).setName("Black"); ((BackgroundColor)colors.get(0)).setColor(Color.BLACK);} + colors.add(new BackgroundColor()); {((BackgroundColor)colors.get(1)).setName("Red"); ((BackgroundColor)colors.get(1)).setColor(new Color((255), (0), (0)));} + colors.add(new BackgroundColor()); {((BackgroundColor)colors.get(2)).setName("Empty"); ((BackgroundColor)colors.get(2)).setColor(msColor.Empty);} + } + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, colors, "Colors"); + + doc.save(getArtifactsDir() + "ReportingEngine.BackColor.docx"); + //ExEnd:SettingBackgroundColor + } +} diff --git a/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/BuildOptions.java b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/BuildOptions.java new file mode 100644 index 00000000..545ecdbc --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/BuildOptions.java @@ -0,0 +1,26 @@ +package DocsExamples.LINQ_Reporting_Engine; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.ReportingEngine; +import com.aspose.words.ReportBuildOptions; + + +public class BuildOptions extends DocsExamplesBase +{ + @Test + public void removeEmptyParagraphs() throws Exception + { + //ExStart:RemoveEmptyParagraphs + Document doc = new Document(getMyDir() + "Reporting engine template - Remove empty paragraphs.docx"); + + ReportingEngine engine = new ReportingEngine(); { engine.setOptions(ReportBuildOptions.REMOVE_EMPTY_PARAGRAPHS); } + engine.buildReport(doc, Common.getManagers(), "Managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.RemoveEmptyParagraphs.docx"); + //ExEnd:RemoveEmptyParagraphs + } +} diff --git a/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Charts.java b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Charts.java new file mode 100644 index 00000000..1cd9b67e --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Charts.java @@ -0,0 +1,78 @@ +package DocsExamples.LINQ_Reporting_Engine; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.ReportingEngine; +import DocsExamples.LINQ_Reporting_Engine.Helpers.Common; + + +public class Charts extends DocsExamplesBase +{ + @Test + public void createBubbleChart() throws Exception + { + //ExStart:BubbleChart + Document doc = new Document(getMyDir() + "Reporting engine template - Bubble chart.docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, Common.getManagers(), "managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.CreateBubbleChart.docx"); + //ExEnd:BubbleChart + } + + @Test + public void setChartSeriesNameDynamically() throws Exception + { + //ExStart:SetChartSeriesNameDynamically + Document doc = new Document(getMyDir() + "Reporting engine template - Chart.docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, Common.getManagers(), "managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.SetChartSeriesNameDynamically.docx"); + //ExEnd:SetChartSeriesNameDynamically + } + + @Test + public void chartWithFilteringGroupingOrdering() throws Exception + { + //ExStart:ChartWithFilteringGroupingOrdering + Document doc = new Document(getMyDir() + "Reporting engine template - Chart with filtering.docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, Common.getContracts(), "contracts"); + + doc.save(getArtifactsDir() + "ReportingEngine.ChartWithFilteringGroupingOrdering.docx"); + //ExEnd:ChartWithFilteringGroupingOrdering + } + + @Test + public void pieChart() throws Exception + { + //ExStart:PieChart + Document doc = new Document(getMyDir() + "Reporting engine template - Pie chart.docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, Common.getManagers(), "managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.PieChart.docx"); + //ExEnd:PieChart + } + + @Test + public void scatterChart() throws Exception + { + //ExStart:ScatterChart + Document doc = new Document(getMyDir() + "Reporting engine template - Scatter chart.docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, Common.getContracts(), "contracts"); + + doc.save(getArtifactsDir() + "ReportingEngine.ScatterChart.docx"); + //ExEnd:ScatterChart + } +} diff --git a/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Helpers/Common.java b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Helpers/Common.java new file mode 100644 index 00000000..401aadda --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Helpers/Common.java @@ -0,0 +1,164 @@ +package DocsExamples.LINQ_Reporting_Engine.Helpers; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import DocsExamples.LINQ_Reporting_Engine.Helpers.Data_Source_Objects.Manager; +import java.util.Iterator; +import DocsExamples.LINQ_Reporting_Engine.Helpers.Data_Source_Objects.Client; +import DocsExamples.LINQ_Reporting_Engine.Helpers.Data_Source_Objects.Contract; +import com.aspose.ms.System.DateTime; +import com.aspose.ms.System.IO.File; + + +class Common extends DocsExamplesBase +{ + /// + /// Return the first manager from Managers, which is an enumeration of instances of the Manager class. + /// + public static Manager getManager() throws Exception + { + //ExStart:GetManager + Iterator managers = getManagers().iterator(); + managers.hasNext(); + + return managers.next(); + //ExEnd:GetManager + } + + /// + /// Return an enumeration of instances of the Client class. + /// + public static Iterable getClients() throws Exception + { + //ExStart:GetClients + for (Manager manager : getManagers()) + { + for (Contract contract : manager.getContracts()) + yield return contract.getClient(); + } + //ExEnd:GetClients + } + + /// + /// Return an enumeration of instances of the Manager class. + /// + public static Iterable getManagers() throws Exception + { + //ExStart:GetManagers + Manager manager = new Manager(); { manager.setName("John Smith"); manager.setAge(36); manager.setPhoto(photo()); } + manager.setContracts(new Contract[] + { + new Contract(); + { + manager.getContracts().setClient(new Client()); + { + manager.getContracts().getClient().setName("A Company"); manager.getContracts().getClient().setCountry("Australia"); + manager.getContracts().getClient().setLocalAddress("219-241 Cleveland St STRAWBERRY HILLS NSW 1427"); + } + manager.getContracts().setManager(manager); manager.getContracts().setPrice(1200000f); manager.getContracts().setDate(new DateTime(2015, 1, 1)); + }, + new Contract(); + { + manager.getContracts().setClient(new Client()); + { + manager.getContracts().getClient().setName("B Ltd."); manager.getContracts().getClient().setCountry("Brazil"); + manager.getContracts().getClient().setLocalAddress("Avenida João Jorge, 112, ap. 31 Vila Industrial Campinas - SP 13035-680"); + } + manager.getContracts().setManager(manager); manager.getContracts().setPrice(750000f); manager.getContracts().setDate(new DateTime(2015, 4, 1)); + }, + new Contract(); + { + manager.getContracts().setClient(new Client()); + { + manager.getContracts().getClient().setName("C & D"); manager.getContracts().getClient().setCountry("Canada"); + manager.getContracts().getClient().setLocalAddress("101-3485 RUE DE LA MONTAGNE MONTRÉAL (QUÉBEC) H3G 2A6"); + } + manager.getContracts().setManager(manager); manager.getContracts().setPrice(350000f); manager.getContracts().setDate(new DateTime(2015, 7, 1)); + } + }); + yield return manager; + + manager = new Manager(); { manager.setName("Tony Anderson"); manager.setAge(37); manager.setPhoto(photo()); } + manager.setContracts(new Contract[] + { + new Contract(); + { + manager.getContracts().setClient(new Client()); + { manager.getContracts().getClient().setName("E Corp."); manager.getContracts().getClient().setLocalAddress("445 Mount Eden Road Mount Eden Auckland 1024"); } + manager.getContracts().setManager(manager); manager.getContracts().setPrice(650000f); manager.getContracts().setDate(new DateTime(2015, 2, 1)); + }, + new Contract(); + { + manager.getContracts().setClient(new Client()); + { manager.getContracts().getClient().setName("F & Partners"); manager.getContracts().getClient().setLocalAddress("20 Greens Road Tuahiwi Kaiapoi 7691 "); } + manager.getContracts().setManager(manager); manager.getContracts().setPrice(550000f); manager.getContracts().setDate(new DateTime(2015, 8, 1)); + }, + }); + yield return manager; + + manager = new Manager(); { manager.setName("July James"); manager.setAge(38); manager.setPhoto(photo()); } + manager.setContracts(new Contract[] + { + new Contract(); + { + manager.getContracts().setClient(new Client()); + { manager.getContracts().getClient().setName("G & Co."); manager.getContracts().getClient().setCountry("Greece"); manager.getContracts().getClient().setLocalAddress("Karkisias 6 GR-111 42 ATHINA GRÉCE"); } + manager.getContracts().setManager(manager); manager.getContracts().setPrice(350000f); manager.getContracts().setDate(new DateTime(2015, 2, 1)); + }, + new Contract(); + { + manager.getContracts().setClient(new Client()); + { + manager.getContracts().getClient().setName("H Group"); manager.getContracts().getClient().setCountry("Hungary"); + manager.getContracts().getClient().setLocalAddress("Budapest Fiktív utca 82., IV. em./28.2806"); + } + manager.getContracts().setManager(manager); manager.getContracts().setPrice(250000f); manager.getContracts().setDate(new DateTime(2015, 5, 1)); + }, + new Contract(); + { + manager.getContracts().setClient(new Client()); + { manager.getContracts().getClient().setName("I & Sons"); manager.getContracts().getClient().setLocalAddress("43 Vogel Street Roslyn Palmerston North 4414"); } + manager.getContracts().setManager(manager); manager.getContracts().setPrice(100000f); manager.getContracts().setDate(new DateTime(2015, 7, 1)); + }, + new Contract(); + { + manager.getContracts().setClient(new Client()); + { + manager.getContracts().getClient().setName("J Ent."); manager.getContracts().getClient().setCountry("Japan"); + manager.getContracts().getClient().setLocalAddress("Hakusan 4-Chōme 3-2 Bunkyō-ku, TŌKYŌ 112-0001 Japan"); + } + manager.getContracts().setManager(manager); manager.getContracts().setPrice(100000f); manager.getContracts().setDate(new DateTime(2015, 8, 1)); + } + }); + yield return manager; + //ExEnd:GetManagers + } + + /// + /// Return an array of photo bytes. + /// + private static byte[] photo() throws Exception + { + //ExStart:Photo + // Load the photo and read all bytes + byte[] logo = com.aspose.ms.System.IO.File.readAllBytes(getImagesDir() + "Logo.jpg"); + + return logo; + //ExEnd:Photo + } + + /// + /// Return an enumeration of instances of the Contract class. + /// + public static Iterable getContracts() throws Exception + { + //ExStart:GetContracts + for (Manager manager : getManagers()) + { + for (Contract contract : manager.getContracts()) + yield return contract; + } + //ExEnd:GetContracts + } +} diff --git a/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Helpers/Data_Source_Objects/BackgroundColor.java b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Helpers/Data_Source_Objects/BackgroundColor.java new file mode 100644 index 00000000..24b27d23 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Helpers/Data_Source_Objects/BackgroundColor.java @@ -0,0 +1,30 @@ +package DocsExamples.LINQ_Reporting_Engine.Helpers.Data_Source_Objects; + +// ********* THIS FILE IS AUTO PORTED ********* + +import java.awt.Color; + + +//ExStart:Color +public class BackgroundColor +{ + public String getName() { return mName; }; public void setName(String value) { mName = value; }; + + private String mName; + public Color getColor() { return mColor; }; public void setColor(Color value) { mColor = value; }; + + private Color mColor; + public int? getColorCode() { return mColorCode; }; public void setColorCode(int? value) { mColorCode = value; }; + + private int? mColorCode; + public double? getValue1() { return mValue1; }; public void setValue1(double? value) { mValue1 = value; }; + + private double? mValue1; + public double? getValue2() { return mValue2; }; public void setValue2(double? value) { mValue2 = value; }; + + private double? mValue2; + public double? getValue3() { return mValue3; }; public void setValue3(double? value) { mValue3 = value; }; + + private double? mValue3; +} +//ExEnd:Color diff --git a/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Helpers/Data_Source_Objects/Client.java b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Helpers/Data_Source_Objects/Client.java new file mode 100644 index 00000000..af4a46b3 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Helpers/Data_Source_Objects/Client.java @@ -0,0 +1,19 @@ +package DocsExamples.LINQ_Reporting_Engine.Helpers.Data_Source_Objects; + +// ********* THIS FILE IS AUTO PORTED ********* + + +//ExStart:Client +public class Client +{ + public String getName() { return mName; }; public void setName(String value) { mName = value; }; + + private String mName; + public String getCountry() { return mCountry; }; public void setCountry(String value) { mCountry = value; }; + + private String mCountry; + public String getLocalAddress() { return mLocalAddress; }; public void setLocalAddress(String value) { mLocalAddress = value; }; + + private String mLocalAddress; +} +//ExEnd:Client diff --git a/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Helpers/Data_Source_Objects/Contract.java b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Helpers/Data_Source_Objects/Contract.java new file mode 100644 index 00000000..3f224221 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Helpers/Data_Source_Objects/Contract.java @@ -0,0 +1,24 @@ +package DocsExamples.LINQ_Reporting_Engine.Helpers.Data_Source_Objects; + +// ********* THIS FILE IS AUTO PORTED ********* + +import com.aspose.ms.System.DateTime; + + +//ExStart:Contract +public class Contract +{ + public Manager getManager() { return mManager; }; public void setManager(Manager value) { mManager = value; }; + + private Manager mManager; + public Client getClient() { return mClient; }; public void setClient(Client value) { mClient = value; }; + + private Client mClient; + public float getPrice() { return mPrice; }; public void setPrice(float value) { mPrice = value; }; + + private float mPrice; + public DateTime getDate() { return mDate; }; public void setDate(DateTime value) { mDate = value; }; + + private DateTime mDate; +} +//ExEnd:Contract diff --git a/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Helpers/Data_Source_Objects/Manager.java b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Helpers/Data_Source_Objects/Manager.java new file mode 100644 index 00000000..ac13d6a1 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Helpers/Data_Source_Objects/Manager.java @@ -0,0 +1,23 @@ +package DocsExamples.LINQ_Reporting_Engine.Helpers.Data_Source_Objects; + +// ********* THIS FILE IS AUTO PORTED ********* + + + +//ExStart:Manager +public class Manager +{ + public String getName() { return mName; }; public void setName(String value) { mName = value; }; + + private String mName; + public int getAge() { return mAge; }; public void setAge(int value) { mAge = value; }; + + private int mAge; + public byte[] getPhoto() { return mPhoto; }; public void setPhoto(byte[] value) { mPhoto = value; }; + + private byte[] mPhoto; + public Iterable getContracts() { return mContracts; }; public void setContracts(Iterable value) { mContracts = value; }; + + private Iterable mContracts; +} +//ExEnd:Manager diff --git a/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Helpers/Data_Source_Objects/PointData.java b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Helpers/Data_Source_Objects/PointData.java new file mode 100644 index 00000000..bd439c81 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Helpers/Data_Source_Objects/PointData.java @@ -0,0 +1,20 @@ +package DocsExamples.LINQ_Reporting_Engine.Helpers.Data_Source_Objects; + +// ********* THIS FILE IS AUTO PORTED ********* + + +//ExStart:PointDataClass +public class PointData +{ + public String getTime() { return mTime; }; public void setTime(String value) { mTime = value; }; + + private String mTime; + public int getFlow() { return mFlow; }; public void setFlow(int value) { mFlow = value; }; + + private int mFlow; + public int getRainfall() { return mRainfall; }; public void setRainfall(int value) { mRainfall = value; }; + + private int mRainfall; +} +//ExEnd:PointDataClass + diff --git a/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Helpers/Data_Source_Objects/Sender.java b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Helpers/Data_Source_Objects/Sender.java new file mode 100644 index 00000000..3d073b80 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Helpers/Data_Source_Objects/Sender.java @@ -0,0 +1,16 @@ +package DocsExamples.LINQ_Reporting_Engine.Helpers.Data_Source_Objects; + +// ********* THIS FILE IS AUTO PORTED ********* + + +//ExStart:Sender +public class Sender +{ + public String getName() { return mName; }; public void setName(String value) { mName = value; }; + + private String mName; + public String getMessage() { return mMessage; }; public void setMessage(String value) { mMessage = value; }; + + private String mMessage; +} +//ExEnd:Sender diff --git a/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Lists.java b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Lists.java new file mode 100644 index 00000000..98d943e7 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Lists.java @@ -0,0 +1,94 @@ +package DocsExamples.LINQ_Reporting_Engine; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.ReportingEngine; +import com.aspose.words.DocumentBuilder; + + +public class Lists extends DocsExamplesBase +{ + @Test + public void createBulletedList() throws Exception + { + //ExStart:BulletedList + Document doc = new Document(getMyDir() + "Reporting engine template - Bulleted list.docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, Common.getClients(), "clients"); + + doc.save(getArtifactsDir() + "ReportingEngine.CreateBulletedList.docx"); + //ExEnd:BulletedList + } + + @Test + public void commonList() throws Exception + { + //ExStart:CommonList + Document doc = new Document(getMyDir() + "Reporting engine template - Common master detail.docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, Common.getManagers(), "managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.CommonList.docx"); + //ExEnd:CommonList + } + + @Test + public void inParagraphList() throws Exception + { + //ExStart:InParagraphList + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("<><<[IndexOf() !=0 ? ”, ”: ””]>><<[Name]>><>"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, Common.getClients(), "clients"); + + doc.save(getArtifactsDir() + "ReportingEngine.InParagraphList.docx"); + //ExEnd:InParagraphList + } + + @Test + public void inTableList() throws Exception + { + //ExStart:InTableList + Document doc = new Document(getMyDir() + "Reporting engine template - Contextual object member access.docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, Common.getManagers(), "Managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.InTableList.docx"); + //ExEnd:InTableList + } + + @Test + public void multicoloredNumberedList() throws Exception + { + //ExStart:MulticoloredNumberedList + Document doc = new Document(getMyDir() + "Reporting engine template - Multicolored numbered list.docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, Common.getClients(), "clients"); + + doc.save(getArtifactsDir() + "ReportingEngine.MulticoloredNumberedList.doc"); + //ExEnd:MulticoloredNumberedList + } + + @Test + public void numberedList() throws Exception + { + //ExStart:NumberedList + Document doc = new Document(getMyDir() + "Reporting engine template - Numbered list.docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, Common.getClients(), "clients"); + + doc.save(getArtifactsDir() + "ReportingEngine.NumberedList.docx"); + //ExEnd:NumberedList + } +} diff --git a/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Tables.java b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Tables.java new file mode 100644 index 00000000..040f9af7 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/LINQ_Reporting_Engine/Tables.java @@ -0,0 +1,51 @@ +package DocsExamples.LINQ_Reporting_Engine; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.ReportingEngine; + + +class Tables extends DocsExamplesBase +{ + @Test + public void inTableAlternateContent() throws Exception + { + //ExStart:InTableAlternateContent + Document doc = new Document(getMyDir() + "Reporting engine template - Total.docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, Common.getContracts(), "Contracts"); + + doc.save(getArtifactsDir() + "ReportingEngine.InTableAlternateContent.docx"); + //ExEnd:InTableAlternateContent + } + + @Test + public void inTableMasterDetail() throws Exception + { + //ExStart:InTableMasterDetail + Document doc = new Document(getMyDir() + "Reporting engine template - Nested data table.docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, Common.getManagers(), "Managers"); + + doc.save(getArtifactsDir() + "ReportingEngine.InTableMasterDetail.docx"); + //ExEnd:InTableMasterDetail + } + + @Test + public void inTableWithFilteringGroupingSorting() throws Exception + { + //ExStart:InTableWithFilteringGroupingSorting + Document doc = new Document(getMyDir() + "Reporting engine template - Table with filtering.docx"); + + ReportingEngine engine = new ReportingEngine(); + engine.buildReport(doc, Common.getContracts(), "contracts"); + + doc.save(getArtifactsDir() + "ReportingEngine.InTableWithFilteringGroupingSorting.docx"); + //ExEnd:InTableWithFilteringGroupingSorting + } +} diff --git a/Examples/DocsExamples/JavaPorting/Mail_Merge_And_Reporting/BaseOperations.java b/Examples/DocsExamples/JavaPorting/Mail_Merge_And_Reporting/BaseOperations.java new file mode 100644 index 00000000..2b6327e7 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Mail_Merge_And_Reporting/BaseOperations.java @@ -0,0 +1,286 @@ +package DocsExamples.Mail_Merge_and_Reporting; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.net.System.Data.DataTable; +import com.aspose.words.net.System.Data.DataRow; +import com.aspose.words.net.System.Data.DataView; +import java.text.MessageFormat; +import com.aspose.words.net.System.Data.DataSet; +import com.aspose.words.MailMergeRegionInfo; +import java.util.ArrayList; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; + + +public class BaseOperations extends DocsExamplesBase +{ + @Test + public void simpleMailMerge() throws Exception + { + //ExStart:ExecuteSimpleMailMerge + //GistId:341b834e9b6a84ac6885e907e0ea4229 + // Include the code for our template. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create Merge Fields. + builder.insertField(" MERGEFIELD CustomerName "); + builder.insertParagraph(); + builder.insertField(" MERGEFIELD Item "); + builder.insertParagraph(); + builder.insertField(" MERGEFIELD Quantity "); + + // Fill the fields in the document with user data. + doc.getMailMerge().execute(new String[] { "CustomerName", "Item", "Quantity" }, + new Object[] { "John Doe", "Hawaiian", "2" }); + + doc.save(getArtifactsDir() + "BaseOperations.SimpleMailMerge.docx"); + //ExEnd:ExecuteSimpleMailMerge + } + + @Test + public void useIfElseMustache() throws Exception + { + //ExStart:UseIfElseMustache + //GistId:544788f602e697802e313a641cedb9b8 + Document doc = new Document(getMyDir() + "Mail merge destinations - Mustache syntax.docx"); + + doc.getMailMerge().setUseNonMergeFields(true); + doc.getMailMerge().execute(new String[] { "GENDER" }, new Object[] { "MALE" }); + + doc.save(getArtifactsDir() + "BaseOperations.IfElseMustache.docx"); + //ExEnd:UseIfElseMustache + } + + @Test + public void mustacheSyntaxUsingDataTable() throws Exception + { + //ExStart:MustacheSyntaxUsingDataTable + //GistId:544788f602e697802e313a641cedb9b8 + Document doc = new Document(getMyDir() + "Mail merge destinations - Vendor.docx"); + + // Loop through each row and fill it with data. + DataTable dataTable = new DataTable("list"); + dataTable.getColumns().add("Number"); + for (int i = 0; i < 10; i++) + { + DataRow dataRow = dataTable.newRow(); + dataTable.getRows().add(dataRow); + dataRow.set(0, "Number " + i); + } + + // Activate performing a mail merge operation into additional field types. + doc.getMailMerge().setUseNonMergeFields(true); + + doc.getMailMerge().executeWithRegions(dataTable); + + doc.save(getArtifactsDir() + "WorkingWithXmlData.MustacheSyntaxUsingDataTable.docx"); + //ExEnd:MustacheSyntaxUsingDataTable + } + + @Test (groups = "IgnoreOnJenkins") + public void executeWithRegionsDataTable() throws Exception + { + //ExStart:ExecuteWithRegionsDataTable + //GistId:de5e13f5d5bb7d8cb88da900b4f9ed8b + Document doc = new Document(getMyDir() + "Mail merge destinations - Orders.docx"); + + // Use DataTable as a data source. + int orderId = 10444; + DataTable orderTable = getTestOrder(orderId); + doc.getMailMerge().executeWithRegions(orderTable); + + // Instead of using DataTable, you can create a DataView for custom sort or filter and then mail merge. + DataView orderDetailsView = new DataView(getTestOrderDetails(orderId)); + orderDetailsView.setSort("ExtendedPrice DESC"); + + // Execute the mail merge operation. + doc.getMailMerge().executeWithRegions(orderDetailsView); + + doc.save(getArtifactsDir() + "MailMerge.ExecuteWithRegions.docx"); + //ExEnd:ExecuteWithRegionsDataTable + } + + //ExStart:ExecuteWithRegionsDataTableMethods + private DataTable getTestOrder(int orderId) + { + DataTable table = executeDataTable($"SELECT * FROM AsposeWordOrders WHERE OrderId = {orderId}"); + table.setTableName("Orders"); + + return table; + } + + private DataTable getTestOrderDetails(int orderId) + { + DataTable table = executeDataTable( + $"SELECT * FROM AsposeWordOrderDetails WHERE OrderId = {orderId} ORDER BY ProductID"); + table.setTableName("OrderDetails"); + + return table; + } + + /// + /// Utility function that creates a connection, command, executes the command and returns the result in a DataTable. + /// + private DataTable executeDataTable(String commandText) + { + String connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + getDatabaseDir() + "Northwind.accdb"; + + OleDbConnection conn = new OleDbConnection(connString); + conn.Open(); + + OleDbCommand cmd = new OleDbCommand(commandText, conn); + OleDbDataAdapter da = new OleDbDataAdapter(cmd); + + DataTable table = new DataTable(); + da.Fill(table); + + conn.Close(); + + return table; + } + //ExEnd:ExecuteWithRegionsDataTableMethods + + @Test (groups = "IgnoreOnJenkins") + public void produceMultipleDocuments() throws Exception + { + //ExStart:ProduceMultipleDocuments + //GistId:341b834e9b6a84ac6885e907e0ea4229 + String connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + getDatabaseDir() + "Northwind.accdb"; + + Document doc = new Document(getMyDir() + "Mail merge destination - Suppliers.docx"); + + OleDbConnection conn = new OleDbConnection(connString); + conn.Open(); + + OleDbCommand cmd = new OleDbCommand("SELECT * FROM Customers", conn); + OleDbDataAdapter da = new OleDbDataAdapter(cmd); + + DataTable data = new DataTable(); + da.Fill(data); + + // Perform a loop through each DataRow to iterate through the DataTable. Clone the template document + // instead of loading it from disk for better speed performance before the mail merge operation. + // You can load the template document from a file or stream but it is faster to load the document + // only once and then clone it in memory before each mail merge operation. + + int counter = 1; + for (DataRow row : (Iterable) data.getRows()) + { + Document dstDoc = (Document) doc.deepClone(true); + + dstDoc.getMailMerge().execute(row); + + dstDoc.save(MessageFormat.format(getArtifactsDir() + "BaseOperations.ProduceMultipleDocuments_{0}.docx", counter++)); + } + //ExEnd:ProduceMultipleDocuments + } + + @Test + public void mailMergeWithRegions() throws Exception + { + //ExStart:MailMergeWithRegions + //GistId:341b834e9b6a84ac6885e907e0ea4229 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // The start point of mail merge with regions the dataset. + builder.insertField(" MERGEFIELD TableStart:Customers"); + + // Data from rows of the "CustomerName" column of the "Customers" table will go in this MERGEFIELD. + builder.write("Orders for "); + builder.insertField(" MERGEFIELD CustomerName"); + builder.write(":"); + + // Create column headers. + builder.startTable(); + builder.insertCell(); + builder.write("Item"); + builder.insertCell(); + builder.write("Quantity"); + builder.endRow(); + + // We have a second data table called "Orders", which has a many-to-one relationship with "Customers" + // picking up rows with the same CustomerID value. + builder.insertCell(); + builder.insertField(" MERGEFIELD TableStart:Orders"); + builder.insertField(" MERGEFIELD ItemName"); + builder.insertCell(); + builder.insertField(" MERGEFIELD Quantity"); + builder.insertField(" MERGEFIELD TableEnd:Orders"); + builder.endTable(); + + // The end point of mail merge with regions. + builder.insertField(" MERGEFIELD TableEnd:Customers"); + + // Pass our dataset to perform mail merge with regions. + DataSet customersAndOrders = createDataSet(); + doc.getMailMerge().executeWithRegions(customersAndOrders); + + doc.save(getArtifactsDir() + "BaseOperations.MailMergeWithRegions.docx"); + //ExEnd:MailMergeWithRegions + } + + //ExStart:CreateDataSet + //GistId:341b834e9b6a84ac6885e907e0ea4229 + private DataSet createDataSet() + { + // Create the customers table. + DataTable tableCustomers = new DataTable("Customers"); + tableCustomers.getColumns().add("CustomerID"); + tableCustomers.getColumns().add("CustomerName"); + tableCustomers.getRows().add(new Object[] { 1, "John Doe" }); + tableCustomers.getRows().add(new Object[] { 2, "Jane Doe" }); + + // Create the orders table. + DataTable tableOrders = new DataTable("Orders"); + tableOrders.getColumns().add("CustomerID"); + tableOrders.getColumns().add("ItemName"); + tableOrders.getColumns().add("Quantity"); + tableOrders.getRows().add(new Object[] { 1, "Hawaiian", 2 }); + tableOrders.getRows().add(new Object[] { 2, "Pepperoni", 1 }); + tableOrders.getRows().add(new Object[] { 2, "Chicago", 1 }); + + // Add both tables to a data set. + DataSet dataSet = new DataSet(); + dataSet.getTables().add(tableCustomers); + dataSet.getTables().add(tableOrders); + + // The "CustomerID" column, also the primary key of the customers table is the foreign key for the Orders table. + dataSet.getRelations().add(tableCustomers.getColumns().get("CustomerID"), tableOrders.getColumns().get("CustomerID")); + + return dataSet; + } + //ExEnd:CreateDataSet + + @Test + public void getRegionsByName() throws Exception + { + //ExStart:GetRegionsByName + //GistId:b4bab1bf22437a86d8062e91cf154494 + Document doc = new Document(getMyDir() + "Mail merge regions.docx"); + + //ExStart:GetRegionsHierarchy + //GistId:b4bab1bf22437a86d8062e91cf154494 + MailMergeRegionInfo regionInfo = doc.getMailMerge().getRegionsHierarchy(); + //ExEnd:GetRegionsHierarchy + + ArrayList regions = doc.getMailMerge().getRegionsByName("Region1"); + Assert.assertEquals(1, doc.getMailMerge().getRegionsByName("Region1").size()); + for (MailMergeRegionInfo region : regions) Assert.assertEquals("Region1", region.getName()); + + regions = doc.getMailMerge().getRegionsByName("Region2"); + Assert.assertEquals(1, doc.getMailMerge().getRegionsByName("Region2").size()); + for (MailMergeRegionInfo region : regions) Assert.assertEquals("Region2", region.getName()); + + regions = doc.getMailMerge().getRegionsByName("NestedRegion1"); + Assert.assertEquals(2, doc.getMailMerge().getRegionsByName("NestedRegion1").size()); + for (MailMergeRegionInfo region : regions) Assert.assertEquals("NestedRegion1", region.getName()); + //ExEnd:GetRegionsByName + } +} diff --git a/Examples/DocsExamples/JavaPorting/Mail_Merge_And_Reporting/Complex_examples_and_helpers/ApplyCustomLogicToEmptyRegions.java b/Examples/DocsExamples/JavaPorting/Mail_Merge_And_Reporting/Complex_examples_and_helpers/ApplyCustomLogicToEmptyRegions.java new file mode 100644 index 00000000..a5b77199 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Mail_Merge_And_Reporting/Complex_examples_and_helpers/ApplyCustomLogicToEmptyRegions.java @@ -0,0 +1,334 @@ +package DocsExamples.Mail_Merge_and_Reporting.Custom_examples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.net.System.Data.DataSet; +import com.aspose.words.MailMergeCleanupOptions; +import java.util.ArrayList; +import com.aspose.words.net.System.Data.DataTable; +import com.aspose.words.IFieldMergingCallback; +import com.aspose.words.FieldMergingArgs; +import com.aspose.words.Table; +import com.aspose.words.NodeType; +import com.aspose.words.Paragraph; +import com.aspose.words.StyleIdentifier; +import com.aspose.words.ImageFieldMergingArgs; +import com.aspose.words.FindReplaceOptions; +import com.aspose.words.ParagraphAlignment; +import com.aspose.words.Cell; +import com.aspose.words.CellMerge; +import com.aspose.words.net.System.Data.DataRelation; + + +class ApplyCustomLogicToEmptyRegions extends DocsExamplesBase +{ + @Test + public void executeWithRegionsNestedCustom() throws Exception + { + //ExStart:ApplyCustomLogicToEmptyRegions + Document doc = new Document(getMyDir() + "Mail merge destination - Northwind suppliers.docx"); + + // Create a data source which has some data missing. + // This will result in some regions are merged, and some remain after executing mail merge + DataSet data = getDataSource(); + + // Ensure that we have not set the removal of any unused regions as we will handle them manually. + // We achieve this by removing the RemoveUnusedRegions flag from the cleanup options using the AND and NOT bitwise operators. + doc.getMailMerge().setCleanupOptions(doc.getMailMerge().getCleanupOptions() & ~MailMergeCleanupOptions.REMOVE_UNUSED_REGIONS); + + doc.getMailMerge().executeWithRegions(data); + + // Regions without data and not merged will remain in the document. + Document mergedDoc = doc.deepClone(); //ExSkip + + // Apply logic to each unused region left in the document. + executeCustomLogicOnEmptyRegions(doc, new EmptyRegionsHandler()); + + doc.save(getArtifactsDir() + "MailMerge.ExecuteWithRegionsNestedCustom_1.docx"); + + doc = mergedDoc.deepClone(); + + // Apply different logic to unused regions this time. + executeCustomLogicOnEmptyRegions(doc, new EmptyRegionsHandlerMergeTable()); + + doc.save(getArtifactsDir() + "MailMerge.ExecuteWithRegionsNestedCustom_2.docx"); + //ExEnd:ApplyCustomLogicToEmptyRegions + + doc = mergedDoc.deepClone(); + + //ExStart:ContactDetails + ArrayList regions = new ArrayList(); + regions.add("ContactDetails"); + + // Only handle the ContactDetails region in our handler. + executeCustomLogicOnEmptyRegions(doc, new EmptyRegionsHandler(), regions); + //ExEnd:ContactDetails + + doc.save(getArtifactsDir() + "MailMerge.ExecuteWithRegionsNestedCustom_3.docx"); + } + + //ExStart:CreateDataSourceFromDocumentRegions + /// + /// Returns a DataSet object containing a DataTable for the unmerged regions in the specified document. + /// If regionsList is null all regions found within the document are included. If an List instance is present, + /// the only regions specified in the list found in the document are added. + /// + private DataSet createDataSourceFromDocumentRegions(Document doc, ArrayList regionsList) throws Exception + { + final String TABLE_START_MARKER = "TableStart:"; + DataSet dataSet = new DataSet(); + String tableName = null; + + for (String fieldName : doc.getMailMerge().getFieldNames()) + { + if (fieldName.contains(TABLE_START_MARKER)) + { + tableName = fieldName.substring(TABLE_START_MARKER.length()); + } + else if (tableName != null) + { + // Add the table name as a new DataTable if it doesn't already exist in the DataSet. + if (dataSet.getTables().get(tableName) == null) + { + DataTable table = new DataTable(tableName); + table.getColumns().add(fieldName); + + // We only need to add the first field for the handler to be called for the region's fields. + if (regionsList == null || regionsList.contains(tableName)) + { + table.getRows().add("FirstField"); + } + + dataSet.getTables().add(table); + } + + tableName = null; + } + } + + return dataSet; + } + //ExEnd:CreateDataSourceFromDocumentRegions + + //ExStart:ExecuteCustomLogicOnEmptyRegions + /// + /// Applies logic defined in the passed handler class to all unused regions in the document. + /// This allows controlling how unused regions are handled in the document manually. + /// + /// The document containing unused regions. + /// The handler which implements the IFieldMergingCallback interface + /// and defines the logic to be applied to each unmerged region. + public void executeCustomLogicOnEmptyRegions(Document doc, IFieldMergingCallback handler) throws Exception + { + // Pass null to handle all regions found in the document. + executeCustomLogicOnEmptyRegions(doc, handler, null); + } + + /// + /// Applies logic defined in the passed handler class to specific unused regions in the document as defined in regionsList. + /// This allows controlling how unused regions are handled in the document manually. + /// + /// The document containing unused regions. + /// The handler which implements the IFieldMergingCallback interface and defines + /// the logic to be applied to each unmerged region. + /// A list of strings corresponding to the region names that are to be handled + /// by the supplied handler class. Other regions encountered will not be handled and are removed automatically. + public void executeCustomLogicOnEmptyRegions(Document doc, IFieldMergingCallback handler, + ArrayList regionsList) throws Exception + { + // Certain regions can be skipped from applying logic to by not adding + // the table name inside the CreateEmptyDataSource method. Enable this cleanup option, so any regions + // which are not handled by the user's logic are removed automatically. + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_UNUSED_REGIONS); + + // Set the user's handler, which is called for each unmerged region. + doc.getMailMerge().setFieldMergingCallback(handler); + + // Execute mail merge using the dummy dataset. The dummy data source contains each unmerged region's table names + // in the document (excluding ones that the user may have specified to be skipped). + // This will allow the handler to be called for each field in the unmerged regions. + doc.getMailMerge().executeWithRegions(createDataSourceFromDocumentRegions(doc, regionsList)); + } + //ExEnd:ExecuteCustomLogicOnEmptyRegions + + //ExStart:EmptyRegionsHandler + public static class EmptyRegionsHandler implements IFieldMergingCallback + { + /// + /// Called for each field belonging to an unmerged region in the document. + /// + public void fieldMerging(FieldMergingArgs args) + { + // Change the text of each field of the ContactDetails region individually. + if ("ContactDetails".equals(args.getTableName())) + { + // Set the text of the field based off the field name. + if ("Name".equals(args.getFieldName())) + args.setText("(No details found)"); + else if ("Number".equals(args.getFieldName())) + args.setText("(N/A)"); + } + + // Remove the entire table of the Suppliers region. Also, check if the previous paragraph + // before the table is a heading paragraph and remove that. + if ("Suppliers".equals(args.getTableName())) + { + Table table = (Table) args.getField().getStart().getAncestor(NodeType.TABLE); + + // Check if the table has been removed from the document already. + if (table.getParentNode() != null) + { + // Try to find the paragraph which precedes the table before the table is removed from the document. + if (table.getPreviousSibling() != null && table.getPreviousSibling().getNodeType() == NodeType.PARAGRAPH) + { + Paragraph previousPara = (Paragraph) table.getPreviousSibling(); + if (isHeadingParagraph(previousPara)) + previousPara.remove(); + } + + table.remove(); + } + } + } + + /// + /// Returns true if the paragraph uses any Heading style, e.g., Heading 1 to Heading 9. + /// + private boolean isHeadingParagraph(Paragraph para) + { + return para.getParagraphFormat().getStyleIdentifier() >= StyleIdentifier.HEADING_1 && + para.getParagraphFormat().getStyleIdentifier() <= StyleIdentifier.HEADING_9; + } + + public void imageFieldMerging(ImageFieldMergingArgs args) + { + // Do nothing. + } + } + //ExEnd:EmptyRegionsHandler + + public static class EmptyRegionsHandlerMergeTable implements IFieldMergingCallback + { + /// + /// Called for each field belonging to an unmerged region in the document. + /// + public void fieldMerging(FieldMergingArgs args) throws Exception + { + //ExStart:RemoveExtraParagraphs + // Store the parent paragraph of the current field for easy access. + Paragraph parentParagraph = args.getField().getStart().getParentParagraph(); + + // Define the logic to be used when the ContactDetails region is encountered. + // The region is removed and replaced with a single line of text stating that there are no records. + if ("ContactDetails".equals(args.getTableName())) + { + // Called for the first field encountered in a region. This can be used to execute logic on the first field + // in the region without needing to hard code the field name. Often the base logic is applied to the first field and + // different logic for other fields. The rest of the fields in the region will have a null FieldValue. + if ("FirstField".equals((String) args.getFieldValue())) + { + FindReplaceOptions options = new FindReplaceOptions(); + // Remove the "Name:" tag from the start of the paragraph. + parentParagraph.getRange().replace("Name:", "", options); + // Set the text of the first field to display a message stating that there are no records. + args.setText("No records to display"); + } + else + { + // We have already inserted our message in the paragraph belonging to the first field. + // The other paragraphs in the region will remain, so we want to remove these. + // A check is added to ensure that the paragraph has not been removed, + // which may happen if more than one field is included in a paragraph. + if (parentParagraph.getParentNode() != null) + parentParagraph.remove(); + } + } + //ExEnd:RemoveExtraParagraphs + + //ExStart:MergeAllCells + // Replace the unused region in the table with a "no records" message and merge all cells into one. + if ("Suppliers".equals(args.getTableName())) + { + if ("FirstField".equals((String) args.getFieldValue())) + { + // We will use the first paragraph to display our message. Make it centered within the table. + // The other fields in other cells within the table will be merged and won't be displayed, + // so we don't need to do anything else with them. + parentParagraph.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + args.setText("No records to display"); + } + + // Merge the cells of the table. + Cell cell = (Cell) parentParagraph.getAncestor(NodeType.CELL); + if (cell != null) + { + cell.getCellFormat().setHorizontalMerge(cell.isFirstCell() ? CellMerge.FIRST : CellMerge.PREVIOUS); + } + } + //ExEnd:MergeAllCells + } + + public void imageFieldMerging(ImageFieldMergingArgs args) + { + // Do Nothing + } + } + + /// + /// Returns the data used to merge the document. + /// This dataset purposely contains only rows for the StoreDetails region and only a select few for the child region. + /// + private DataSet getDataSource() + { + DataSet data = new DataSet(); + DataTable storeDetails = new DataTable("StoreDetails"); + DataTable contactDetails = new DataTable("ContactDetails"); + + contactDetails.getColumns().add("ID"); + contactDetails.getColumns().add("Name"); + contactDetails.getColumns().add("Number"); + + storeDetails.getColumns().add("ID"); + storeDetails.getColumns().add("Name"); + storeDetails.getColumns().add("Address"); + storeDetails.getColumns().add("City"); + storeDetails.getColumns().add("Country"); + + storeDetails.getRows().add("0", "Hungry Coyote Import Store", "2732 Baker Blvd", "Eugene", "USA"); + storeDetails.getRows().add("1", "Great Lakes Food Market", "City Center Plaza, 516 Main St.", "San Francisco", + "USA"); + + contactDetails.getRows().add("0", "Thomas Hardy", "(206) 555-9857 ext 237"); + contactDetails.getRows().add("0", "Elizabeth Brown", "(206) 555-9857 ext 764"); + + data.getTables().add(storeDetails); + data.getTables().add(contactDetails); + + data.getRelations().add(storeDetails.getColumns().get("ID"), contactDetails.getColumns().get("ID")); + + return data; + } + + private /*final*/ DataTable orderTable = null; + private /*final*/ DataTable itemTable = null; + + private void disableForeignKeyConstraints(DataSet dataSet) + { + //ExStart:DisableForeignKeyConstraints + //GistId:c68048adceb3bda6a1511c7d6f5ebf7b + dataSet.getRelations().add(new DataRelation("OrderToItem", orderTable.getColumns().get("Order_Id"), + itemTable.getColumns().get("Order_Id"), false)); + //ExEnd:DisableForeignKeyConstraints + } + + private void createDataRelation(DataSet dataSet) + { + //ExStart:CreateDataRelation + dataSet.getRelations().add(new DataRelation("OrderToItem", orderTable.getColumns().get("Order_Id"), + itemTable.getColumns().get("Order_Id"))); + //ExEnd:CreateDataRelation + } +} diff --git a/Examples/DocsExamples/JavaPorting/Mail_Merge_And_Reporting/Complex_examples_and_helpers/CreateMailMergeTemplate.java b/Examples/DocsExamples/JavaPorting/Mail_Merge_And_Reporting/Complex_examples_and_helpers/CreateMailMergeTemplate.java new file mode 100644 index 00000000..b9e7afb8 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Mail_Merge_And_Reporting/Complex_examples_and_helpers/CreateMailMergeTemplate.java @@ -0,0 +1,64 @@ +package DocsExamples.Mail_Merge_and_Reporting.Custom_examples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.TextFormFieldType; +import com.aspose.words.BreakType; + + +class CreateMailMergeTemplate +{ + + public Document template() throws Exception + { + //ExStart:CreateMailMergeTemplate + //GistId:0a1baaa127443b485cc692c8d98ee353 + DocumentBuilder builder = new DocumentBuilder(); + + // Insert a text input field the unique name of this field is "Hello", the other parameters define + // what type of FormField it is, the format of the text, the field result and the maximum text length (0 = no limit) + builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", "Hello", 0); + builder.insertField("MERGEFIELD CustomerFirstName \\* MERGEFORMAT"); + + builder.insertTextInput("TextInput1", TextFormFieldType.REGULAR, "", " ", 0); + builder.insertField("MERGEFIELD CustomerLastName \\* MERGEFORMAT"); + + builder.insertTextInput("TextInput1", TextFormFieldType.REGULAR, "", " , ", 0); + + // Inserts a paragraph break into the document + builder.insertParagraph(); + + // Insert mail body + builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", "Thanks for purchasing our ", 0); + builder.insertField("MERGEFIELD ProductName \\* MERGEFORMAT"); + + builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", ", please download your Invoice at ", + 0); + builder.insertField("MERGEFIELD InvoiceURL \\* MERGEFORMAT"); + + builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", + ". If you have any questions please call ", 0); + builder.insertField("MERGEFIELD Supportphone \\* MERGEFORMAT"); + + builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", ", or email us at ", 0); + builder.insertField("MERGEFIELD SupportEmail \\* MERGEFORMAT"); + + builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", ".", 0); + + builder.insertParagraph(); + + // Insert mail ending + builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", "Best regards,", 0); + builder.insertBreak(BreakType.LINE_BREAK); + builder.insertField("MERGEFIELD EmployeeFullname \\* MERGEFORMAT"); + + builder.insertTextInput("TextInput1", TextFormFieldType.REGULAR, "", " ", 0); + builder.insertField("MERGEFIELD EmployeeDepartment \\* MERGEFORMAT"); + + return builder.getDocument(); + //ExEnd:CreateMailMergeTemplate + } +} + diff --git a/Examples/DocsExamples/JavaPorting/Mail_Merge_And_Reporting/Complex_examples_and_helpers/NestedMailMergeCustom.java b/Examples/DocsExamples/JavaPorting/Mail_Merge_And_Reporting/Complex_examples_and_helpers/NestedMailMergeCustom.java new file mode 100644 index 00000000..2a101660 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Mail_Merge_And_Reporting/Complex_examples_and_helpers/NestedMailMergeCustom.java @@ -0,0 +1,245 @@ +package DocsExamples.Mail_Merge_and_Reporting.Custom_examples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import com.aspose.ms.java.collections.StringSwitchMap; +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import java.util.ArrayList; +import com.aspose.words.IMailMergeDataSource; +import com.aspose.words.ref.Ref; + + +class NestedMailMergeCustom extends DocsExamplesBase +{ + @Test + public void customMailMerge() throws Exception + { + //ExStart:NestedMailMergeCustom + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertField(" MERGEFIELD TableStart:Customer"); + + builder.write("Full name:\t"); + builder.insertField(" MERGEFIELD FullName "); + builder.write("\nAddress:\t"); + builder.insertField(" MERGEFIELD Address "); + builder.write("\nOrders:\n"); + + builder.insertField(" MERGEFIELD TableStart:Order"); + + builder.write("\tItem name:\t"); + builder.insertField(" MERGEFIELD Name "); + builder.write("\n\tQuantity:\t"); + builder.insertField(" MERGEFIELD Quantity "); + builder.insertParagraph(); + + builder.insertField(" MERGEFIELD TableEnd:Order"); + + builder.insertField(" MERGEFIELD TableEnd:Customer"); + + ArrayList customers = new ArrayList(); + { + customers.add(new Customer("Thomas Hardy", "120 Hanover Sq., London")); + customers.add(new Customer("Paolo Accorti", "Via Monte Bianco 34, Torino")); + } + + customers.get(0).getOrders().add(new Order("Rugby World Cup Cap", 2)); + customers.get(0).getOrders().add(new Order("Rugby World Cup Ball", 1)); + customers.get(1).getOrders().add(new Order("Rugby World Cup Guide", 1)); + + // To be able to mail merge from your data source, + // it must be wrapped into an object that implements the IMailMergeDataSource interface. + CustomerMailMergeDataSource customersDataSource = new CustomerMailMergeDataSource(customers); + + doc.getMailMerge().executeWithRegions(customersDataSource); + + doc.save(getArtifactsDir() + "NestedMailMergeCustom.CustomMailMerge.docx"); + //ExEnd:NestedMailMergeCustom + } + + /// + /// An example of a "data entity" class in your application. + /// + public static class Customer + { + public Customer(String aFullName, String anAddress) + { + setFullName(aFullName); + setAddress(anAddress); + setOrders(new ArrayList()); + } + + public String getFullName() { return mFullName; }; public void setFullName(String value) { mFullName = value; }; + + private String mFullName; + public String getAddress() { return mAddress; }; public void setAddress(String value) { mAddress = value; }; + + private String mAddress; + public ArrayList getOrders() { return mOrders; }; public void setOrders(ArrayList value) { mOrders = value; }; + + private ArrayList mOrders; + } + + /// + /// An example of a child "data entity" class in your application. + /// + public static class Order + { + public Order(String oName, int oQuantity) + { + setName(oName); + setQuantity(oQuantity); + } + + public String getName() { return mName; }; public void setName(String value) { mName = value; }; + + private String mName; + public int getQuantity() { return mQuantity; }; public void setQuantity(int value) { mQuantity = value; }; + + private int mQuantity; + } + + /// + /// A custom mail merge data source that you implement to allow Aspose.Words + /// to mail merge data from your Customer objects into Microsoft Word documents. + /// + public static class CustomerMailMergeDataSource implements IMailMergeDataSource + { + public CustomerMailMergeDataSource(ArrayList customers) + { + mCustomers = customers; + + // When the data source is initialized, it must be positioned before the first record. + mRecordIndex = -1; + } + + /// + /// The name of the data source. Used by Aspose.Words only when executing mail merge with repeatable regions. + /// + public String TableName => "Customer"; + + /// + /// Aspose.Words calls this method to get a value for every data field. + /// + public boolean getValue(String fieldName, /*out*/Ref fieldValue) + { + switch (gStringSwitchMap.of(fieldName)) + { + case /*"FullName"*/0: + fieldValue.set(mCustomers.get(mRecordIndex).getFullName()); + return true; + case /*"Address"*/1: + fieldValue.set(mCustomers.get(mRecordIndex).getAddress()); + return true; + case /*"Order"*/2: + fieldValue.set(mCustomers.get(mRecordIndex).getOrders()); + return true; + default: + fieldValue.set(null); + return false; + } + } + + /// + /// A standard implementation for moving to a next record in a collection. + /// + public boolean moveNext() + { + if (!IsEof) + mRecordIndex++; + + return !IsEof; + } + + //ExStart:GetChildDataSource + //GistId:c68048adceb3bda6a1511c7d6f5ebf7b + public IMailMergeDataSource getChildDataSource(String tableName) + { + switch (gStringSwitchMap.of(tableName)) + { + // Get the child collection to merge it with the region provided with tableName variable. + case /*"Order"*/2: + return new OrderMailMergeDataSource(mCustomers.get(mRecordIndex).getOrders()); + default: + return null; + } + } + //ExEnd:GetChildDataSource + + private boolean IsEof => (mRecordIndex >= mCustomers.Count); + + private /*final*/ ArrayList mCustomers; + private int mRecordIndex; + } + + public static class OrderMailMergeDataSource implements IMailMergeDataSource + { + public OrderMailMergeDataSource(ArrayList orders) + { + mOrders = orders; + + // When the data source is initialized, it must be positioned before the first record. + mRecordIndex = -1; + } + + /// + /// The name of the data source. Used by Aspose.Words only when executing mail merge with repeatable regions. + /// + public String TableName => "Order"; + + /// + /// Aspose.Words calls this method to get a value for every data field. + /// + public boolean getValue(String fieldName, /*out*/Ref fieldValue) + { + switch (gStringSwitchMap.of(fieldName)) + { + case /*"Name"*/3: + fieldValue.set(mOrders[mRecordIndex].Name); + return true; + case /*"Quantity"*/4: + fieldValue.set(mOrders[mRecordIndex].Quantity); + return true; + default: + fieldValue.set(null); + return false; + } + } + + /// + /// A standard implementation for moving to a next record in a collection. + /// + public boolean moveNext() + { + if (!IsEof) + mRecordIndex++; + + return !IsEof; + } + + public IMailMergeDataSource getChildDataSource(String tableName) + { + // Return null because we haven't any child elements for this sort of object. + return null; + } + + private boolean IsEof => mRecordIndex >= private mOrders.CountmOrders; + + private /*final*/ ArrayList mOrders; + private int mRecordIndex; + } + + //JAVA-added for string switch emulation + private static final StringSwitchMap gStringSwitchMap = new StringSwitchMap + ( + "FullName", + "Address", + "Order", + "Name", + "Quantity" + ); + +} diff --git a/Examples/DocsExamples/JavaPorting/Mail_Merge_And_Reporting/WorkingWithCleanupOptions.java b/Examples/DocsExamples/JavaPorting/Mail_Merge_And_Reporting/WorkingWithCleanupOptions.java new file mode 100644 index 00000000..d6b037ff --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Mail_Merge_And_Reporting/WorkingWithCleanupOptions.java @@ -0,0 +1,147 @@ +package DocsExamples.Mail_Merge_and_Reporting; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.net.System.Data.DataSet; +import com.aspose.words.MailMergeCleanupOptions; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.FieldMergeField; + + +class WorkingWithCleanupOptions extends DocsExamplesBase +{ + @Test + public void removeRowsFromTable() throws Exception + { + //ExStart:RemoveRowsFromTable + Document doc = new Document(getMyDir() + "Mail merge destination - Northwind suppliers.docx"); + + DataSet data = new DataSet(); + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_UNUSED_REGIONS | + MailMergeCleanupOptions.REMOVE_EMPTY_TABLE_ROWS); + + doc.getMailMerge().setMergeDuplicateRegions(true); + doc.getMailMerge().executeWithRegions(data); + + doc.save(getArtifactsDir() + "WorkingWithCleanupOptions.RemoveRowsFromTable.docx"); + //ExEnd:RemoveRowsFromTable + } + + @Test + public void cleanupParagraphsWithPunctuationMarks() throws Exception + { + //ExStart:CleanupParagraphsWithPunctuationMarks + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + FieldMergeField mergeFieldOption1 = (FieldMergeField) builder.insertField("MERGEFIELD", "Option_1"); + mergeFieldOption1.setFieldName("Option_1"); + + // Here is the complete list of cleanable punctuation marks: ! , . : ; ? ¡ ¿. + builder.write(" ? "); + + FieldMergeField mergeFieldOption2 = (FieldMergeField) builder.insertField("MERGEFIELD", "Option_2"); + mergeFieldOption2.setFieldName("Option_2"); + + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_EMPTY_PARAGRAPHS); + // The option's default value is true, which means that the behavior was changed to mimic MS Word. + // If you rely on the old behavior can revert it by setting the option to false. + doc.getMailMerge().setCleanupParagraphsWithPunctuationMarks(true); + + doc.getMailMerge().execute(new String[] { "Option_1", "Option_2" }, new Object[] { null, null }); + + doc.save(getArtifactsDir() + "WorkingWithCleanupOptions.CleanupParagraphsWithPunctuationMarks.docx"); + //ExEnd:CleanupParagraphsWithPunctuationMarks + } + + @Test + public void removeUnmergedRegions() throws Exception + { + //ExStart:RemoveUnmergedRegions + //GistId:f39874821cb317d245a769c9ce346fea + Document doc = new Document(getMyDir() + "Mail merge destination - Northwind suppliers.docx"); + + DataSet data = new DataSet(); + //ExStart:MailMergeCleanupOptions + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_UNUSED_REGIONS); + // doc.MailMerge.CleanupOptions = MailMergeCleanupOptions.RemoveContainingFields; + // doc.MailMerge.CleanupOptions |= MailMergeCleanupOptions.RemoveStaticFields; + // doc.MailMerge.CleanupOptions |= MailMergeCleanupOptions.RemoveEmptyParagraphs; + // doc.MailMerge.CleanupOptions |= MailMergeCleanupOptions.RemoveUnusedFields; + //ExEnd:MailMergeCleanupOptions + + // Merge the data with the document by executing mail merge which will have no effect as there is no data. + // However the regions found in the document will be removed automatically as they are unused. + doc.getMailMerge().executeWithRegions(data); + + doc.save(getArtifactsDir() + "WorkingWithCleanupOptions.RemoveUnmergedRegions.docx"); + //ExEnd:RemoveUnmergedRegions + } + + @Test + public void removeEmptyParagraphs() throws Exception + { + //ExStart:RemoveEmptyParagraphs + //GistId:f39874821cb317d245a769c9ce346fea + Document doc = new Document(getMyDir() + "Table with fields.docx"); + + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_EMPTY_PARAGRAPHS); + + doc.getMailMerge().execute(new String[] { "FullName", "Company", "Address", "Address2", "City" }, + new Object[] { "James Bond", "MI5 Headquarters", "Milbank", "", "London" }); + + doc.save(getArtifactsDir() + "WorkingWithCleanupOptions.RemoveEmptyParagraphs.docx"); + //ExEnd:RemoveEmptyParagraphs + } + + @Test + public void removeUnusedFields() throws Exception + { + //ExStart:RemoveUnusedFields + //GistId:f39874821cb317d245a769c9ce346fea + Document doc = new Document(getMyDir() + "Table with fields.docx"); + + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_UNUSED_FIELDS); + + doc.getMailMerge().execute(new String[] { "FullName", "Company", "Address", "Address2", "City" }, + new Object[] { "James Bond", "MI5 Headquarters", "Milbank", "", "London" }); + + doc.save(getArtifactsDir() + "WorkingWithCleanupOptions.RemoveUnusedFields.docx"); + //ExEnd:RemoveUnusedFields + } + + @Test + public void removeContainingFields() throws Exception + { + //ExStart:RemoveContainingFields + //GistId:f39874821cb317d245a769c9ce346fea + Document doc = new Document(getMyDir() + "Table with fields.docx"); + + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_CONTAINING_FIELDS); + + doc.getMailMerge().execute(new String[] { "FullName", "Company", "Address", "Address2", "City" }, + new Object[] { "James Bond", "MI5 Headquarters", "Milbank", "", "London" }); + + doc.save(getArtifactsDir() + "WorkingWithCleanupOptions.RemoveContainingFields.docx"); + //ExEnd:RemoveContainingFields + } + + @Test + public void removeEmptyTableRows() throws Exception + { + //ExStart:RemoveEmptyTableRows + //GistId:f39874821cb317d245a769c9ce346fea + Document doc = new Document(getMyDir() + "Table with fields.docx"); + + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_EMPTY_TABLE_ROWS); + + doc.getMailMerge().execute(new String[] { "FullName", "Company", "Address", "Address2", "City" }, + new Object[] { "James Bond", "MI5 Headquarters", "Milbank", "", "London" }); + + doc.save(getArtifactsDir() + "WorkingWithCleanupOptions.RemoveEmptyTableRows.docx"); + //ExEnd:RemoveEmptyTableRows + } +} diff --git a/Examples/DocsExamples/JavaPorting/Mail_Merge_And_Reporting/WorkingWithFields.java b/Examples/DocsExamples/JavaPorting/Mail_Merge_And_Reporting/WorkingWithFields.java new file mode 100644 index 00000000..d1c806cb --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Mail_Merge_And_Reporting/WorkingWithFields.java @@ -0,0 +1,446 @@ +package DocsExamples.Mail_Merge_and_Reporting; + +// ********* THIS FILE IS AUTO PORTED ********* + +import com.aspose.ms.java.collections.StringSwitchMap; +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.IFieldMergingCallback; +import com.aspose.words.FieldMergingArgs; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.TextFormFieldType; +import com.aspose.words.ImageFieldMergingArgs; +import com.aspose.words.MergeFieldImageDimension; +import com.aspose.words.MergeFieldImageDimensionUnit; +import com.aspose.words.MailMergeCleanupOptions; +import com.aspose.words.Shape; +import com.aspose.words.ShapeType; +import com.aspose.words.WrapType; +import com.aspose.words.IMailMergeDataSourceRoot; +import com.aspose.words.IMailMergeDataSource; +import com.aspose.words.FieldIf; +import com.aspose.words.net.System.Data.DataTable; +import com.aspose.words.net.System.Data.IDataReader; +import com.aspose.ms.System.IO.MemoryStream; +import com.aspose.words.FieldMergeField; +import java.awt.Color; +import com.aspose.words.net.System.Data.DataRow; +import com.aspose.words.FieldNextIf; +import com.aspose.words.FieldType; +import com.aspose.words.FieldSkipIf; +import com.aspose.words.ref.Ref; + + +class WorkingWithFields extends DocsExamplesBase +{ + @Test + public void mailMergeFormFields() throws Exception + { + //ExStart:MailMergeFormFields + //GistId:0a1baaa127443b485cc692c8d98ee353 + Document doc = new Document(getMyDir() + "Mail merge destinations - Fax.docx"); + + // Setup mail merge event handler to do the custom work. + doc.getMailMerge().setFieldMergingCallback(new HandleMergeField()); + // Trim trailing and leading whitespaces mail merge values. + doc.getMailMerge().setTrimWhitespaces(false); + + String[] fieldNames = { + "RecipientName", "SenderName", "FaxNumber", "PhoneNumber", + "Subject", "Body", "Urgent", "ForReview", "PleaseComment" + }; + + Object[] fieldValues = { + "Josh", "Jenny", "123456789", "", "Hello", + "HTML Body Test message 1", true, false, true + }; + + doc.getMailMerge().execute(fieldNames, fieldValues); + + doc.save(getArtifactsDir() + "WorkingWithFields.MailMergeFormFields.docx"); + //ExEnd:MailMergeFormFields + } + + //ExStart:HandleMergeField + //GistId:8a66b5cea0f9f8b862c092c9b93ccb3c + private static class HandleMergeField implements IFieldMergingCallback + { + /// + /// This handler is called for every mail merge field found in the document, + /// for every record found in the data source. + /// + public void /*IFieldMergingCallback.*/fieldMerging(FieldMergingArgs e) throws Exception + { + if (mBuilder == null) + mBuilder = new DocumentBuilder(e.getDocument()); + + // We decided that we want all boolean values to be output as check box form fields. + if (e.getFieldValue() instanceof /*boolean*/Boolean) + { + // Move the "cursor" to the current merge field. + mBuilder.moveToMergeField(e.getFieldName()); + + String checkBoxName = $"{e.FieldName}{e.RecordIndex}"; + + mBuilder.insertCheckBox(checkBoxName, (/*boolean*/Boolean) e.getFieldValue(), 0); + + return; + } + + switch (gStringSwitchMap.of(e.getFieldName())) + { + case /*"Body"*/0: + mBuilder.moveToMergeField(e.getFieldName()); + mBuilder.insertHtml((String) e.getFieldValue()); + break; + case /*"Subject"*/1: + { + mBuilder.moveToMergeField(e.getFieldName()); + String textInputName = $"{e.FieldName}{e.RecordIndex}"; + mBuilder.insertTextInput(textInputName, TextFormFieldType.REGULAR, "", (String) e.getFieldValue(), 0); + break; + } + } + } + + //ExStart:ImageFieldMerging + //GistId:0a1baaa127443b485cc692c8d98ee353 + public void /*IFieldMergingCallback.*/imageFieldMerging(ImageFieldMergingArgs args) + { + args.setImageFileName("Image.png"); + args.getImageWidth().setValue(200.0); + args.setImageHeight(new MergeFieldImageDimension(200.0, MergeFieldImageDimensionUnit.PERCENT)); + } + //ExEnd:ImageFieldMerging + + private DocumentBuilder mBuilder; + } + //ExEnd:HandleMergeField + + @Test + public void mailMergeImageField() throws Exception + { + //ExStart:MailMergeImageField + //GistId:8a66b5cea0f9f8b862c092c9b93ccb3c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("{{#foreach example}}"); + builder.writeln("{{Image(126pt;126pt):stempel}}"); + builder.writeln("{{/foreach example}}"); + + doc.getMailMerge().setUseNonMergeFields(true); + doc.getMailMerge().setTrimWhitespaces(true); + doc.getMailMerge().setUseWholeParagraphAsRegion(false); + doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_EMPTY_TABLE_ROWS + | MailMergeCleanupOptions.REMOVE_CONTAINING_FIELDS + | MailMergeCleanupOptions.REMOVE_UNUSED_REGIONS + | MailMergeCleanupOptions.REMOVE_UNUSED_FIELDS); + + doc.getMailMerge().setFieldMergingCallback(new ImageFieldMergingHandler()); + doc.getMailMerge().executeWithRegions(new DataSourceRoot()); + + doc.save(getArtifactsDir() + "WorkingWithFields.MailMergeImageField.docx"); + //ExEnd:MailMergeImageField + } + + //ExStart:ImageFieldMergingHandler + //GistId:8a66b5cea0f9f8b862c092c9b93ccb3c + private static class ImageFieldMergingHandler implements IFieldMergingCallback + { + public void /*IFieldMergingCallback.*/fieldMerging(FieldMergingArgs args) + { + // Implementation is not required. + } + + public void /*IFieldMergingCallback.*/imageFieldMerging(ImageFieldMergingArgs args) throws Exception + { + Shape shape = new Shape(args.getDocument(), ShapeType.IMAGE); + { + shape.setWidth(126.0); shape.setHeight(126.0); shape.setWrapType(WrapType.SQUARE); + } + + shape.getImageData().setImage(getMyDir() + "Mail merge image.png"); + + args.setShape(shape); + } + } + //ExEnd:ImageFieldMergingHandler + + //ExStart:DataSourceRoot + //GistId:8a66b5cea0f9f8b862c092c9b93ccb3c + public static class DataSourceRoot implements IMailMergeDataSourceRoot + { + public IMailMergeDataSource getDataSource(String s) + { + return new DataSource(); + } + + private static class DataSource implements IMailMergeDataSource + { + private boolean next = true; + + String IMailMergeDataSource.TableName => private TableNametableName(); + + private String tableName() + { + return "example"; + } + + public boolean moveNext() + { + boolean result = next; + next = false; + return result; + } + + public IMailMergeDataSource getChildDataSource(String s) + { + return null; + } + + public boolean getValue(String fieldName, /*out*/Ref fieldValue) + { + fieldValue.set(null); + return false; + } + } + } + //ExEnd:DataSourceRoot + + @Test + public void mailMergeAndConditionalField() throws Exception + { + //ExStart:MailMergeAndConditionalField + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a MERGEFIELD nested inside an IF field. + // Since the IF field statement is false, the result of the inner MERGEFIELD will not be displayed, + // and the MERGEFIELD will not receive any data during a mail merge. + FieldIf fieldIf = (FieldIf)builder.insertField(" IF 1 = 2 "); + builder.moveTo(fieldIf.getSeparator()); + builder.insertField(" MERGEFIELD FullName "); + + // We can still count MERGEFIELDs inside false-statement IF fields if we set this flag to true. + doc.getMailMerge().setUnconditionalMergeFieldsAndRegions(true); + + DataTable dataTable = new DataTable(); + dataTable.getColumns().add("FullName"); + dataTable.getRows().add("James Bond"); + + doc.getMailMerge().execute(dataTable); + + // The result will not be visible in the document because the IF field is false, + // but the inner MERGEFIELD did indeed receive data. + doc.save(getArtifactsDir() + "WorkingWithFields.MailMergeAndConditionalField.docx"); + //ExEnd:MailMergeAndConditionalField + } + + @Test (groups = "IgnoreOnJenkins") + public void mailMergeImageFromBlob() throws Exception + { + //ExStart:MailMergeImageFromBlob + //GistId:8a66b5cea0f9f8b862c092c9b93ccb3c + Document doc = new Document(getMyDir() + "Mail merge destination - Northwind employees.docx"); + + doc.getMailMerge().setFieldMergingCallback(new HandleMergeImageFieldFromBlob()); + + String connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + getDatabaseDir() + "Northwind.accdb"; + OleDbConnection conn = new OleDbConnection(connString); + conn.Open(); + + OleDbCommand cmd = new OleDbCommand("SELECT * FROM Employees", conn); + IDataReader dataReader = cmd.ExecuteReader(); + + doc.getMailMerge().executeWithRegions(dataReader, "Employees"); + + conn.Close(); + + doc.save(getArtifactsDir() + "WorkingWithFields.MailMergeImageFromBlob.docx"); + //ExEnd:MailMergeImageFromBlob + } + + //ExStart:HandleMergeImageFieldFromBlob + //GistId:8a66b5cea0f9f8b862c092c9b93ccb3c + public static class HandleMergeImageFieldFromBlob implements IFieldMergingCallback + { + public void /*IFieldMergingCallback.*/fieldMerging(FieldMergingArgs args) + { + // Do nothing. + } + + /// + /// This is called when mail merge engine encounters Image:XXX merge field in the document. + /// You have a chance to return an Image object, file name, or a stream that contains the image. + /// + public void /*IFieldMergingCallback.*/imageFieldMerging(ImageFieldMergingArgs e) throws Exception + { + // The field value is a byte array, just cast it and create a stream on it. + MemoryStream imageStream = new MemoryStream((byte[]) e.getFieldValue()); + // Now the mail merge engine will retrieve the image from the stream. + e.setImageStreamInternal(imageStream); + } + } + //ExEnd:HandleMergeImageFieldFromBlob + + @Test + public void handleMailMergeSwitches() throws Exception + { + Document doc = new Document(getMyDir() + "Field sample - MERGEFIELD.docx"); + + doc.getMailMerge().setFieldMergingCallback(new MailMergeSwitches()); + + final String HTML = "\n

          Hello world!

          \n "; + + doc.getMailMerge().execute(new String[] { "htmlField1" }, new Object[] { HTML }); + + doc.save(getArtifactsDir() + "WorkingWithFields.HandleMailMergeSwitches.docx"); + } + + //ExStart:HandleMailMergeSwitches + public static class MailMergeSwitches implements IFieldMergingCallback + { + public void /*IFieldMergingCallback.*/fieldMerging(FieldMergingArgs e) throws Exception + { + if (e.getFieldName().startsWith("HTML")) + { + if (e.getField().getFieldCode().contains("\\b")) + { + FieldMergeField field = e.getField(); + + DocumentBuilder builder = new DocumentBuilder(e.getDocument()); + builder.moveToMergeField(e.getDocumentFieldName(), true, false); + builder.write(field.getTextBefore()); + builder.insertHtml(e.getFieldValue().toString()); + + e.setText(""); + } + } + } + + public void /*IFieldMergingCallback.*/imageFieldMerging(ImageFieldMergingArgs args) + { + } + } + //ExEnd:HandleMailMergeSwitches + + @Test + public void alternatingRows() throws Exception + { + //ExStart:MailMergeAlternatingRows + Document doc = new Document(getMyDir() + "Mail merge destination - Northwind suppliers.docx"); + + doc.getMailMerge().setFieldMergingCallback(new HandleMergeFieldAlternatingRows()); + + DataTable dataTable = getSuppliersDataTable(); + doc.getMailMerge().executeWithRegions(dataTable); + + doc.save(getArtifactsDir() + "WorkingWithFields.AlternatingRows.doc"); + //ExEnd:MailMergeAlternatingRows + } + + //ExStart:HandleMergeFieldAlternatingRows + private static class HandleMergeFieldAlternatingRows implements IFieldMergingCallback + { + /// + /// Called for every merge field encountered in the document. + /// We can either return some data to the mail merge engine or do something else with the document. + /// In this case we modify cell formatting. + /// + public void /*IFieldMergingCallback.*/fieldMerging(FieldMergingArgs e) + { + if (mBuilder == null) + mBuilder = new DocumentBuilder(e.getDocument()); + + if ("CompanyName".equals(e.getFieldName())) + { + // Select the color depending on whether the row number is even or odd. + Color rowColor = isOdd(mRowIdx) + ? new Color((213), (227), (235)) + : new Color((242), (242), (242)); + + // There is no way to set cell properties for the whole row at the moment, so we have to iterate over all cells in the row. + for (int colIdx = 0; colIdx < 4; colIdx++) + { + mBuilder.moveToCell(0, mRowIdx, colIdx, 0); + mBuilder.getCellFormat().getShading().setBackgroundPatternColor(rowColor); + } + + mRowIdx++; + } + } + + public void /*IFieldMergingCallback.*/imageFieldMerging(ImageFieldMergingArgs args) + { + // Do nothing. + } + + private DocumentBuilder mBuilder; + private int mRowIdx; + } + + /// + /// Returns true if the value is odd; false if the value is even. + /// + private static boolean isOdd(int value) + { + return (value / 2 * 2) == value; + } + + /// + /// Create DataTable and fill it with data. + /// In real life this DataTable should be filled from a database. + /// + private DataTable getSuppliersDataTable() + { + DataTable dataTable = new DataTable("Suppliers"); + + dataTable.getColumns().add("CompanyName"); + dataTable.getColumns().add("ContactName"); + + for (int i = 0; i < 10; i++) + { + DataRow datarow = dataTable.newRow(); + + dataTable.getRows().add(datarow); + datarow.set(0, "Company " + i); + datarow.set(1, "Contact " + i); + } + + return dataTable; + } + //ExEnd:HandleMergeFieldAlternatingRows + + @Test + public void fieldNext() throws Exception + { + //ExStart:FieldNext + //GistId:b4bab1bf22437a86d8062e91cf154494 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Use NextIf field. A NEXTIF field has the same function as a NEXT field, + // but it skips to the next row only if a statement constructed by the following 3 properties is true. + FieldNextIf fieldNextIf = (FieldNextIf)builder.insertField(FieldType.FIELD_NEXT_IF, true); + + // Or use SkipIf field. + FieldSkipIf fieldSkipIf = (FieldSkipIf)builder.insertField(FieldType.FIELD_SKIP_IF, true); + + fieldNextIf.setLeftExpression("5"); + fieldNextIf.setRightExpression("2 + 3"); + fieldNextIf.setComparisonOperator("="); + + doc.save(getArtifactsDir() + "WorkingWithFields.FieldNext.docx"); + //ExEnd:FieldNext + } + + //JAVA-added for string switch emulation + private static final StringSwitchMap gStringSwitchMap = new StringSwitchMap + ( + "Body", + "Subject" + ); + +} diff --git a/Examples/DocsExamples/JavaPorting/Mail_Merge_And_Reporting/WorkingWithXMLData.java b/Examples/DocsExamples/JavaPorting/Mail_Merge_And_Reporting/WorkingWithXMLData.java new file mode 100644 index 00000000..9caba0af --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Mail_Merge_And_Reporting/WorkingWithXMLData.java @@ -0,0 +1,217 @@ +package DocsExamples.Mail_Merge_and_Reporting; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.net.System.Data.DataSet; +import com.aspose.words.Document; +import com.aspose.words.IMailMergeDataSource; +import java.lang.Class; +import java.lang.reflect.Field; +import java.util.Iterator; +import com.aspose.words.ref.Ref; + + +class WorkingWithXmlData extends DocsExamplesBase +{ + @Test + public void xmlMailMerge() throws Exception + { + //ExStart:XmlMailMerge + //GistId:0441f68c5209fec25c47d1a0a203fbb0 + DataSet customersDs = new DataSet(); + customersDs.readXml(getMyDir() + "Mail merge data - Customers.xml"); + + Document doc = new Document(getMyDir() + "Mail merge destinations - Registration complete.docx"); + doc.getMailMerge().execute(customersDs.getTables().get("Customer")); + + doc.save(getArtifactsDir() + "WorkingWithXmlData.XmlMailMerge.docx"); + //ExEnd:XmlMailMerge + } + + @Test + public void nestedMailMerge() throws Exception + { + //ExStart:NestedMailMerge + //GistId:c68048adceb3bda6a1511c7d6f5ebf7b + // The Datatable.TableNames and the DataSet.Relations are defined implicitly by .NET through ReadXml. + DataSet pizzaDs = new DataSet(); + pizzaDs.readXml(getMyDir() + "Mail merge data - Orders.xml"); + + Document doc = new Document(getMyDir() + "Mail merge destinations - Invoice.docx"); + + // Trim trailing and leading whitespaces mail merge values. + doc.getMailMerge().setTrimWhitespaces(false); + + doc.getMailMerge().executeWithRegions(pizzaDs); + + doc.save(getArtifactsDir() + "WorkingWithXmlData.NestedMailMerge.docx"); + //ExEnd:NestedMailMerge + } + + @Test + public void mustacheSyntaxUsingDataSet() throws Exception + { + //ExStart:MailMergeUsingMustacheSyntax + DataSet ds = new DataSet(); + ds.readXml(getMyDir() + "Mail merge data - Vendors.xml"); + + Document doc = new Document(getMyDir() + "Mail merge destinations - Vendor.docx"); + + doc.getMailMerge().setUseNonMergeFields(true); + + doc.getMailMerge().executeWithRegions(ds); + + doc.save(getArtifactsDir() + "WorkingWithXmlData.MustacheSyntaxUsingDataSet.docx"); + //ExEnd:MailMergeUsingMustacheSyntax + } + + @Test + public void linqToXmlMailMerge() throws Exception + { + XElement orderXml = XElement.Load(getMyDir() + "Mail merge data - Purchase order.xml"); + + // Query the purchase order XML file using LINQ to extract the order items into an object of an unknown type. + // + // Ensure you give the unknown type properties the same names as the MERGEFIELD fields in the document. + // + // To pass the actual values stored in the XML element or attribute to Aspose.Words, + // we need to cast them to string. This prevents the XML tags from being inserted into the final document + // when the XElement or XAttribute objects are passed to Aspose.Words. + + //ExStart:LinqToXmlMailMergeOrderItems + var orderItems = + from order : orderXml.Descendants("Item") + select new + {, + PartNumber = (String) order.Attribute("PartNumber"), + ProductName = (String) order.Element("ProductName"), + Quantity = (String) order.Element("Quantity"), + USPrice = (String) order.Element("USPrice"), + Comment = (String) order.Element("Comment") + ShipDate = (String) order.Element("ShipDate") + }; + //ExEnd:LinqToXmlMailMergeOrderItems + + //ExStart:LinqToXmlQueryForDeliveryAddress + var deliveryAddress = + from delivery : orderXml.Elements("Address") + where ((String) delivery.Attribute("Type") == "Shipping") + select new + {, + Name = (String) delivery.Element("Name"), + Country = (String) delivery.Element("Country"), + Zip = (String) delivery.Element("Zip"), + State = (String) delivery.Element("State"), + City = (String) delivery.Element("City") + Street = (String) delivery.Element("Street") + }; + //ExEnd:LinqToXmlQueryForDeliveryAddress + + MyMailMergeDataSource orderItemsDataSource = new MyMailMergeDataSource(orderItems, "Items"); + MyMailMergeDataSource deliveryDataSource = new MyMailMergeDataSource(deliveryAddress); + + //ExStart:LinqToXmlMailMerge + Document doc = new Document(getMyDir() + "Mail merge destinations - LINQ.docx"); + + // Fill the document with data from our data sources using mail merge regions for populating the order items + // table is required because it allows the region to be repeated in the document for each order item. + doc.getMailMerge().executeWithRegions(orderItemsDataSource); + + doc.getMailMerge().execute(deliveryDataSource); + + doc.save(getArtifactsDir() + "WorkingWithXmlData.LinqToXmlMailMerge.docx"); + //ExEnd:LinqToXmlMailMerge + } + + /// + /// Aspose.Words do not accept LINQ queries as input for mail merge directly + /// but provide a generic mechanism that allows mail merges from any data source. + /// + /// This class is a simple implementation of the Aspose.Words custom mail merge data source + /// interface that accepts a LINQ query (any IEnumerable object). + /// Aspose.Words call this class during the mail merge to retrieve the data. + /// + //ExStart:MyMailMergeDataSource + public static class MyMailMergeDataSource implements IMailMergeDataSource + //ExEnd:MyMailMergeDataSource + { + /// + /// Creates a new instance of a custom mail merge data source. + /// + /// Data returned from a LINQ query. + //ExStart:MyMailMergeDataSourceConstructor + public MyMailMergeDataSource(Iterable data) + { + mEnumerator = data.iterator(); + } + //ExEnd:MyMailMergeDataSourceConstructor + + /// + /// Creates a new instance of a custom mail merge data source, for mail merge with regions. + /// + /// Data returned from a LINQ query. + /// The name of the data source is only used when you perform a mail merge with regions. + /// If you prefer to use the simple mail merge, then use the constructor with one parameter. + //ExStart:MyMailMergeDataSourceConstructorWithDataTable + public MyMailMergeDataSource(Iterable data, String tableName) + { + mEnumerator = data.iterator(); + mTableName = tableName; + } + //ExEnd:MyMailMergeDataSourceConstructorWithDataTable + + /// + /// Aspose.Words call this method to get a value for every data field. + /// + /// This is a simple "generic" implementation of a data source that can work over any IEnumerable collection. + /// This implementation assumes that the merge field name in the document matches the public property's name + /// on the object in the collection and uses reflection to get the property's value. + /// + //ExStart:MyMailMergeDataSourceGetValue + public boolean getValue(String fieldName, /*out*/Ref fieldValue) + { + // Use reflection to get the property by name from the current object. + Object obj = mEnumerator.next(); + Class currentRecordType = obj.getClass(); + + Field property = currentRecordType.GetProperty(fieldName); + if (property != null) + { + fieldValue.set(property.GetValue(obj, null)); + return true; + } + fieldValue.set(null); + + return false; + } + //ExEnd:MyMailMergeDataSourceGetValue + + /// + /// Moves to the next record in the collection. + /// + //ExStart:MyMailMergeDataSourceMoveNext + public boolean moveNext() + { + return mEnumerator.hasNext(); + } + //ExEnd:MyMailMergeDataSourceMoveNext + + /// + /// The name of the data source. Used by Aspose.Words only when executing mail merge with repeatable regions. + /// + //ExStart:MyMailMergeDataSourceTableName + public String getTableName() { return mTableName; }; + + private String mTableName; + //ExEnd:MyMailMergeDataSourceTableName + + public IMailMergeDataSource getChildDataSource(String tableName) + { + return null; + } + + private /*final*/ Iterator mEnumerator; + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/ExtractContent.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/ExtractContent.java new file mode 100644 index 00000000..5183b2cf --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/ExtractContent.java @@ -0,0 +1,448 @@ +package DocsExamples.Programming_with_Documents.Contents_Management; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.Paragraph; +import com.aspose.words.NodeType; +import com.aspose.words.Table; +import java.util.ArrayList; +import com.aspose.words.Node; +import java.util.Collections; +import com.aspose.words.Bookmark; +import com.aspose.words.BookmarkStart; +import com.aspose.words.BookmarkEnd; +import com.aspose.words.CommentRangeStart; +import com.aspose.words.CommentRangeEnd; +import com.aspose.words.NodeCollection; +import com.aspose.ms.System.msString; +import com.aspose.words.Run; +import com.aspose.ms.System.msConsole; +import com.aspose.words.SaveFormat; +import com.aspose.words.DocumentVisitor; +import com.aspose.words.VisitorAction; +import com.aspose.words.FieldStart; +import com.aspose.words.FieldSeparator; +import com.aspose.words.FieldEnd; +import com.aspose.words.ControlChar; +import com.aspose.words.Body; +import com.aspose.ms.System.Text.msStringBuilder; +import com.aspose.words.HeaderFooter; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.Shape; + + +public class ExtractContent extends DocsExamplesBase +{ + @Test + public void extractContentBetweenBlockLevelNodes() throws Exception + { + //ExStart:ExtractContentBetweenBlockLevelNodes + //GistId:1f94e59ea4838ffac2f0edf921f67060 + Document doc = new Document(getMyDir() + "Extract content.docx"); + + Paragraph startPara = (Paragraph) doc.getLastSection().getChild(NodeType.PARAGRAPH, 2, true); + Table endTable = (Table) doc.getLastSection().getChild(NodeType.TABLE, 0, true); + // Extract the content between these nodes in the document. Include these markers in the extraction. + ArrayList extractedNodes = ExtractContentHelper.extractContent(startPara, endTable, true, false); + + // Let's reverse the array to make inserting the content back into the document easier. + Collections.reverse(extractedNodes); + for (Node extractedNode : extractedNodes) + endTable.getParentNode().insertAfter(extractedNode, endTable); + + doc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenBlockLevelNodes.docx"); + //ExEnd:ExtractContentBetweenBlockLevelNodes + } + + @Test + public void extractContentBetweenBookmark() throws Exception + { + //ExStart:ExtractContentBetweenBookmark + //GistId:1f94e59ea4838ffac2f0edf921f67060 + Document doc = new Document(getMyDir() + "Extract content.docx"); + + Bookmark bookmark = doc.getRange().getBookmarks().get("Bookmark1"); + BookmarkStart bookmarkStart = bookmark.getBookmarkStart(); + BookmarkEnd bookmarkEnd = bookmark.getBookmarkEnd(); + + // Firstly, extract the content between these nodes, including the bookmark. + ArrayList extractedNodesInclusive = ExtractContentHelper.extractContent(bookmarkStart, bookmarkEnd, true, true); + + Document dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodesInclusive); + dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenBookmark.IncludingBookmark.docx"); + + // Secondly, extract the content between these nodes this time without including the bookmark. + ArrayList extractedNodesExclusive = ExtractContentHelper.extractContent(bookmarkStart, bookmarkEnd, false, true); + + dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodesExclusive); + dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenBookmark.WithoutBookmark.docx"); + //ExEnd:ExtractContentBetweenBookmark + } + + @Test + public void extractContentBetweenCommentRange() throws Exception + { + //ExStart:ExtractContentBetweenCommentRange + //GistId:1f94e59ea4838ffac2f0edf921f67060 + Document doc = new Document(getMyDir() + "Extract content.docx"); + + CommentRangeStart commentStart = (CommentRangeStart) doc.getChild(NodeType.COMMENT_RANGE_START, 0, true); + CommentRangeEnd commentEnd = (CommentRangeEnd) doc.getChild(NodeType.COMMENT_RANGE_END, 0, true); + + // Firstly, extract the content between these nodes including the comment as well. + ArrayList extractedNodesInclusive = ExtractContentHelper.extractContent(commentStart, commentEnd, true, true); + + Document dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodesInclusive); + dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenCommentRange.IncludingComment.docx"); + + // Secondly, extract the content between these nodes without the comment. + ArrayList extractedNodesExclusive = ExtractContentHelper.extractContent(commentStart, commentEnd, false, true); + + dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodesExclusive); + dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenCommentRange.WithoutComment.docx"); + //ExEnd:ExtractContentBetweenCommentRange + } + + @Test + public void extractContentBetweenParagraphs() throws Exception + { + //ExStart:ExtractContentBetweenParagraphs + //GistId:1f94e59ea4838ffac2f0edf921f67060 + Document doc = new Document(getMyDir() + "Extract content.docx"); + + Paragraph startPara = (Paragraph) doc.getFirstSection().getBody().getChild(NodeType.PARAGRAPH, 6, true); + Paragraph endPara = (Paragraph) doc.getFirstSection().getBody().getChild(NodeType.PARAGRAPH, 10, true); + // Extract the content between these nodes in the document. Include these markers in the extraction. + ArrayList extractedNodes = ExtractContentHelper.extractContent(startPara, endPara, true, true); + + Document dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodes); + dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenParagraphs.docx"); + //ExEnd:ExtractContentBetweenParagraphs + } + + @Test + public void extractContentBetweenParagraphStyles() throws Exception + { + //ExStart:ExtractContentBetweenParagraphStyles + //GistId:1f94e59ea4838ffac2f0edf921f67060 + Document doc = new Document(getMyDir() + "Extract content.docx"); + + // Gather a list of the paragraphs using the respective heading styles. + ArrayList parasStyleHeading1 = paragraphsByStyleName(doc, "Heading 1"); + ArrayList parasStyleHeading3 = paragraphsByStyleName(doc, "Heading 3"); + + // Use the first instance of the paragraphs with those styles. + Node startPara = parasStyleHeading1.get(0); + Node endPara = parasStyleHeading3.get(0); + + // Extract the content between these nodes in the document. Don't include these markers in the extraction. + ArrayList extractedNodes = ExtractContentHelper.extractContent(startPara, endPara, false, true); + + Document dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodes); + dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenParagraphStyles.docx"); + //ExEnd:ExtractContentBetweenParagraphStyles + } + + //ExStart:ParagraphsByStyleName + //GistId:1f94e59ea4838ffac2f0edf921f67060 + public ArrayList paragraphsByStyleName(Document doc, String styleName) + { + // Create an array to collect paragraphs of the specified style. + ArrayList paragraphsWithStyle = new ArrayList(); + NodeCollection paragraphs = doc.getChildNodes(NodeType.PARAGRAPH, true); + + // Look through all paragraphs to find those with the specified style. + for (Paragraph paragraph : (Iterable) paragraphs) + { + if (msString.equals(paragraph.getParagraphFormat().getStyle().getName(), styleName)) + paragraphsWithStyle.add(paragraph); + } + + return paragraphsWithStyle; + } + //ExEnd:ParagraphsByStyleName + + @Test + public void extractContentBetweenRuns() throws Exception + { + //ExStart:ExtractContentBetweenRuns + //GistId:1f94e59ea4838ffac2f0edf921f67060 + Document doc = new Document(getMyDir() + "Extract content.docx"); + + Paragraph para = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 7, true); + Run startRun = para.getRuns().get(1); + Run endRun = para.getRuns().get(4); + + // Extract the content between these nodes in the document. Include these markers in the extraction. + ArrayList extractedNodes = ExtractContentHelper.extractContent(startRun, endRun, true, false); + for (Node extractedNode : extractedNodes) + System.out.println(extractedNode.toString(SaveFormat.TEXT)); + //ExEnd:ExtractContentBetweenRuns + } + + @Test + public void extractContentUsingDocumentVisitor() throws Exception + { + //ExStart:ExtractContentUsingDocumentVisitor + //GistId:1f94e59ea4838ffac2f0edf921f67060 + Document doc = new Document(getMyDir() + "Extract content.docx"); + + ConvertDocToTxt convertToPlainText = new ConvertDocToTxt(); + // Note that every node in the object model has the accept method so the visiting + // can be executed not only for the whole document, but for any node in the document. + doc.accept(convertToPlainText); + + // Once the visiting is complete, we can retrieve the result of the operation, + // That in this example, has accumulated in the visitor. + System.out.println(convertToPlainText.getText()); + //ExEnd:ExtractContentUsingDocumentVisitor + } + + //ExStart:ConvertDocToTxt + //GistId:1f94e59ea4838ffac2f0edf921f67060 + /// + /// Simple implementation of saving a document in the plain text format. Implemented as a Visitor. + /// + static class ConvertDocToTxt extends DocumentVisitor + { + public ConvertDocToTxt() + { + mIsSkipText = false; + mBuilder = new StringBuilder(); + } + + /// + /// Gets the plain text of the document that was accumulated by the visitor. + /// + public String getText() + { + return mBuilder.toString(); + } + + /// + /// Called when a Run node is encountered in the document. + /// + public /*override*/ /*VisitorAction*/int visitRun(Run run) + { + appendText(run.getText()); + // Let the visitor continue visiting other nodes. + return VisitorAction.CONTINUE; + } + + /// + /// Called when a FieldStart node is encountered in the document. + /// + public /*override*/ /*VisitorAction*/int visitFieldStart(FieldStart fieldStart) + { + // In Microsoft Word, a field code (such as "MERGEFIELD FieldName") follows + // after a field start character. We want to skip field codes and output field. + // Result only, therefore we use a flag to suspend the output while inside a field code. + // Note this is a very simplistic implementation and will not work very well. + // If you have nested fields in a document. + mIsSkipText = true; + return VisitorAction.CONTINUE; + } + + /// + /// Called when a FieldSeparator node is encountered in the document. + /// + public /*override*/ /*VisitorAction*/int visitFieldSeparator(FieldSeparator fieldSeparator) + { + // Once reached a field separator node, we enable the output because we are + // now entering the field result nodes. + mIsSkipText = false; + return VisitorAction.CONTINUE; + } + + /// + /// Called when a FieldEnd node is encountered in the document. + /// + public /*override*/ /*VisitorAction*/int visitFieldEnd(FieldEnd fieldEnd) + { + // Make sure we enable the output when reached a field end because some fields + // do not have field separator and do not have field result. + mIsSkipText = false; + return VisitorAction.CONTINUE; + } + + /// + /// Called when visiting of a Paragraph node is ended in the document. + /// + public /*override*/ /*VisitorAction*/int visitParagraphEnd(Paragraph paragraph) + { + // When outputting to plain text we output Cr+Lf characters. + appendText(ControlChar.CR_LF); + return VisitorAction.CONTINUE; + } + + public /*override*/ /*VisitorAction*/int visitBodyStart(Body body) + { + // We can detect beginning and end of all composite nodes such as Section, Body, + // Table, Paragraph etc and provide custom handling for them. + msStringBuilder.append(mBuilder, "*** Body Started ***\r\n"); + return VisitorAction.CONTINUE; + } + + public /*override*/ /*VisitorAction*/int visitBodyEnd(Body body) + { + msStringBuilder.append(mBuilder, "*** Body Ended ***\r\n"); + return VisitorAction.CONTINUE; + } + + /// + /// Called when a HeaderFooter node is encountered in the document. + /// + public /*override*/ /*VisitorAction*/int visitHeaderFooterStart(HeaderFooter headerFooter) + { + // Returning this value from a visitor method causes visiting of this + // Node to stop and move on to visiting the next sibling node + // The net effect in this example is that the text of headers and footers + // Is not included in the resulting output + return VisitorAction.SKIP_THIS_NODE; + } + + /// + /// Adds text to the current output. Honors the enabled/disabled output flag. + /// + private void appendText(String text) + { + if (!mIsSkipText) + msStringBuilder.append(mBuilder, text); + } + + private /*final*/ StringBuilder mBuilder; + private boolean mIsSkipText; + } + //ExEnd:ConvertDocToTxt + + @Test + public void extractContentUsingField() throws Exception + { + //ExStart:ExtractContentUsingField + //GistId:1f94e59ea4838ffac2f0edf921f67060 + Document doc = new Document(getMyDir() + "Extract content.docx"); + DocumentBuilder builder = new DocumentBuilder(doc); + // Pass the first boolean parameter to get the DocumentBuilder to move to the FieldStart of the field. + // We could also get FieldStarts of a field using GetChildNode method as in the other examples. + builder.moveToMergeField("Fullname", false, false); + + // The builder cursor should be positioned at the start of the field. + FieldStart startField = (FieldStart) builder.getCurrentNode(); + Paragraph endPara = (Paragraph) doc.getFirstSection().getChild(NodeType.PARAGRAPH, 5, true); + // Extract the content between these nodes in the document. Don't include these markers in the extraction. + ArrayList extractedNodes = ExtractContentHelper.extractContent(startField, endPara, false, true); + + Document dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodes); + dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentUsingField.docx"); + //ExEnd:ExtractContentUsingField + } + + @Test + public void simpleExtractText() throws Exception + { + //ExStart:SimpleExtractText + //GistId:1f94e59ea4838ffac2f0edf921f67060 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField("MERGEFIELD Field"); + + // When converted to text it will not retrieve fields code or special characters, + // but will still contain some natural formatting characters such as paragraph markers etc. + // This is the same as "viewing" the document as if it was opened in a text editor. + System.out.println("Convert to text result: " + doc.toString(SaveFormat.TEXT)); + //ExEnd:SimpleExtractText + } + + @Test + public void extractPrintText() throws Exception + { + //ExStart:ExtractText + //GistId:458eb4fd5bd1de8b06fab4d1ef1acdc6 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + // The range text will include control characters such as "\a" for a cell. + // You can call ToString and pass SaveFormat.Text on the desired node to find the plain text content. + System.out.println("Contents of the table: "); + System.out.println(table.getRange().getText()); + //ExEnd:ExtractText + + //ExStart:PrintTextRangeRowAndTable + //GistId:458eb4fd5bd1de8b06fab4d1ef1acdc6 + System.out.println("\nContents of the row: "); + System.out.println(table.getRows().get(1).getRange().getText()); + + System.out.println("\nContents of the cell: "); + System.out.println(table.getLastRow().getLastCell().getRange().getText()); + //ExEnd:PrintTextRangeRowAndTable + } + + @Test + public void extractImages() throws Exception + { + //ExStart:ExtractImages + //GistId:1f94e59ea4838ffac2f0edf921f67060 + Document doc = new Document(getMyDir() + "Images.docx"); + + NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true); + int imageIndex = 0; + + for (Shape shape : (Iterable) shapes) + { + if (shape.hasImage()) + { + String imageFileName = + $"Image.ExportImages.{imageIndex}_{FileFormatUtil.ImageTypeToExtension(shape.ImageData.ImageType)}"; + + // Note, if you have only an image (not a shape with a text and the image), + // you can use shape.GetShapeRenderer().Save(...) method to save the image. + shape.getImageData().save(getArtifactsDir() + imageFileName); + imageIndex++; + } + } + //ExEnd:ExtractImages + } + + @Test + public void extractContentBasedOnStyles() throws Exception + { + //ExStart:ExtractContentBasedOnStyles + //GistId:a73b495f610523670f0847331ef4d6fc + Document doc = new Document(getMyDir() + "Styles.docx"); + + ArrayList paragraphs = paragraphsByStyleName(doc, "Heading 1"); + System.out.println("Paragraphs with \"Heading 1\" styles ({paragraphs.Count}):"); + + for (Paragraph paragraph : paragraphs) + msConsole.write(paragraph.toString(SaveFormat.TEXT)); + + ArrayList runs = runsByStyleName(doc, "Intense Emphasis"); + System.out.println("\nRuns with \"Intense Emphasis\" styles ({runs.Count}):"); + + for (Run run : runs) + System.out.println(run.getRange().getText()); + //ExEnd:ExtractContentBasedOnStyles + } + + //ExStart:RunsByStyleName + //GistId:a73b495f610523670f0847331ef4d6fc + public ArrayList runsByStyleName(Document doc, String styleName) + { + ArrayList runsWithStyle = new ArrayList(); + NodeCollection runs = doc.getChildNodes(NodeType.RUN, true); + + for (Run run : (Iterable) runs) + { + if (msString.equals(run.getFont().getStyle().getName(), styleName)) + runsWithStyle.add(run); + } + + return runsWithStyle; + } + //ExEnd:RunsByStyleName +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/ExtractContentHelper.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/ExtractContentHelper.java new file mode 100644 index 00000000..9ee9b762 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/ExtractContentHelper.java @@ -0,0 +1,312 @@ +package DocsExamples.Programming_with_Documents.Contents_Management; + +// ********* THIS FILE IS AUTO PORTED ********* + +import java.util.ArrayList; +import com.aspose.words.Node; +import com.aspose.words.NodeType; +import com.aspose.words.Section; +import com.aspose.words.CompositeNode; +import com.aspose.ms.System.Diagnostics.Debug; +import com.aspose.words.Paragraph; +import com.aspose.words.Document; +import com.aspose.words.NodeImporter; +import com.aspose.words.ImportFormatMode; +import com.aspose.words.HeaderFooter; + + +class ExtractContentHelper +{ + public static ArrayList extractContent(Node startNode, Node endNode, boolean isInclusive, boolean copySection) + { + // First, check that the nodes passed to this method are valid for use. + verifyParameterNodes(startNode, endNode); + + // Create a list to store the extracted nodes. + ArrayList nodes = new ArrayList(); + + // If either marker is part of a comment, including the comment itself, we need to move the pointer + // forward to the Comment Node found after the CommentRangeEnd node. + if (endNode.getNodeType() == NodeType.COMMENT_RANGE_END && isInclusive) + { + Node node = findNextNode(NodeType.COMMENT, endNode.getNextSibling()); + if (node != null) + endNode = node; + } + + // Keep a record of the original nodes passed to this method to split marker nodes if needed. + Node originalStartNode = startNode; + Node originalEndNode = endNode; + + // Extract content based on block-level nodes (paragraphs and tables). Traverse through parent nodes to find them. + // We will split the first and last nodes' content, depending if the marker nodes are inline. + startNode = getAncestorInBody(startNode); + endNode = getAncestorInBody(endNode); + + boolean isExtracting = true; + boolean isStartingNode = true; + // The current node we are extracting from the document. + Node currNode = startNode; + + // Begin extracting content. Process all block-level nodes and specifically split the first + // and last nodes when needed, so paragraph formatting is retained. + // Method is a little more complicated than a regular extractor as we need to factor + // in extracting using inline nodes, fields, bookmarks, etc. to make it useful. + while (isExtracting) + { + if (copySection) + { + Node section = currNode.getAncestor(NodeType.SECTION); + if (!nodes.Any(o => o.Range.Text.Equals(section.Range.Text))) + nodes.add(section.deepClone(true)); + } + + // Clone the current node and its children to obtain a copy. + Node cloneNode = currNode.deepClone(true); + boolean isEndingNode = currNode.equals(endNode); + + if (isStartingNode || isEndingNode) + { + // We need to process each marker separately, so pass it off to a separate method instead. + // End should be processed at first to keep node indexes. + if (isEndingNode) + { + // !isStartingNode: don't add the node twice if the markers are the same node. + processMarker(cloneNode, nodes, originalEndNode, currNode, isInclusive, + false, !isStartingNode, false); + isExtracting = false; + } + + // Conditional needs to be separate as the block level start and end markers, maybe the same node. + if (isStartingNode) + { + processMarker(cloneNode, nodes, originalStartNode, currNode, isInclusive, + true, true, false); + isStartingNode = false; + } + } + else + // Node is not a start or end marker, simply add the copy to the list. + nodes.add(cloneNode); + + // Move to the next node and extract it. If the next node is null, + // the rest of the content is found in a different section. + if (currNode.getNextSibling() == null && isExtracting) + { + // Move to the next section. + Section nextSection = (Section) currNode.getAncestor(NodeType.SECTION).getNextSibling(); + currNode = nextSection.getBody().getFirstChild(); + } + else + // Move to the next node in the body. + currNode = currNode.getNextSibling(); + } + + // For compatibility with mode with inline bookmarks, add the next paragraph (empty). + if (isInclusive && originalEndNode == endNode && !originalEndNode.isComposite()) + includeNextParagraph(endNode, nodes); + + // Return the nodes between the node markers. + return nodes; + } + + private static void verifyParameterNodes(Node startNode, Node endNode) + { + // The order in which these checks are done is important. + if (startNode == null) + throw new IllegalArgumentException("Start node cannot be null"); + if (endNode == null) + throw new IllegalArgumentException("End node cannot be null"); + + if (!startNode.getDocument().equals(endNode.getDocument())) + throw new IllegalArgumentException("Start node and end node must belong to the same document"); + + if (startNode.getAncestor(NodeType.BODY) == null || endNode.getAncestor(NodeType.BODY) == null) + throw new IllegalArgumentException("Start node and end node must be a child or descendant of a body"); + + // Check the end node is after the start node in the DOM tree. + // First, check if they are in different sections, then if they're not, + // check their position in the body of the same section. + Section startSection = (Section) startNode.getAncestor(NodeType.SECTION); + Section endSection = (Section) endNode.getAncestor(NodeType.SECTION); + + int startIndex = startSection.getParentNode().indexOf(startSection); + int endIndex = endSection.getParentNode().indexOf(endSection); + + if (startIndex == endIndex) + { + if (startSection.getBody().indexOf(getAncestorInBody(startNode)) > + endSection.getBody().indexOf(getAncestorInBody(endNode))) + throw new IllegalArgumentException("The end node must be after the start node in the body"); + } + else if (startIndex > endIndex) + throw new IllegalArgumentException("The section of end node must be after the section start node"); + } + + private static Node findNextNode(/*NodeType*/int nodeType, Node fromNode) + { + if (fromNode == null || fromNode.getNodeType() == nodeType) + return fromNode; + + if (fromNode.isComposite()) + { + Node node = findNextNode(nodeType, ((CompositeNode) fromNode).getFirstChild()); + if (node != null) + return node; + } + + return findNextNode(nodeType, fromNode.getNextSibling()); + } + + private static void processMarker(Node cloneNode, ArrayList nodes, Node node, Node blockLevelAncestor, + boolean isInclusive, boolean isStartMarker, boolean canAdd, boolean forceAdd) + { + // If we are dealing with a block-level node, see if it should be included and add it to the list. + if (node == blockLevelAncestor) + { + if (canAdd && isInclusive) + nodes.add(cloneNode); + return; + } + + // cloneNode is a clone of blockLevelNode. If node != blockLevelNode, blockLevelAncestor + // is the node's ancestor that means it is a composite node. + com.aspose.ms.System.Diagnostics.Debug.assert(cloneNode.isComposite()); + + // If a marker is a FieldStart node check if it's to be included or not. + // We assume for simplicity that the FieldStart and FieldEnd appear in the same paragraph. + if (node.getNodeType() == NodeType.FIELD_START) + { + // If the marker is a start node and is not included, skip to the end of the field. + // If the marker is an end node and is to be included, then move to the end field so the field will not be removed. + if (isStartMarker && !isInclusive || !isStartMarker && isInclusive) + { + while (node.getNextSibling() != null && node.getNodeType() != NodeType.FIELD_END) + node = node.getNextSibling(); + } + } + + // Support a case if the marker node is on the third level of the document body or lower. + ArrayList nodeBranch = fillSelfAndParents(node, blockLevelAncestor); + + // Process the corresponding node in our cloned node by index. + Node currentCloneNode = cloneNode; + for (int i = nodeBranch.size() - 1; i >= 0; i--) + { + Node currentNode = nodeBranch.get(i); + int nodeIndex = currentNode.getParentNode().indexOf(currentNode); + currentCloneNode = ((CompositeNode) currentCloneNode).getChildNodes(NodeType.ANY, false).get(nodeIndex); + + removeNodesOutsideOfRange(currentCloneNode, isInclusive || (i > 0), isStartMarker); + } + + // After processing, the composite node may become empty if it has doesn't include it. + if (canAdd && + (forceAdd || ((CompositeNode) cloneNode).hasChildNodes())) + nodes.add(cloneNode); + } + + private static void removeNodesOutsideOfRange(Node markerNode, boolean isInclusive, boolean isStartMarker) + { + boolean isProcessing = true; + boolean isRemoving = isStartMarker; + Node nextNode = markerNode.getParentNode().getFirstChild(); + + while (isProcessing && nextNode != null) + { + Node currentNode = nextNode; + boolean isSkip = false; + + if (currentNode.equals(markerNode)) + { + if (isStartMarker) + { + isProcessing = false; + if (isInclusive) + isRemoving = false; + } + else + { + isRemoving = true; + if (isInclusive) + isSkip = true; + } + } + + nextNode = nextNode.getNextSibling(); + if (isRemoving && !isSkip) + currentNode.remove(); + } + } + + private static ArrayList fillSelfAndParents(Node node, Node tillNode) + { + ArrayList list = new ArrayList(); + Node currentNode = node; + + while (currentNode != tillNode) + { + list.add(currentNode); + currentNode = currentNode.getParentNode(); + } + + return list; + } + + private static void includeNextParagraph(Node node, ArrayList nodes) + { + Paragraph paragraph = (Paragraph) findNextNode(NodeType.PARAGRAPH, node.getNextSibling()); + if (paragraph != null) + { + // Move to the first child to include paragraphs without content. + Node markerNode = paragraph.hasChildNodes() ? paragraph.getFirstChild() : paragraph; + Node rootNode = getAncestorInBody(paragraph); + + processMarker(rootNode.deepClone(true), nodes, markerNode, rootNode, + markerNode == paragraph, false, true, true); + } + } + + private static Node getAncestorInBody(Node startNode) + { + while (startNode.getParentNode().getNodeType() != NodeType.BODY) + startNode = startNode.getParentNode(); + return startNode; + } + + + //ExStart:GenerateDocument + //GistId:1f94e59ea4838ffac2f0edf921f67060 + public static Document generateDocument(Document srcDoc, ArrayList nodes) throws Exception + { + Document dstDoc = new Document(); + // Remove default section in the destination document. + dstDoc.getFirstSection().remove(); + + // Import each node from the list into the new document. Keep the original formatting of the node. + NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + Section importedSection = null; + for (Node node : nodes) + { + if (node.getNodeType() == NodeType.SECTION) + { + // Import a section from the source document. + Section srcSection = (Section)node; + importedSection = (Section)importer.importNode(srcSection, false); + importedSection.appendChild(importer.importNode(srcSection.getBody(), false)); + for (HeaderFooter hf : (Iterable) srcSection.getHeadersFooters()) + importedSection.getHeadersFooters().add(importer.importNode(hf, true)); + + dstDoc.appendChild(importedSection); + } + else + { + Node importNode = importer.importNode(node, true); + importedSection.getBody().appendChild(importNode); + } + } + + return dstDoc; + } + //ExEnd:GenerateDocument +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/FindAndReplace.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/FindAndReplace.java new file mode 100644 index 00000000..12cca561 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/FindAndReplace.java @@ -0,0 +1,717 @@ +package DocsExamples.Programming_with_Documents.Contents_Management; + +// ********* THIS FILE IS AUTO PORTED ********* + +import com.aspose.ms.System.ms; +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.ms.System.msConsole; +import com.aspose.words.FindReplaceOptions; +import com.aspose.words.FindReplaceDirection; +import com.aspose.ms.System.Text.RegularExpressions.Regex; +import com.aspose.ms.System.Text.RegularExpressions.RegexOptions; +import com.aspose.words.IReplacingCallback; +import com.aspose.words.ReplaceAction; +import com.aspose.words.ReplacingArgs; +import com.aspose.words.Node; +import com.aspose.words.Run; +import java.util.ArrayList; +import com.aspose.words.NodeType; +import java.awt.Color; +import com.aspose.words.BreakType; +import com.aspose.words.ParagraphAlignment; +import com.aspose.ms.System.Drawing.msColor; +import java.util.Date; +import com.aspose.ms.System.DateTime; +import com.aspose.words.HeaderFooterCollection; +import com.aspose.words.HeaderFooter; +import com.aspose.words.HeaderFooterType; +import com.aspose.words.Section; +import com.aspose.ms.System.Text.msStringBuilder; +import com.aspose.words.FieldType; +import com.aspose.words.Shape; +import com.aspose.words.ShapeType; +import com.aspose.words.Table; +import com.aspose.ms.System.Diagnostics.Debug; +import java.text.MessageFormat; + + +class FindAndReplace extends DocsExamplesBase +{ + @Test + public void simpleFindReplace() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello _CustomerName_,"); + System.out.println("Original document text: " + doc.getRange().getText()); + + doc.getRange().replace("_CustomerName_", "James Bond", new FindReplaceOptions(FindReplaceDirection.FORWARD)); + + System.out.println("Document text after replace: " + doc.getRange().getText()); + + // Save the modified document + doc.save(getArtifactsDir() + "FindAndReplace.SimpleFindReplace.docx"); + } + + @Test + public void findAndHighlight() throws Exception + { + //ExStart:FindAndHighlight + Document doc = new Document(getMyDir() + "Find and highlight.docx"); + + FindReplaceOptions options = new FindReplaceOptions(); + { + options.setReplacingCallback(new ReplaceEvaluatorFindAndHighlight()); options.setDirection(FindReplaceDirection.BACKWARD); + } + + Regex regex = new Regex("your document", RegexOptions.IGNORE_CASE); + doc.getRange().replaceInternal(regex, "", options); + + doc.save(getArtifactsDir() + "FindAndReplace.FindAndHighlight.docx"); + //ExEnd:FindAndHighlight + } + + //ExStart:ReplaceEvaluatorFindAndHighlight + private static class ReplaceEvaluatorFindAndHighlight implements IReplacingCallback + { + /// + /// This method is called by the Aspose.Words find and replace engine for each match. + /// This method highlights the match string, even if it spans multiple runs. + /// + public /*ReplaceAction*/int /*IReplacingCallback.*/replacing(ReplacingArgs e) + { + // This is a Run node that contains either the beginning or the complete match. + Node currentNode = e.getMatchNode(); + + // The first (and may be the only) run can contain text before the match, + // in this case it is necessary to split the run. + if (e.getMatchOffset() > 0) + currentNode = splitRun((Run) currentNode, e.getMatchOffset()); + + // This array is used to store all nodes of the match for further highlighting. + ArrayList runs = new ArrayList(); + + // Find all runs that contain parts of the match string. + int remainingLength = e.getMatchInternal().getValue().length(); + while ( + remainingLength > 0 && + currentNode != null && + currentNode.getText().length() <= remainingLength) + { + runs.add((Run) currentNode); + remainingLength -= currentNode.getText().length(); + + // Select the next Run node. + // Have to loop because there could be other nodes such as BookmarkStart etc. + do + { + currentNode = currentNode.getNextSibling(); + } while (currentNode != null && currentNode.getNodeType() != NodeType.RUN); + } + + // Split the last run that contains the match if there is any text left. + if (currentNode != null && remainingLength > 0) + { + splitRun((Run) currentNode, remainingLength); + runs.add((Run) currentNode); + } + + // Now highlight all runs in the sequence. + for (Run run : runs) + run.getFont().setHighlightColor(Color.YELLOW); + + // Signal to the replace engine to do nothing because we have already done all what we wanted. + return ReplaceAction.SKIP; + } + } + //ExEnd:ReplaceEvaluatorFindAndHighlight + + //ExStart:SplitRun + /// + /// Splits text of the specified run into two runs. + /// Inserts the new run just after the specified run. + /// + private static Run splitRun(Run run, int position) + { + Run afterRun = (Run) run.deepClone(true); + afterRun.setText(run.getText().substring(position)); + + run.setText(run.getText().substring((0), (0) + (position))); + run.getParentNode().insertAfter(afterRun, run); + + return afterRun; + } + //ExEnd:SplitRun + + @Test + public void metaCharactersInSearchPattern() throws Exception + { + /* meta-characters + &p - paragraph break + &b - section break + &m - page break + &l - manual line break + */ + + //ExStart:MetaCharactersInSearchPattern + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("This is Line 1"); + builder.writeln("This is Line 2"); + + doc.getRange().replace("This is Line 1&pThis is Line 2", "This is replaced line"); + + builder.moveToDocumentEnd(); + builder.write("This is Line 1"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("This is Line 2"); + + doc.getRange().replace("This is Line 1&mThis is Line 2", "Page break is replaced with new text."); + + doc.save(getArtifactsDir() + "FindAndReplace.MetaCharactersInSearchPattern.docx"); + //ExEnd:MetaCharactersInSearchPattern + } + + @Test + public void replaceTextContainingMetaCharacters() throws Exception + { + //ExStart:ReplaceTextContainingMetaCharacters + //GistId:27c3408b2c7fbee8d6dc6a1c8b61c105 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Arial"); + builder.writeln("First section"); + builder.writeln(" 1st paragraph"); + builder.writeln(" 2nd paragraph"); + builder.writeln("{insert-section}"); + builder.writeln("Second section"); + builder.writeln(" 1st paragraph"); + + FindReplaceOptions findReplaceOptions = new FindReplaceOptions(); + findReplaceOptions.getApplyParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + + // Double each paragraph break after word "section", add kind of underline and make it centered. + int count = doc.getRange().replace("section&p", "section&p----------------------&p", findReplaceOptions); + + // Insert section break instead of custom text tag. + count = doc.getRange().replace("{insert-section}", "&b", findReplaceOptions); + + doc.save(getArtifactsDir() + "FindAndReplace.ReplaceTextContainingMetaCharacters.docx"); + //ExEnd:ReplaceTextContainingMetaCharacters + } + + @Test + public void highlightColor() throws Exception + { + //ExStart:HighlightColor + //GistId:27c3408b2c7fbee8d6dc6a1c8b61c105 + Document doc = new Document(getMyDir() + "Footer.docx"); + + FindReplaceOptions options = new FindReplaceOptions(); + options.getApplyFont().setHighlightColor(msColor.getDarkOrange()); + doc.getRange().replaceInternal(new Regex("(header|footer)"), "", options); + //ExEnd:HighlightColor + } + + @Test + public void ignoreTextInsideFields() throws Exception + { + //ExStart:IgnoreTextInsideFields + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert field with text inside. + builder.insertField("INCLUDETEXT", "Text in field"); + + FindReplaceOptions options = new FindReplaceOptions(); { options.setIgnoreFields(true); } + + Regex regex = new Regex("e"); + doc.getRange().replaceInternal(regex, "*", options); + + System.out.println(doc.getText()); + + options.setIgnoreFields(false); + doc.getRange().replaceInternal(regex, "*", options); + + System.out.println(doc.getText()); + //ExEnd:IgnoreTextInsideFields + } + + @Test + public void ignoreTextInsideDeleteRevisions() throws Exception + { + //ExStart:IgnoreTextInsideDeleteRevisions + //GistId:27c3408b2c7fbee8d6dc6a1c8b61c105 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert non-revised text. + builder.writeln("Deleted"); + builder.write("Text"); + + // Remove first paragraph with tracking revisions. + doc.startTrackRevisionsInternal("author", new Date); + doc.getFirstSection().getBody().getFirstParagraph().remove(); + doc.stopTrackRevisions(); + + FindReplaceOptions options = new FindReplaceOptions(); { options.setIgnoreDeleted(true); } + + Regex regex = new Regex("e"); + doc.getRange().replaceInternal(regex, "*", options); + + System.out.println(doc.getText()); + + options.setIgnoreDeleted(false); + doc.getRange().replaceInternal(regex, "*", options); + + System.out.println(doc.getText()); + //ExEnd:IgnoreTextInsideDeleteRevisions + } + + @Test + public void ignoreTextInsideInsertRevisions() throws Exception + { + //ExStart:IgnoreTextInsideInsertRevisions + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert text with tracking revisions. + doc.startTrackRevisionsInternal("author", new Date); + builder.writeln("Inserted"); + doc.stopTrackRevisions(); + + // Insert non-revised text. + builder.write("Text"); + + FindReplaceOptions options = new FindReplaceOptions(); { options.setIgnoreInserted(true); } + + Regex regex = new Regex("e"); + doc.getRange().replaceInternal(regex, "*", options); + + System.out.println(doc.getText()); + + options.setIgnoreInserted(false); + doc.getRange().replaceInternal(regex, "*", options); + + System.out.println(doc.getText()); + //ExEnd:IgnoreTextInsideInsertRevisions + } + + @Test + public void replaceHtmlTextWithMetaCharacters() throws Exception + { + //ExStart:ReplaceHtmlTextWithMetaCharacters + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("{PLACEHOLDER}"); + + FindReplaceOptions findReplaceOptions = new FindReplaceOptions(); { findReplaceOptions.setReplacingCallback(new FindAndInsertHtml()); } + + doc.getRange().replace("{PLACEHOLDER}", "

          “Some Text”

          ", findReplaceOptions); + + doc.save(getArtifactsDir() + "FindAndReplace.ReplaceHtmlTextWithMetaCharacters.docx"); + //ExEnd:ReplaceHtmlTextWithMetaCharacters + } + + //ExStart:ReplaceHtmlFindAndInsertHtml + public final static class FindAndInsertHtml implements IReplacingCallback + { + public /*ReplaceAction*/int /*IReplacingCallback.*/replacing(ReplacingArgs e) throws Exception + { + Node currentNode = e.getMatchNode(); + + DocumentBuilder builder = new DocumentBuilder(ms.as(e.getMatchNode().getDocument(), Document.class)); + builder.moveTo(currentNode); + builder.insertHtml(e.getReplacement()); + + currentNode.remove(); + + return ReplaceAction.SKIP; + } + } + //ExEnd:ReplaceHtmlFindAndInsertHtml + + @Test + public void replaceTextInFooter() throws Exception + { + //ExStart:ReplaceTextInFooter + //GistId:27c3408b2c7fbee8d6dc6a1c8b61c105 + Document doc = new Document(getMyDir() + "Footer.docx"); + + HeaderFooterCollection headersFooters = doc.getFirstSection().getHeadersFooters(); + HeaderFooter footer = headersFooters.getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY); + + FindReplaceOptions options = new FindReplaceOptions(); { options.setMatchCase(false); options.setFindWholeWordsOnly(false); } + footer.getRange().replace("(C) 2006 Aspose Pty Ltd.", "Copyright (C) 2020 by Aspose Pty Ltd.", options); + + doc.save(getArtifactsDir() + "FindAndReplace.ReplaceTextInFooter.docx"); + //ExEnd:ReplaceTextInFooter + } + + @Test + //ExStart:ShowChangesForHeaderAndFooterOrders + public void showChangesForHeaderAndFooterOrders() throws Exception + { + ReplaceLog logger = new ReplaceLog(); + + Document doc = new Document(getMyDir() + "Footer.docx"); + Section firstPageSection = doc.getFirstSection(); + + FindReplaceOptions options = new FindReplaceOptions(); { options.setReplacingCallback(logger); } + + doc.getRange().replaceInternal(new Regex("(header|footer)"), "", options); + + doc.save(getArtifactsDir() + "FindAndReplace.ShowChangesForHeaderAndFooterOrders.docx"); + + logger.clearText(); + + firstPageSection.getPageSetup().setDifferentFirstPageHeaderFooter(false); + + doc.getRange().replaceInternal(new Regex("(header|footer)"), "", options); + } + + private static class ReplaceLog implements IReplacingCallback + { + public /*ReplaceAction*/int replacing(ReplacingArgs args) + { + msStringBuilder.appendLine(mTextBuilder, args.getMatchNode().getText()); + return ReplaceAction.SKIP; + } + + void clearText() + { + mTextBuilder.Clear(); + } + + private /*final*/ StringBuilder mTextBuilder = new StringBuilder(); + } + //ExEnd:ShowChangesForHeaderAndFooterOrders + + @Test + public void replaceTextWithField() throws Exception + { + Document doc = new Document(getMyDir() + "Replace text with fields.docx"); + + FindReplaceOptions options = new FindReplaceOptions(); + { + options.setReplacingCallback(new ReplaceTextWithFieldHandler(FieldType.FIELD_MERGE_FIELD)); + } + + doc.getRange().replaceInternal(new Regex("PlaceHolder(\\d+)"), "", options); + + doc.save(getArtifactsDir() + "FindAndReplace.ReplaceTextWithField.docx"); + } + + + public static class ReplaceTextWithFieldHandler implements IReplacingCallback + { + public ReplaceTextWithFieldHandler(/*FieldType*/int type) + { + mFieldType = type; + } + + public /*ReplaceAction*/int replacing(ReplacingArgs args) throws Exception + { + ArrayList runs = findAndSplitMatchRuns(args); + + DocumentBuilder builder = new DocumentBuilder((Document) args.getMatchNode().getDocument()); + builder.moveTo(runs.get(runs.size() - 1)); + + // Calculate the field's name from the FieldType enumeration by removing + // the first instance of "Field" from the text. This works for almost all of the field types. + String fieldName = FieldType.toString(mFieldType).toUpperCase().substring(5); + + // Insert the field into the document using the specified field type and the matched text as the field name. + // If the fields you are inserting do not require this extra parameter, it can be removed from the string below. + builder.insertField($"{fieldName} {args.Match.Groups[0]}"); + + for (Run run : runs) + run.remove(); + + return ReplaceAction.SKIP; + } + + /// + /// Finds and splits the match runs and returns them in an List. + /// + public ArrayList findAndSplitMatchRuns(ReplacingArgs args) + { + // This is a Run node that contains either the beginning or the complete match. + Node currentNode = args.getMatchNode(); + + // The first (and may be the only) run can contain text before the match, + // In this case it is necessary to split the run. + if (args.getMatchOffset() > 0) + currentNode = splitRun((Run) currentNode, args.getMatchOffset()); + + // This array is used to store all nodes of the match for further removing. + ArrayList runs = new ArrayList(); + + // Find all runs that contain parts of the match string. + int remainingLength = args.getMatchInternal().getValue().length(); + while ( + remainingLength > 0 && + currentNode != null && + currentNode.getText().length() <= remainingLength) + { + runs.add((Run) currentNode); + remainingLength -= currentNode.getText().length(); + + do + { + currentNode = currentNode.getNextSibling(); + } while (currentNode != null && currentNode.getNodeType() != NodeType.RUN); + } + + // Split the last run that contains the match if there is any text left. + if (currentNode != null && remainingLength > 0) + { + splitRun((Run) currentNode, remainingLength); + runs.add((Run) currentNode); + } + + return runs; + } + + /// + /// Splits text of the specified run into two runs. + /// Inserts the new run just after the specified run. + /// + private Run splitRun(Run run, int position) + { + Run afterRun = (Run) run.deepClone(true); + + afterRun.setText(run.getText().substring(position)); + run.setText(run.getText().substring((0), (0) + (position))); + + run.getParentNode().insertAfter(afterRun, run); + + return afterRun; + } + + private /*final*/ /*FieldType*/int mFieldType; + } + + @Test + public void replaceWithEvaluator() throws Exception + { + //ExStart:ReplaceWithEvaluator + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("sad mad bad"); + + FindReplaceOptions options = new FindReplaceOptions(); { options.setReplacingCallback(new MyReplaceEvaluator()); } + + doc.getRange().replaceInternal(new Regex("[s|m]ad"), "", options); + + doc.save(getArtifactsDir() + "FindAndReplace.ReplaceWithEvaluator.docx"); + //ExEnd:ReplaceWithEvaluator + } + + //ExStart:MyReplaceEvaluator + private static class MyReplaceEvaluator implements IReplacingCallback + { + /// + /// This is called during a replace operation each time a match is found. + /// This method appends a number to the match string and returns it as a replacement string. + /// + public /*ReplaceAction*/int /*IReplacingCallback.*/replacing(ReplacingArgs e) + { + e.setReplacement(e.getMatchInternal() + Integer.toString(mMatchNumber)); + mMatchNumber++; + + return ReplaceAction.REPLACE; + } + + private int mMatchNumber; + } + //ExEnd:MyReplaceEvaluator + + @Test + //ExStart:ReplaceWithHtml + //GistId:27c3408b2c7fbee8d6dc6a1c8b61c105 + public void replaceWithHtml() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello ,"); + + FindReplaceOptions options = new FindReplaceOptions(); + options.setReplacingCallback(new ReplaceWithHtmlEvaluator(options)); + + doc.getRange().replaceInternal(new Regex(" ,"), "", options); + + doc.save(getArtifactsDir() + "FindAndReplace.ReplaceWithHtml.docx"); + } + + private static class ReplaceWithHtmlEvaluator implements IReplacingCallback + { + ReplaceWithHtmlEvaluator(FindReplaceOptions options) + { + mOptions = options; + } + + /// + /// NOTE: This is a simplistic method that will only work well when the match + /// starts at the beginning of a run. + /// + public /*ReplaceAction*/int /*IReplacingCallback.*/replacing(ReplacingArgs args) throws Exception + { + DocumentBuilder builder = new DocumentBuilder((Document) args.getMatchNode().getDocument()); + builder.moveTo(args.getMatchNode()); + + // Replace '' text with a red bold name. + builder.insertHtml("James Bond, "); + args.setReplacement(""); + + return ReplaceAction.REPLACE; + } + + private /*final*/ FindReplaceOptions mOptions; + } + //ExEnd:ReplaceWithHtml + + @Test + public void replaceWithRegex() throws Exception + { + //ExStart:ReplaceWithRegex + //GistId:27c3408b2c7fbee8d6dc6a1c8b61c105 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("sad mad bad"); + + FindReplaceOptions options = new FindReplaceOptions(); + + doc.getRange().replaceInternal(new Regex("[s|m]ad"), "bad", options); + + doc.save(getArtifactsDir() + "FindAndReplace.ReplaceWithRegex.docx"); + //ExEnd:ReplaceWithRegex + } + + @Test + public void recognizeAndSubstitutionsWithinReplacementPatterns() throws Exception + { + //ExStart:RecognizeAndSubstitutionsWithinReplacementPatterns + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Jason give money to Paul."); + + Regex regex = new Regex("([A-z]+) give money to ([A-z]+)"); + + FindReplaceOptions options = new FindReplaceOptions(); { options.setUseSubstitutions(true); } + + doc.getRange().replaceInternal(regex, "$2 take money from $1", options); + //ExEnd:RecognizeAndSubstitutionsWithinReplacementPatterns + } + + @Test + public void replaceWithString() throws Exception + { + //ExStart:ReplaceWithString + //GistId:27c3408b2c7fbee8d6dc6a1c8b61c105 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello _CustomerName_,"); + + doc.getRange().replace("_CustomerName_", "James Bond", new FindReplaceOptions(FindReplaceDirection.FORWARD)); + + doc.save(getArtifactsDir() + "FindAndReplace.ReplaceWithString.docx"); + //ExEnd:ReplaceWithString + } + + @Test + //ExStart:UsingLegacyOrder + public void usingLegacyOrder() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("[tag 1]"); + Shape textBox = builder.insertShape(ShapeType.TEXT_BOX, 100.0, 50.0); + builder.writeln("[tag 3]"); + + builder.moveTo(textBox.getFirstParagraph()); + builder.write("[tag 2]"); + + FindReplaceOptions options = new FindReplaceOptions(); + { + options.setReplacingCallback(new ReplacingCallback()); options.setUseLegacyOrder(true); + } + + doc.getRange().replaceInternal(new Regex("\\[(.*?)\\]"), "", options); + + doc.save(getArtifactsDir() + "FindAndReplace.UsingLegacyOrder.docx"); + } + + private static class ReplacingCallback implements IReplacingCallback + { + public /*ReplaceAction*/int /*IReplacingCallback.*/replacing(ReplacingArgs e) + { + msConsole.write(e.getMatchInternal().getValue()); + return ReplaceAction.REPLACE; + } + } + //ExEnd:UsingLegacyOrder + + @Test + public void replaceTextInTable() throws Exception + { + //ExStart:ReplaceText + //GistId:458eb4fd5bd1de8b06fab4d1ef1acdc6 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table)doc.getChild(NodeType.TABLE, 0, true); + + table.getRange().replace("Carrots", "Eggs", new FindReplaceOptions(FindReplaceDirection.FORWARD)); + table.getLastRow().getLastCell().getRange().replace("50", "20", new FindReplaceOptions(FindReplaceDirection.FORWARD)); + + doc.save(getArtifactsDir() + "FindAndReplace.ReplaceTextInTable.docx"); + //ExEnd:ReplaceText + } + + //ExStart:LineCounter + //GistId:27c3408b2c7fbee8d6dc6a1c8b61c105 + @Test //ExSkip + public void lineCounter() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("This is first line"); + builder.writeln("Second line"); + builder.writeln("And last line"); + + // Prepend each line with line number. + FindReplaceOptions opt = new FindReplaceOptions(); { opt.setReplacingCallback(new LineCounterCallback()); } + doc.getRange().replaceInternal(new Regex("[^&p]*&p"), "", opt); + + doc.save(getArtifactsDir() + "FindAndReplace.LineCounter.docx"); + } + + static class LineCounterCallback implements IReplacingCallback + { + public /*ReplaceAction*/int replacing(ReplacingArgs args) + { + Debug.writeLine(args.getMatchInternal().getValue()); + + args.setReplacement(MessageFormat.format("{0} {1}", mCounter++, args.getMatchInternal().getValue())); + return ReplaceAction.REPLACE; + } + + private int mCounter = 1; + } + //ExEnd:LineCounter +} + diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/RemoveContent.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/RemoveContent.java new file mode 100644 index 00000000..e7f9fb9f --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/RemoveContent.java @@ -0,0 +1,165 @@ +package DocsExamples.Programming_with_Documents.Contents_Management; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.NodeCollection; +import com.aspose.words.NodeType; +import com.aspose.words.Paragraph; +import com.aspose.words.Run; +import com.aspose.words.ControlChar; +import com.aspose.words.Section; +import com.aspose.words.HeaderFooter; +import com.aspose.words.HeaderFooterType; +import java.util.ArrayList; +import com.aspose.words.FieldStart; +import com.aspose.words.Node; +import com.aspose.words.FieldType; +import com.aspose.words.FieldEnd; + + +class RemoveContent extends DocsExamplesBase +{ + @Test + public void removePageBreaks() throws Exception + { + //ExStart:OpenDocument + //GistId:1d626c7186a318d22d022dc96dd91d55 + Document doc = new Document(getMyDir() + "Document.docx"); + //ExEnd:OpenDocument + + // In Aspose.Words section breaks are represented as separate Section nodes in the document. + // To remove these separate sections, the sections are combined. + removePageBreaks(doc); + removeSectionBreaks(doc); + + doc.save(getArtifactsDir() + "RemoveContent.RemovePageBreaks.docx"); + } + + //ExStart:RemovePageBreaks + private void removePageBreaks(Document doc) + { + NodeCollection paragraphs = doc.getChildNodes(NodeType.PARAGRAPH, true); + + for (Paragraph para : (Iterable) paragraphs) + { + // If the paragraph has a page break before the set, then clear it. + if (para.getParagraphFormat().getPageBreakBefore()) + para.getParagraphFormat().setPageBreakBefore(false); + + // Check all runs in the paragraph for page breaks and remove them. + for (Run run : (Iterable) para.getRuns()) + { + if (run.getText().contains(ControlChar.PAGE_BREAK)) + run.setText(run.getText().replace(ControlChar.PAGE_BREAK, "")); + } + } + } + //ExEnd:RemovePageBreaks + + //ExStart:RemoveSectionBreaks + //GistId:1afca4d3da7cb4240fb91c3d93d8c30d + private void removeSectionBreaks(Document doc) + { + // Loop through all sections starting from the section that precedes the last one and moving to the first section. + for (int i = doc.getSections().getCount() - 2; i >= 0; i--) + { + // Copy the content of the current section to the beginning of the last section. + doc.getLastSection().prependContent(doc.getSections().get(i)); + // Remove the copied section. + doc.getSections().get(i).remove(); + } + } + //ExEnd:RemoveSectionBreaks + + @Test + public void removeFooters() throws Exception + { + //ExStart:RemoveFooters + //GistId:84cab3a22008f041ee6c1e959da09949 + Document doc = new Document(getMyDir() + "Header and footer types.docx"); + + for (Section section : (Iterable
          ) doc) + { + // Up to three different footers are possible in a section (for first, even and odd pages) + // we check and delete all of them. + HeaderFooter footer = section.getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_FIRST); + footer?.Remove(); + + // Primary footer is the footer used for odd pages. + footer = section.getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY); + footer?.Remove(); + + footer = section.getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_EVEN); + footer?.Remove(); + } + + doc.save(getArtifactsDir() + "RemoveContent.RemoveFooters.docx"); + //ExEnd:RemoveFooters + } + + @Test + //ExStart:RemoveToc + //GistId:db118a3e1559b9c88355356df9d7ea10 + public void removeToc() throws Exception + { + Document doc = new Document(getMyDir() + "Table of contents.docx"); + + // Remove the first table of contents from the document. + removeTableOfContents(doc, 0); + + doc.save(getArtifactsDir() + "RemoveContent.RemoveToc.doc"); + } + + /// + /// Removes the specified table of contents field from the document. + /// + /// The document to remove the field from. + /// The zero-based index of the TOC to remove. + public void removeTableOfContents(Document doc, int index) + { + // Store the FieldStart nodes of TOC fields in the document for quick access. + ArrayList fieldStarts = new ArrayList(); + // This is a list to store the nodes found inside the specified TOC. They will be removed at the end of this method. + ArrayList nodeList = new ArrayList(); + + for (FieldStart start : (Iterable) doc.getChildNodes(NodeType.FIELD_START, true)) + { + if (start.getFieldType() == FieldType.FIELD_TOC) + { + fieldStarts.add(start); + } + } + + // Ensure the TOC specified by the passed index exists. + if (index > fieldStarts.size() - 1) + throw new IllegalArgumentException("Specified argument was out of the range of valid values.\r\nParameter name: " + "TOC index is out of range"); + + boolean isRemoving = true; + + Node currentNode = fieldStarts.get(index); + while (isRemoving) + { + // It is safer to store these nodes and delete them all at once later. + nodeList.add(currentNode); + currentNode = currentNode.nextPreOrder(doc); + + // Once we encounter a FieldEnd node of type FieldTOC, + // we know we are at the end of the current TOC and stop here. + if (currentNode.getNodeType() == NodeType.FIELD_END) + { + FieldEnd fieldEnd = (FieldEnd) currentNode; + if (fieldEnd.getFieldType() == FieldType.FIELD_TOC) + isRemoving = false; + } + } + + for (Node node : nodeList) + { + node.remove(); + } + } + //ExEnd:RemoveToc +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/WorkingWithBookmarks.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/WorkingWithBookmarks.java new file mode 100644 index 00000000..4b3c7b8f --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/WorkingWithBookmarks.java @@ -0,0 +1,262 @@ +package DocsExamples.Programming_with_Documents.Contents_Management; + +// ********* THIS FILE IS AUTO PORTED ********* + +import com.aspose.ms.System.ms; +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.Bookmark; +import com.aspose.words.DocumentBuilder; +import com.aspose.ms.System.msConsole; +import com.aspose.words.NodeType; +import com.aspose.words.Row; +import com.aspose.words.CompositeNode; +import com.aspose.words.NodeImporter; +import com.aspose.words.ImportFormatMode; +import com.aspose.words.Paragraph; +import com.aspose.words.Node; +import com.aspose.words.PdfSaveOptions; +import com.aspose.words.Run; + + +class WorkingWithBookmarks extends DocsExamplesBase +{ + @Test + public void accessBookmarks() throws Exception + { + //ExStart:AccessBookmarks + //GistId:c4555b1a088856e21394104faeb86e51 + Document doc = new Document(getMyDir() + "Bookmarks.docx"); + // By index: + Bookmark bookmark1 = doc.getRange().getBookmarks().get(0); + // By name: + Bookmark bookmark2 = doc.getRange().getBookmarks().get("MyBookmark3"); + //ExEnd:AccessBookmarks + } + + @Test + public void updateBookmarkData() throws Exception + { + //ExStart:UpdateBookmarkData + //GistId:c4555b1a088856e21394104faeb86e51 + Document doc = new Document(getMyDir() + "Bookmarks.docx"); + + Bookmark bookmark = doc.getRange().getBookmarks().get("MyBookmark1"); + + String name = bookmark.getName(); + String text = bookmark.getText(); + + bookmark.setName("RenamedBookmark"); + bookmark.setText("This is a new bookmarked text."); + //ExEnd:UpdateBookmarkData + } + + @Test + public void bookmarkTableColumns() throws Exception + { + //ExStart:BookmarkTable + //GistId:c4555b1a088856e21394104faeb86e51 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startTable(); + + builder.insertCell(); + + builder.startBookmark("MyBookmark"); + + builder.write("This is row 1 cell 1"); + + builder.insertCell(); + builder.write("This is row 1 cell 2"); + + builder.endRow(); + + builder.insertCell(); + builder.writeln("This is row 2 cell 1"); + + builder.insertCell(); + builder.writeln("This is row 2 cell 2"); + + builder.endRow(); + builder.endTable(); + + builder.endBookmark("MyBookmark"); + //ExEnd:BookmarkTable + + //ExStart:BookmarkTableColumns + //GistId:c4555b1a088856e21394104faeb86e51 + for (Bookmark bookmark : doc.getRange().getBookmarks()) + { + System.out.println("Bookmark: {0}{1}",bookmark.getName(),bookmark.isColumn() ? " (Column)" : ""); + + if (bookmark.isColumn()) + { + if (bookmark.getBookmarkStart().getAncestor(NodeType.ROW) instanceof Row row && bookmark.FirstColumn < row.Cells.Count) + Console.WriteLine(row.Cells[bookmark.FirstColumn].GetText().TrimEnd(ControlChar.CellChar)); + } + } + //ExEnd:BookmarkTableColumns + } + + @Test + public void copyBookmarkedText() throws Exception + { + Document srcDoc = new Document(getMyDir() + "Bookmarks.docx"); + + // This is the bookmark whose content we want to copy. + Bookmark srcBookmark = srcDoc.getRange().getBookmarks().get("MyBookmark1"); + + // We will be adding to this document. + Document dstDoc = new Document(); + + // Let's say we will be appended to the end of the body of the last section. + CompositeNode dstNode = dstDoc.getLastSection().getBody(); + + // If you import multiple times without a single context, it will result in many styles created. + NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + appendBookmarkedText(importer, srcBookmark, dstNode); + + dstDoc.save(getArtifactsDir() + "WorkingWithBookmarks.CopyBookmarkedText.docx"); + } + + /// + /// Copies content of the bookmark and adds it to the end of the specified node. + /// The destination node can be in a different document. + /// + /// Maintains the import context. + /// The input bookmark. + /// Must be a node that can contain paragraphs (such as a Story). + private void appendBookmarkedText(NodeImporter importer, Bookmark srcBookmark, CompositeNode dstNode) throws Exception + { + // This is the paragraph that contains the beginning of the bookmark. + Paragraph startPara = (Paragraph) srcBookmark.getBookmarkStart().getParentNode(); + + // This is the paragraph that contains the end of the bookmark. + Paragraph endPara = (Paragraph) srcBookmark.getBookmarkEnd().getParentNode(); + + if (startPara == null || endPara == null) + throw new IllegalStateException( + "Parent of the bookmark start or end is not a paragraph, cannot handle this scenario yet."); + + // Limit ourselves to a reasonably simple scenario. + if (startPara.getParentNode() != endPara.getParentNode()) + throw new IllegalStateException( + "Start and end paragraphs have different parents, cannot handle this scenario yet."); + + // We want to copy all paragraphs from the start paragraph up to (and including) the end paragraph, + // therefore the node at which we stop is one after the end paragraph. + Node endNode = endPara.getNextSibling(); + + for (Node curNode = startPara; curNode != endNode; curNode = curNode.getNextSibling()) + { + // This creates a copy of the current node and imports it (makes it valid) in the context + // of the destination document. Importing means adjusting styles and list identifiers correctly. + Node newNode = importer.importNode(curNode, true); + + dstNode.appendChild(newNode); + } + } + + @Test + public void createBookmark() throws Exception + { + //ExStart:CreateBookmark + //GistId:c4555b1a088856e21394104faeb86e51 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startBookmark("My Bookmark"); + builder.writeln("Text inside a bookmark."); + + builder.startBookmark("Nested Bookmark"); + builder.writeln("Text inside a NestedBookmark."); + builder.endBookmark("Nested Bookmark"); + + builder.writeln("Text after Nested Bookmark."); + builder.endBookmark("My Bookmark"); + + PdfSaveOptions options = new PdfSaveOptions(); + options.getOutlineOptions().getBookmarksOutlineLevels().add("My Bookmark", 1); + options.getOutlineOptions().getBookmarksOutlineLevels().add("Nested Bookmark", 2); + + doc.save(getArtifactsDir() + "WorkingWithBookmarks.CreateBookmark.docx", options); + //ExEnd:CreateBookmark + } + + @Test + public void showHideBookmarks() throws Exception + { + //ExStart:ShowHideBookmarks + //GistId:c4555b1a088856e21394104faeb86e51 + Document doc = new Document(getMyDir() + "Bookmarks.docx"); + + showHideBookmarkedContent(doc, "MyBookmark1", true); + + doc.save(getArtifactsDir() + "WorkingWithBookmarks.ShowHideBookmarks.docx"); + //ExEnd:ShowHideBookmarks + } + + //ExStart:ShowHideBookmarkedContent + //GistId:c4555b1a088856e21394104faeb86e51 + public void showHideBookmarkedContent(Document doc, String bookmarkName, boolean isHidden) + { + Bookmark bm = doc.getRange().getBookmarks().get(bookmarkName); + + Node currentNode = bm.getBookmarkStart(); + while (currentNode != null && currentNode.getNodeType() != NodeType.BOOKMARK_END) + { + if (currentNode.getNodeType() == NodeType.RUN) + { + Run run = ms.as(currentNode, Run.class); + run.getFont().setHidden(isHidden); + } + currentNode = currentNode.getNextSibling(); + } + } + //ExEnd:ShowHideBookmarkedContent + + @Test + public void untangleRowBookmarks() throws Exception + { + Document doc = new Document(getMyDir() + "Table column bookmarks.docx"); + + // This performs the custom task of putting the row bookmark ends into the same row with the bookmark starts. + untangle(doc); + + // Now we can easily delete rows by a bookmark without damaging any other row's bookmarks. + deleteRowByBookmark(doc, "ROW2"); + + // This is just to check that the other bookmark was not damaged. + if (doc.getRange().getBookmarks().get("ROW1").getBookmarkEnd() == null) + throw new Exception("Wrong, the end of the bookmark was deleted."); + + doc.save(getArtifactsDir() + "WorkingWithBookmarks.UntangleRowBookmarks.docx"); + } + + private void untangle(Document doc) throws Exception + { + for (Bookmark bookmark : doc.getRange().getBookmarks()) + { + // Get the parent row of both the bookmark and bookmark end node. + Row row1 = (Row) bookmark.getBookmarkStart().getAncestor(Row.class); + Row row2 = (Row) bookmark.getBookmarkEnd().getAncestor(Row.class); + + // If both rows are found okay, and the bookmark start and end are contained in adjacent rows, + // move the bookmark end node to the end of the last paragraph in the top row's last cell. + if (row1 != null && row2 != null && row1.getNextSibling() == row2) + row1.getLastCell().getLastParagraph().appendChild(bookmark.getBookmarkEnd()); + } + } + + private void deleteRowByBookmark(Document doc, String bookmarkName) + { + Bookmark bookmark = doc.getRange().getBookmarks().get(bookmarkName); + + Row row = (Row) bookmark?.BookmarkStart.GetAncestor(typeof(Row)); + row?.Remove(); + } +} + diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/WorkingWithRanges.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/WorkingWithRanges.java new file mode 100644 index 00000000..5546d09d --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/WorkingWithRanges.java @@ -0,0 +1,31 @@ +package DocsExamples.Programming_with_Documents.Contents_Management; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; + + +class WorkingWithRanges extends DocsExamplesBase +{ + @Test + public void rangesDeleteText() throws Exception + { + //ExStart:RangesDeleteText + //GistId:9164e9c0658006e51db723b0742c12fc + Document doc = new Document(getMyDir() + "Document.docx"); + doc.getSections().get(0).getRange().delete(); + //ExEnd:RangesDeleteText + } + + @Test + public void rangesGetText() throws Exception + { + //ExStart:RangesGetText + //GistId:9164e9c0658006e51db723b0742c12fc + Document doc = new Document(getMyDir() + "Document.docx"); + String text = doc.getRange().getText(); + //ExEnd:RangesGetText + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/WorkingWithSDT.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/WorkingWithSDT.java new file mode 100644 index 00000000..b0021f01 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/WorkingWithSDT.java @@ -0,0 +1,296 @@ +package DocsExamples.Programming_with_Documents.Contents_Management; + +// ********* THIS FILE IS AUTO PORTED ********* + +import com.aspose.ms.System.ms; +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.StructuredDocumentTag; +import com.aspose.words.SdtType; +import com.aspose.words.MarkupLevel; +import com.aspose.words.SaveFormat; +import com.aspose.words.NodeType; +import com.aspose.words.Paragraph; +import com.aspose.words.Run; +import com.aspose.words.SdtListItem; +import com.aspose.words.Shape; +import com.aspose.ms.System.Drawing.msColor; +import java.awt.Color; +import com.aspose.words.CustomXmlPart; +import com.aspose.ms.System.Guid; +import com.aspose.words.Style; +import com.aspose.words.StyleIdentifier; +import com.aspose.words.Table; +import com.aspose.words.Row; +import com.aspose.words.NodeCollection; +import com.aspose.words.StructuredDocumentTagRangeStart; +import com.aspose.ms.System.msConsole; +import com.aspose.ms.System.Text.Encoding; + + +class WorkingWithSdt extends DocsExamplesBase +{ + @Test + public void sdtCheckBox() throws Exception + { + //ExStart:SdtCheckBox + //GistId:089defec1b191de967e6099effeabda7 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + StructuredDocumentTag sdtCheckBox = new StructuredDocumentTag(doc, SdtType.CHECKBOX, MarkupLevel.INLINE); + builder.insertNode(sdtCheckBox); + + doc.save(getArtifactsDir() + "WorkingWithSdt.SdtCheckBox.docx", SaveFormat.DOCX); + //ExEnd:SdtCheckBox + } + + @Test + public void currentStateOfCheckBox() throws Exception + { + //ExStart:CurrentStateOfCheckBox + //GistId:089defec1b191de967e6099effeabda7 + Document doc = new Document(getMyDir() + "Structured document tags.docx"); + + // Get the first content control from the document. + StructuredDocumentTag sdtCheckBox = + (StructuredDocumentTag) doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + + if (sdtCheckBox.getSdtType() == SdtType.CHECKBOX) + sdtCheckBox.setChecked(true); + + doc.save(getArtifactsDir() + "WorkingWithSdt.CurrentStateOfCheckBox.docx"); + //ExEnd:CurrentStateOfCheckBox + } + + @Test + public void modifySdt() throws Exception + { + //ExStart:ModifySdt + //GistId:089defec1b191de967e6099effeabda7 + Document doc = new Document(getMyDir() + "Structured document tags.docx"); + + for (StructuredDocumentTag sdt : (Iterable) doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG, true)) + { + switch (sdt.getSdtType()) + { + case SdtType.PLAIN_TEXT: + { + sdt.removeAllChildren(); + Paragraph para = ms.as(sdt.appendChild(new Paragraph(doc)), Paragraph.class); + Run run = new Run(doc, "new text goes here"); + para.appendChild(run); + break; + } + case SdtType.DROP_DOWN_LIST: + { + SdtListItem secondItem = sdt.getListItems().get(2); + sdt.getListItems().setSelectedValue(secondItem); + break; + } + case SdtType.PICTURE: + { + Shape shape = (Shape) sdt.getChild(NodeType.SHAPE, 0, true); + if (shape.hasImage()) + { + shape.getImageData().setImage(getImagesDir() + "Watermark.png"); + } + + break; + } + } + } + + doc.save(getArtifactsDir() + "WorkingWithSdt.ModifySdt.docx"); + //ExEnd:ModifySdt + } + + @Test + public void sdtComboBox() throws Exception + { + //ExStart:SdtComboBox + //GistId:089defec1b191de967e6099effeabda7 + Document doc = new Document(); + + StructuredDocumentTag sdt = new StructuredDocumentTag(doc, SdtType.COMBO_BOX, MarkupLevel.BLOCK); + sdt.getListItems().add(new SdtListItem("Choose an item", "-1")); + sdt.getListItems().add(new SdtListItem("Item 1", "1")); + sdt.getListItems().add(new SdtListItem("Item 2", "2")); + doc.getFirstSection().getBody().appendChild(sdt); + + doc.save(getArtifactsDir() + "WorkingWithSdt.SdtComboBox.docx"); + //ExEnd:SdtComboBox + } + + @Test + public void sdtRichTextBox() throws Exception + { + //ExStart:SdtRichTextBox + //GistId:089defec1b191de967e6099effeabda7 + Document doc = new Document(); + + StructuredDocumentTag sdtRichText = new StructuredDocumentTag(doc, SdtType.RICH_TEXT, MarkupLevel.BLOCK); + + Paragraph para = new Paragraph(doc); + Run run = new Run(doc); + run.setText("Hello World"); + run.getFont().setColor(msColor.getGreen()); + para.getRuns().add(run); + sdtRichText.getChildNodes(NodeType.ANY, false).add(para); + doc.getFirstSection().getBody().appendChild(sdtRichText); + + doc.save(getArtifactsDir() + "WorkingWithSdt.SdtRichTextBox.docx"); + //ExEnd:SdtRichTextBox + } + + @Test + public void sdtColor() throws Exception + { + //ExStart:SdtColor + //GistId:089defec1b191de967e6099effeabda7 + Document doc = new Document(getMyDir() + "Structured document tags.docx"); + + StructuredDocumentTag sdt = (StructuredDocumentTag) doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + sdt.setColor(Color.RED); + + doc.save(getArtifactsDir() + "WorkingWithSdt.SdtColor.docx"); + //ExEnd:SdtColor + } + + @Test + public void clearSdt() throws Exception + { + //ExStart:ClearSdt + //GistId:089defec1b191de967e6099effeabda7 + Document doc = new Document(getMyDir() + "Structured document tags.docx"); + + StructuredDocumentTag sdt = (StructuredDocumentTag) doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + sdt.clear(); + + doc.save(getArtifactsDir() + "WorkingWithSdt.ClearSdt.doc"); + //ExEnd:ClearSdt + } + + @Test + public void bindSdtToCustomXmlPart() throws Exception + { + //ExStart:BindSdtToCustomXmlPart + //GistId:089defec1b191de967e6099effeabda7 + Document doc = new Document(); + CustomXmlPart xmlPart = + doc.getCustomXmlParts().add(Guid.newGuid().toString("B"), "Hello, World!"); + + StructuredDocumentTag sdt = new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.BLOCK); + doc.getFirstSection().getBody().appendChild(sdt); + + sdt.getXmlMapping().setMapping(xmlPart, "/root[1]/text[1]", ""); + + doc.save(getArtifactsDir() + "WorkingWithSdt.BindSdtToCustomXmlPart.doc"); + //ExEnd:BindSdtToCustomXmlPart + } + + @Test + public void sdtStyle() throws Exception + { + //ExStart:SdtStyle + //GistId:089defec1b191de967e6099effeabda7 + Document doc = new Document(getMyDir() + "Structured document tags.docx"); + + StructuredDocumentTag sdt = (StructuredDocumentTag) doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); + Style style = doc.getStyles().getByStyleIdentifier(StyleIdentifier.QUOTE); + sdt.setStyle(style); + + doc.save(getArtifactsDir() + "WorkingWithSdt.SdtStyle.docx"); + //ExEnd:SdtStyle + } + + @Test + public void repeatingSectionMappedToCustomXmlPart() throws Exception + { + //ExStart:RepeatingSectionMappedToCustomXmlPart + //GistId:089defec1b191de967e6099effeabda7 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + CustomXmlPart xmlPart = doc.getCustomXmlParts().add("Books", + "Everyday ItalianGiada De Laurentiis" + + "Harry PotterJ K. Rowling" + + "Learning XMLErik T. Ray"); + + Table table = builder.startTable(); + + builder.insertCell(); + builder.write("Title"); + + builder.insertCell(); + builder.write("Author"); + + builder.endRow(); + builder.endTable(); + + StructuredDocumentTag repeatingSectionSdt = + new StructuredDocumentTag(doc, SdtType.REPEATING_SECTION, MarkupLevel.ROW); + repeatingSectionSdt.getXmlMapping().setMapping(xmlPart, "/books[1]/book", ""); + table.appendChild(repeatingSectionSdt); + + StructuredDocumentTag repeatingSectionItemSdt = + new StructuredDocumentTag(doc, SdtType.REPEATING_SECTION_ITEM, MarkupLevel.ROW); + repeatingSectionSdt.appendChild(repeatingSectionItemSdt); + + Row row = new Row(doc); + repeatingSectionItemSdt.appendChild(row); + + StructuredDocumentTag titleSdt = + new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.CELL); + titleSdt.getXmlMapping().setMapping(xmlPart, "/books[1]/book[1]/title[1]", ""); + row.appendChild(titleSdt); + + StructuredDocumentTag authorSdt = + new StructuredDocumentTag(doc, SdtType.PLAIN_TEXT, MarkupLevel.CELL); + authorSdt.getXmlMapping().setMapping(xmlPart, "/books[1]/book[1]/author[1]", ""); + row.appendChild(authorSdt); + + doc.save(getArtifactsDir() + "WorkingWithSdt.RepeatingSectionMappedToCustomXmlPart.docx"); + //ExEnd:RepeatingSectionMappedToCustomXmlPart + } + + @Test + public void multiSection() throws Exception + { + //ExStart:MultiSectionSDT + Document doc = new Document(getMyDir() + "Multi-section structured document tags.docx"); + + NodeCollection tags = doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_START, true); + + for (StructuredDocumentTagRangeStart tag : (Iterable) tags) + System.out.println(tag.getTitle()); + //ExEnd:MultiSectionSDT + } + + @Test + public void sdtRangeStartXmlMapping() throws Exception + { + //ExStart:SdtRangeStartXmlMapping + //GistId:089defec1b191de967e6099effeabda7 + Document doc = new Document(getMyDir() + "Multi-section structured document tags.docx"); + + // Construct an XML part that contains data and add it to the document's CustomXmlPart collection. + String xmlPartId = Guid.newGuid().toString("B"); + String xmlPartContent = "Text element #1Text element #2"; + CustomXmlPart xmlPart = doc.getCustomXmlParts().add(xmlPartId, xmlPartContent); + System.out.println(Encoding.getUTF8().getString(xmlPart.getData())); + + // Create a StructuredDocumentTag that will display the contents of our CustomXmlPart in the document. + StructuredDocumentTagRangeStart sdtRangeStart = (StructuredDocumentTagRangeStart)doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG_RANGE_START, 0, true); + + // If we set a mapping for our StructuredDocumentTag, + // it will only display a part of the CustomXmlPart that the XPath points to. + // This XPath will point to the contents second "" element of the first "" element of our CustomXmlPart. + sdtRangeStart.getXmlMapping().setMapping(xmlPart, "/root[1]/text[2]", null); + + doc.save(getArtifactsDir() + "WorkingWithSdt.SdtRangeStartXmlMapping.docx"); + //ExEnd:SdtRangeStartXmlMapping + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/WorkingWithStylesAndThemes.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/WorkingWithStylesAndThemes.java new file mode 100644 index 00000000..7a4c6127 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/WorkingWithStylesAndThemes.java @@ -0,0 +1,138 @@ +package DocsExamples.Programming_with_Documents.Contents_Management; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.StyleCollection; +import com.aspose.words.Style; +import com.aspose.ms.System.msConsole; +import com.aspose.words.Theme; +import com.aspose.ms.System.Drawing.msColor; +import java.awt.Color; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.StyleType; +import com.aspose.words.StyleIdentifier; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; + + +class WorkingWithStylesAndThemes extends DocsExamplesBase +{ + @Test + public void accessStyles() throws Exception + { + //ExStart:AccessStyles + //GistId:a73b495f610523670f0847331ef4d6fc + Document doc = new Document(); + + String styleName = ""; + + // Get styles collection from the document. + StyleCollection styles = doc.getStyles(); + for (Style style : styles) + { + if ("".equals(styleName)) + { + styleName = style.getName(); + System.out.println(styleName); + } + else + { + styleName = styleName + ", " + style.getName(); + System.out.println(styleName); + } + } + //ExEnd:AccessStyles + } + + @Test + public void copyStyles() throws Exception + { + //ExStart:CopyStyles + //GistId:a73b495f610523670f0847331ef4d6fc + Document doc = new Document(); + Document target = new Document(getMyDir() + "Rendering.docx"); + + target.copyStylesFromTemplate(doc); + + doc.save(getArtifactsDir() + "WorkingWithStylesAndThemes.CopyStyles.docx"); + //ExEnd:CopyStyles + } + + @Test + public void getThemeProperties() throws Exception + { + //ExStart:GetThemeProperties + //GistId:a73b495f610523670f0847331ef4d6fc + Document doc = new Document(); + + Theme theme = doc.getTheme(); + + System.out.println(theme.getMajorFonts().getLatin()); + System.out.println(theme.getMinorFonts().getEastAsian()); + System.out.println(theme.getColors().getAccent1()); + //ExEnd:GetThemeProperties + } + + @Test + public void setThemeProperties() throws Exception + { + //ExStart:SetThemeProperties + //GistId:a73b495f610523670f0847331ef4d6fc + Document doc = new Document(); + + Theme theme = doc.getTheme(); + theme.getMinorFonts().setLatin("Times New Roman"); + theme.getColors().setHyperlink(msColor.getGold()); + //ExEnd:SetThemeProperties + } + + @Test + public void insertStyleSeparator() throws Exception + { + //ExStart:InsertStyleSeparator + //GistId:4b5526c3c0d9cad73e05fb4b18d2c3d2 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Style paraStyle = builder.getDocument().getStyles().add(StyleType.PARAGRAPH, "MyParaStyle"); + paraStyle.getFont().setBold(false); + paraStyle.getFont().setSize(8.0); + paraStyle.getFont().setName("Arial"); + + // Append text with "Heading 1" style. + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + builder.write("Heading 1"); + builder.insertStyleSeparator(); + + // Append text with another style. + builder.getParagraphFormat().setStyleName(paraStyle.getName()); + builder.write("This is text with some other formatting "); + + doc.save(getArtifactsDir() + "WorkingWithStylesAndThemes.InsertStyleSeparator.docx"); + //ExEnd:InsertStyleSeparator + } + + @Test + public void copyStyleDifferentDocument() throws Exception + { + //ExStart:CopyStyleDifferentDocument + //GistId:93b92a7e6f2f4bbfd9177dd7fcecbd8c + Document srcDoc = new Document(); + + // Create a custom style for the source document. + Style srcStyle = srcDoc.getStyles().add(StyleType.PARAGRAPH, "MyStyle"); + srcStyle.getFont().setColor(Color.RED); + + // Import the source document's custom style into the destination document. + Document dstDoc = new Document(); + Style newStyle = dstDoc.getStyles().addCopy(srcStyle); + + // The imported style has an appearance identical to its source style. + Assert.assertEquals("MyStyle", newStyle.getName()); + Assert.assertEquals(Color.RED.getRGB(), newStyle.getFont().getColor().getRGB()); + //ExEnd:CopyStyleDifferentDocument + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/WorkingWithTableOfContent.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/WorkingWithTableOfContent.java new file mode 100644 index 00000000..58ab9635 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Contents_Management/WorkingWithTableOfContent.java @@ -0,0 +1,91 @@ +package DocsExamples.Programming_with_Documents.Contents_Management; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.StyleIdentifier; +import com.aspose.words.Paragraph; +import com.aspose.words.NodeType; +import com.aspose.words.TabStop; +import com.aspose.words.Field; +import com.aspose.words.FieldType; +import com.aspose.words.FieldHyperlink; +import com.aspose.ms.System.msConsole; +import com.aspose.words.SaveFormat; +import com.aspose.words.Bookmark; + + +class WorkingWithTableOfContent extends DocsExamplesBase +{ + @Test + public void changeStyleOfTocLevel() throws Exception + { + //ExStart:ChangeStyleOfTocLevel + //GistId:db118a3e1559b9c88355356df9d7ea10 + Document doc = new Document(); + // Retrieve the style used for the first level of the TOC and change the formatting of the style. + doc.getStyles().getByStyleIdentifier(StyleIdentifier.TOC_1).getFont().setBold(true); + //ExEnd:ChangeStyleOfTocLevel + } + + @Test + public void changeTocTabStops() throws Exception + { + //ExStart:ChangeTocTabStops + //GistId:db118a3e1559b9c88355356df9d7ea10 + Document doc = new Document(getMyDir() + "Table of contents.docx"); + + for (Paragraph para : (Iterable) doc.getChildNodes(NodeType.PARAGRAPH, true)) + { + // Check if this paragraph is formatted using the TOC result based styles. + // This is any style between TOC and TOC9. + if (para.getParagraphFormat().getStyle().getStyleIdentifier() >= StyleIdentifier.TOC_1 && + para.getParagraphFormat().getStyle().getStyleIdentifier() <= StyleIdentifier.TOC_9) + { + // Get the first tab used in this paragraph, this should be the tab used to align the page numbers. + TabStop tab = para.getParagraphFormat().getTabStops().get(0); + + // Remove the old tab from the collection. + para.getParagraphFormat().getTabStops().removeByPosition(tab.getPosition()); + + // Insert a new tab using the same properties but at a modified position. + // We could also change the separators used (dots) by passing a different Leader type. + para.getParagraphFormat().getTabStops().add(tab.getPosition() - 50.0, tab.getAlignment(), tab.getLeader()); + } + } + + doc.save(getArtifactsDir() + "WorkingWithTableOfContent.ChangeTocTabStops.docx"); + //ExEnd:ChangeTocTabStops + } + + @Test + public void extractToc() throws Exception + { + //ExStart:ExtractToc + //GistId:db118a3e1559b9c88355356df9d7ea10 + Document doc = new Document(getMyDir() + "Table of contents.docx"); + + for (Field field : doc.getRange().getFields()) + { + if (((field.getType()) == (FieldType.FIELD_HYPERLINK))) + { + FieldHyperlink hyperlink = (FieldHyperlink)field; + if (hyperlink.getSubAddress() != null && hyperlink.getSubAddress().startsWith("_Toc")) + { + Paragraph tocItem = (Paragraph)field.getStart().getAncestor(NodeType.PARAGRAPH); + System.out.println(tocItem.toString(SaveFormat.TEXT).trim()); + System.out.println("------------------"); + if (tocItem != null) + { + Bookmark bm = doc.getRange().getBookmarks().get(hyperlink.getSubAddress()); + Paragraph pointer = (Paragraph)bm.getBookmarkStart().getAncestor(NodeType.PARAGRAPH); + System.out.println(pointer.toString(SaveFormat.TEXT)); + } + } + } + } + //ExEnd:ExtractToc + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/EnableOpenTypeFeatures.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/EnableOpenTypeFeatures.java new file mode 100644 index 00000000..60a677e4 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/EnableOpenTypeFeatures.java @@ -0,0 +1,27 @@ +package DocsExamples.Programming_with_Documents; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.shaping.harfbuzz.HarfBuzzTextShaperFactory; + + +class EnableOpenTypeFeatures extends DocsExamplesBase +{ + @Test + public void openTypeFeatures() throws Exception + { + //ExStart:OpenTypeFeatures + //GistId:7840fae2297fa05bba1ca0608cb81bf1 + Document doc = new Document(getMyDir() + "OpenType text shaping.docx"); + + // When we set the text shaper factory, the layout starts to use OpenType features. + // An Instance property returns BasicTextShaperCache object wrapping HarfBuzzTextShaperFactory. + doc.getLayoutOptions().setTextShaperFactory(com.aspose.words.shaping.harfbuzz.HarfBuzzTextShaperFactory.getInstance()); + + doc.save(getArtifactsDir() + "WorkingWithHarfBuzz.OpenTypeFeatures.pdf"); + //ExEnd:OpenTypeFeatures + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Protect_or_encrypt_document/DocumentProtection.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Protect_or_encrypt_document/DocumentProtection.java new file mode 100644 index 00000000..b334606c --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Protect_or_encrypt_document/DocumentProtection.java @@ -0,0 +1,176 @@ +package DocsExamples.Programming_with_Documents.Protect_or_Encrypt_Document; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.ProtectionType; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.EditableRangeStart; +import com.aspose.words.EditableRange; +import com.aspose.words.EditableRangeEnd; +import com.aspose.words.BreakType; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; + + +class DocumentProtection extends DocsExamplesBase +{ + @Test + public void passwordProtection() throws Exception + { + //ExStart:PasswordProtection + //GistId:856ba85fa704fa728b0ec20aafddd16b + Document doc = new Document(); + + // Apply document protection. + doc.protect(ProtectionType.NO_PROTECTION, "password"); + + doc.save(getArtifactsDir() + "DocumentProtection.PasswordProtection.docx"); + //ExEnd:PasswordProtection + } + + @Test + public void allowOnlyFormFieldsProtect() throws Exception + { + //ExStart:AllowOnlyFormFieldsProtect + //GistId:856ba85fa704fa728b0ec20aafddd16b + // Insert two sections with some text. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Text added to a document."); + + // A document protection only works when document protection is turned and only editing in form fields is allowed. + doc.protect(ProtectionType.ALLOW_ONLY_FORM_FIELDS, "password"); + + // Save the protected document. + doc.save(getArtifactsDir() + "DocumentProtection.AllowOnlyFormFieldsProtect.docx"); + //ExEnd:AllowOnlyFormFieldsProtect + } + + @Test + public void removeDocumentProtection() throws Exception + { + //ExStart:RemoveDocumentProtection + //GistId:856ba85fa704fa728b0ec20aafddd16b + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Text added to a document."); + + // Documents can have protection removed either with no password, or with the correct password. + doc.unprotect(); + doc.protect(ProtectionType.READ_ONLY, "newPassword"); + doc.unprotect("newPassword"); + + doc.save(getArtifactsDir() + "DocumentProtection.RemoveDocumentProtection.docx"); + //ExEnd:RemoveDocumentProtection + } + + @Test + public void unrestrictedEditableRegions() throws Exception + { + //ExStart:UnrestrictedEditableRegions + //GistId:856ba85fa704fa728b0ec20aafddd16b + // Upload a document and make it as read-only. + Document doc = new Document(getMyDir() + "Document.docx"); + DocumentBuilder builder = new DocumentBuilder(doc); + + doc.protect(ProtectionType.READ_ONLY, "MyPassword"); + + builder.writeln("Hello world! Since we have set the document's protection level to read-only, " + "we cannot edit this paragraph without the password."); + + // Start an editable range. + EditableRangeStart edRangeStart = builder.startEditableRange(); + // An EditableRange object is created for the EditableRangeStart that we just made. + EditableRange editableRange = edRangeStart.getEditableRange(); + + // Put something inside the editable range. + builder.writeln("Paragraph inside first editable range"); + + // An editable range is well-formed if it has a start and an end. + EditableRangeEnd edRangeEnd = builder.endEditableRange(); + + builder.writeln("This paragraph is outside any editable ranges, and cannot be edited."); + + doc.save(getArtifactsDir() + "DocumentProtection.UnrestrictedEditableRegions.docx"); + //ExEnd:UnrestrictedEditableRegions + } + + @Test + public void unrestrictedSection() throws Exception + { + //ExStart:UnrestrictedSection + //GistId:856ba85fa704fa728b0ec20aafddd16b + // Insert two sections with some text. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Section 1. Unprotected."); + builder.insertBreak(BreakType.SECTION_BREAK_CONTINUOUS); + builder.writeln("Section 2. Protected."); + + // Section protection only works when document protection is turned and only editing in form fields is allowed. + doc.protect(ProtectionType.ALLOW_ONLY_FORM_FIELDS, "password"); + + // By default, all sections are protected, but we can selectively turn protection off. + doc.getSections().get(0).setProtectedForForms(false); + doc.save(getArtifactsDir() + "DocumentProtection.UnrestrictedSection.docx"); + + doc = new Document(getArtifactsDir() + "DocumentProtection.UnrestrictedSection.docx"); + Assert.assertFalse(doc.getSections().get(0).getProtectedForForms()); + Assert.assertTrue(doc.getSections().get(1).getProtectedForForms()); + //ExEnd:UnrestrictedSection + } + + @Test + public void getProtectionType() throws Exception + { + //ExStart:GetProtectionType + Document doc = new Document(getMyDir() + "Document.docx"); + /*ProtectionType*/int protectionType = doc.getProtectionType(); + //ExEnd:GetProtectionType + } + + @Test + public void readOnlyProtection() throws Exception + { + //ExStart:ReadOnlyProtection + //GistId:7cf6735e83804ba8942663695b22ee42 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Open document as read-only"); + + // Enter a password that's up to 15 characters long. + doc.getWriteProtection().setPassword("MyPassword"); + + // Make the document as read-only. + doc.getWriteProtection().setReadOnlyRecommended(true); + + // Apply write protection as read-only. + doc.protect(ProtectionType.READ_ONLY); + doc.save(getArtifactsDir() + "DocumentProtection.ReadOnlyProtection.docx"); + //ExEnd:ReadOnlyProtection + } + + @Test + public void removeReadOnlyRestriction() throws Exception + { + //ExStart:RemoveReadOnlyRestriction + //GistId:7cf6735e83804ba8942663695b22ee42 + Document doc = new Document(); + + // Enter a password that's up to 15 characters long. + doc.getWriteProtection().setPassword("MyPassword"); + + // Remove the read-only option. + doc.getWriteProtection().setReadOnlyRecommended(false); + + // Apply write protection without any protection. + doc.protect(ProtectionType.NO_PROTECTION); + doc.save(getArtifactsDir() + "DocumentProtection.RemoveReadOnlyRestriction.docx"); + //ExEnd:RemoveReadOnlyRestriction + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Protect_or_encrypt_document/WorkingWithDigitalSinatures.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Protect_or_encrypt_document/WorkingWithDigitalSinatures.java new file mode 100644 index 00000000..48bd32fb --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Protect_or_encrypt_document/WorkingWithDigitalSinatures.java @@ -0,0 +1,229 @@ +package DocsExamples.Programming_with_Documents.Protect_or_Encrypt_Document; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.CertificateHolder; +import com.aspose.words.DigitalSignatureUtil; +import com.aspose.words.SignOptions; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.SignatureLine; +import com.aspose.words.SignatureLineOptions; +import com.aspose.ms.System.IO.File; +import com.aspose.words.Shape; +import com.aspose.words.NodeType; +import com.aspose.ms.System.Guid; +import java.util.Date; +import com.aspose.ms.System.DateTime; +import com.aspose.words.DigitalSignature; +import com.aspose.ms.System.msConsole; +import com.aspose.ms.System.IO.Stream; +import com.aspose.ms.System.IO.FileStream; +import com.aspose.ms.System.IO.FileMode; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.ms.System.Convert; + + +class WorkingWithDigitalSinatures extends DocsExamplesBase +{ + @Test + public void signDocument() throws Exception + { + //ExStart:SignDocument + //GistId:bdc15a6de6b25d9d4e66f2ce918fc01b + CertificateHolder certHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + + DigitalSignatureUtil.sign(getMyDir() + "Digitally signed.docx", getArtifactsDir() + "Document.Signed.docx", + certHolder); + //ExEnd:SignDocument + } + + @Test + public void signingEncryptedDocument() throws Exception + { + //ExStart:SigningEncryptedDocument + SignOptions signOptions = new SignOptions(); { signOptions.setDecryptionPassword("decryptionPassword"); } + + CertificateHolder certHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + + DigitalSignatureUtil.sign(getMyDir() + "Digitally signed.docx", getArtifactsDir() + "Document.EncryptedDocument.docx", + certHolder, signOptions); + //ExEnd:SigningEncryptedDocument + } + + @Test + public void creatingAndSigningNewSignatureLine() throws Exception + { + //ExStart:CreatingAndSigningNewSignatureLine + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + SignatureLine signatureLine = builder.insertSignatureLine(new SignatureLineOptions()).getSignatureLine(); + + doc.save(getArtifactsDir() + "SignDocuments.SignatureLine.docx"); + + SignOptions signOptions = new SignOptions(); + { + signOptions.setSignatureLineId(signatureLine.getIdInternal()); + signOptions.setSignatureLineImage(File.readAllBytes(getImagesDir() + "Enhanced Windows MetaFile.emf")); + } + + CertificateHolder certHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + + DigitalSignatureUtil.sign(getArtifactsDir() + "SignDocuments.SignatureLine.docx", + getArtifactsDir() + "SignDocuments.NewSignatureLine.docx", certHolder, signOptions); + //ExEnd:CreatingAndSigningNewSignatureLine + } + + @Test + public void signingExistingSignatureLine() throws Exception + { + //ExStart:SigningExistingSignatureLine + Document doc = new Document(getMyDir() + "Signature line.docx"); + + SignatureLine signatureLine = + ((Shape) doc.getFirstSection().getBody().getChild(NodeType.SHAPE, 0, true)).getSignatureLine(); + + SignOptions signOptions = new SignOptions(); + { + signOptions.setSignatureLineId(signatureLine.getIdInternal()); + signOptions.setSignatureLineImage(File.readAllBytes(getImagesDir() + "Enhanced Windows MetaFile.emf")); + } + + CertificateHolder certHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + + DigitalSignatureUtil.sign(getMyDir() + "Digitally signed.docx", + getArtifactsDir() + "SignDocuments.SigningExistingSignatureLine.docx", certHolder, signOptions); + //ExEnd:SigningExistingSignatureLine + } + + @Test + public void setSignatureProviderId() throws Exception + { + //ExStart:SetSignatureProviderID + Document doc = new Document(getMyDir() + "Signature line.docx"); + + SignatureLine signatureLine = + ((Shape) doc.getFirstSection().getBody().getChild(NodeType.SHAPE, 0, true)).getSignatureLine(); + + SignOptions signOptions = new SignOptions(); + { + signOptions.setProviderId(signatureLine.getProviderIdInternal()); signOptions.setSignatureLineId(signatureLine.getIdInternal()); + } + + CertificateHolder certHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + + DigitalSignatureUtil.sign(getMyDir() + "Digitally signed.docx", + getArtifactsDir() + "SignDocuments.SetSignatureProviderId.docx", certHolder, signOptions); + //ExEnd:SetSignatureProviderID + } + + @Test + public void createNewSignatureLineAndSetProviderId() throws Exception + { + //ExStart:CreateNewSignatureLineAndSetProviderId + //GistId:bdc15a6de6b25d9d4e66f2ce918fc01b + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + SignatureLineOptions signatureLineOptions = new SignatureLineOptions(); + { + signatureLineOptions.setSigner("yourname"); + signatureLineOptions.setSignerTitle("Worker"); + signatureLineOptions.setEmail("yourname@aspose.com"); + signatureLineOptions.setShowDate(true); + signatureLineOptions.setDefaultInstructions(false); + signatureLineOptions.setInstructions("Please sign here."); + signatureLineOptions.setAllowComments(true); + } + + SignatureLine signatureLine = builder.insertSignatureLine(signatureLineOptions).getSignatureLine(); + signatureLine.setProviderIdInternal(Guid.parse("CF5A7BB4-8F3C-4756-9DF6-BEF7F13259A2")); + + doc.save(getArtifactsDir() + "SignDocuments.SignatureLineProviderId.docx"); + + SignOptions signOptions = new SignOptions(); + { + signOptions.setSignatureLineId(signatureLine.getIdInternal()); + signOptions.setProviderId(signatureLine.getProviderIdInternal()); + signOptions.setComments("Document was signed by Aspose"); + signOptions.setSignTime(new Date); + } + + CertificateHolder certHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"); + + DigitalSignatureUtil.sign(getArtifactsDir() + "SignDocuments.SignatureLineProviderId.docx", + getArtifactsDir() + "SignDocuments.CreateNewSignatureLineAndSetProviderId.docx", certHolder, signOptions); + //ExEnd:CreateNewSignatureLineAndSetProviderId + } + + @Test + public void accessAndVerifySignature() throws Exception + { + //ExStart:AccessAndVerifySignature + Document doc = new Document(getMyDir() + "Digitally signed.docx"); + + for (DigitalSignature signature : doc.getDigitalSignatures()) + { + System.out.println("*** Signature Found ***"); + System.out.println("Is valid: " + signature.isValid()); + // This property is available in MS Word documents only. + System.out.println("Reason for signing: " + signature.getComments()); + System.out.println("Time of signing: " + signature.getSignTimeInternal()); + System.out.println("Subject name: " + signature.getCertificateHolder().getCertificateInternal().getSubjectName().Name); + System.out.println("Issuer name: " + signature.getCertificateHolder().getCertificateInternal().getIssuerName().Name); + msConsole.writeLine(); + } + //ExEnd:AccessAndVerifySignature + } + + @Test + public void removeSignatures() throws Exception + { + //ExStart:RemoveSignatures + //GistId:bdc15a6de6b25d9d4e66f2ce918fc01b + // There are two ways of using the DigitalSignatureUtil class to remove digital signatures + // from a signed document by saving an unsigned copy of it somewhere else in the local file system. + // 1 - Determine the locations of both the signed document and the unsigned copy by filename strings: + DigitalSignatureUtil.removeAllSignatures(getMyDir() + "Digitally signed.docx", + getArtifactsDir() + "DigitalSignatureUtil.LoadAndRemove.FromString.docx"); + + // 2 - Determine the locations of both the signed document and the unsigned copy by file streams: + Stream streamIn = new FileStream(getMyDir() + "Digitally signed.docx", FileMode.OPEN); + try /*JAVA: was using*/ + { + Stream streamOut = new FileStream(getArtifactsDir() + "DigitalSignatureUtil.LoadAndRemove.FromStream.docx", FileMode.CREATE); + try /*JAVA: was using*/ + { + DigitalSignatureUtil.removeAllSignaturesInternal(streamIn, streamOut); + } + finally { if (streamOut != null) streamOut.close(); } + } + finally { if (streamIn != null) streamIn.close(); } + + // Verify that both our output documents have no digital signatures. + Assert.isEmpty(DigitalSignatureUtil.loadSignatures(getArtifactsDir() + "DigitalSignatureUtil.LoadAndRemove.FromString.docx")); + Assert.isEmpty(DigitalSignatureUtil.loadSignatures(getArtifactsDir() + "DigitalSignatureUtil.LoadAndRemove.FromStream.docx")); + //ExEnd:RemoveSignatures + } + + @Test + public void signatureValue() throws Exception + { + //ExStart:SignatureValue + //GistId:bdc15a6de6b25d9d4e66f2ce918fc01b + Document doc = new Document(getMyDir() + "Digitally signed.docx"); + + for (DigitalSignature digitalSignature : doc.getDigitalSignatures()) + { + String signatureValue = Convert.toBase64String(digitalSignature.getSignatureValue()); + Assert.assertEquals("K1cVLLg2kbJRAzT5WK+m++G8eEO+l7S+5ENdjMxxTXkFzGUfvwxREuJdSFj9AbD" + + "MhnGvDURv9KEhC25DDF1al8NRVR71TF3CjHVZXpYu7edQS5/yLw/k5CiFZzCp1+MmhOdYPcVO+Fm" + + "+9fKr2iNLeyYB+fgEeZHfTqTFM2WwAqo=", signatureValue); + } + //ExEnd:SignatureValue + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Split_documents/PageSplitter.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Split_documents/PageSplitter.java new file mode 100644 index 00000000..3cd35287 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Split_documents/PageSplitter.java @@ -0,0 +1,763 @@ +package DocsExamples.Programming_with_Documents.Split_Documents; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.ms.System.IO.Path; +import com.aspose.ms.System.msConsole; +import com.aspose.words.Document; +import java.util.ArrayList; +import com.aspose.ms.System.IO.Directory; +import com.aspose.ms.System.IO.SearchOption; +import com.aspose.words.Node; +import com.aspose.words.NodeType; +import java.util.Map; +import java.util.HashMap; +import com.aspose.words.LayoutCollector; +import com.aspose.words.Paragraph; +import com.aspose.ms.System.Collections.msDictionary; +import com.aspose.words.Run; +import com.aspose.ms.System.msString; +import com.aspose.words.DocumentVisitor; +import com.aspose.words.VisitorAction; +import com.aspose.words.Table; +import com.aspose.words.Row; +import com.aspose.words.Cell; +import com.aspose.words.StructuredDocumentTag; +import com.aspose.words.SmartTag; +import com.aspose.words.Section; +import com.aspose.words.HeaderFooterCollection; +import com.aspose.words.HeaderFooter; +import com.aspose.words.SectionStart; +import com.aspose.words.CompositeNode; +import java.util.Collections; +import com.aspose.words.Body; + + +class PageSplitter extends DocsExamplesBase +{ + @Test + public void splitDocuments() throws Exception + { + splitAllDocumentsToPages(getMyDir()); + } + + public void splitDocumentToPages(String docName) throws Exception + { + String fileName = Path.getFileNameWithoutExtension(docName); + String extensionName = Path.getExtension(docName); + + System.out.println("Processing document: " + fileName + extensionName); + + Document doc = new Document(docName); + + // Split nodes in the document into separate pages. + DocumentPageSplitter splitter = new DocumentPageSplitter(doc); + + // Save each page to the disk as a separate document. + for (int page = 1; page <= doc.getPageCount(); page++) + { + Document pageDoc = splitter.getDocumentOfPage(page); + pageDoc.save(Path.combine(getArtifactsDir(), + $"{fileName} - page{page} Out{extensionName}")); + } + } + + public void splitAllDocumentsToPages(String folderName) throws Exception + { + ArrayList fileNames = Directory.getFiles(folderName, "*.doc", SearchOption.TOP_DIRECTORY_ONLY) + .Where(item => item.EndsWith(".doc")).ToList(); + + for (String fileName : fileNames) + { + splitDocumentToPages(fileName); + } + } +} + +/// +/// Splits a document into multiple documents, one per page. +/// +class DocumentPageSplitter +{ + private /*final*/ PageNumberFinder pageNumberFinder; + + /// + /// Initializes a new instance of the class. + /// This method splits the document into sections so that each page begins and ends at a section boundary. + /// It is recommended not to modify the document afterwards. + /// + /// Source document + public DocumentPageSplitter(Document source) throws Exception + { + pageNumberFinder = PageNumberFinderFactory.create(source); + } + + /// + /// Gets the document this instance works with. + /// + private Document Document => private pageNumberFinder.DocumentpageNumberFinder; + + /// + /// Gets the document of a page. + /// + /// + /// 1-based index of a page. + /// + /// + /// The . + /// + public Document getDocumentOfPage(int pageIndex) + { + return getDocumentOfPageRange(pageIndex, pageIndex); + } + + /// + /// Gets the document of a page range. + /// + /// + /// 1-based index of the start page. + /// + /// + /// 1-based index of the end page. + /// + /// + /// The . + /// + public Document getDocumentOfPageRange(int startIndex, int endIndex) + { + Document result = (Document) Document.deepClone(false); + for (Node section : pageNumberFinder.RetrieveAllNodesOnPages(startIndex, endIndex, + NodeType.SECTION) !!Autoporter error: Undefined expression type ) + { + result.appendChild(result.importNode(section, true)); + } + + return result; + } +} + +/// +/// Provides methods for extracting nodes of a document which are rendered on a specified pages. +/// +public class PageNumberFinder +{ + // Maps node to a start/end page numbers. + // This is used to override baseline page numbers provided by the collector when the document is split. + private /*final*/ Map nodeStartPageLookup = new HashMap(); + private /*final*/ Map nodeEndPageLookup = new HashMap(); + private /*final*/ LayoutCollector collector; + + // Maps page number to a list of nodes found on that page. + private Map> reversePageLookup; + + /// + /// Initializes a new instance of the class. + /// + /// A collector instance that has layout model records for the document. + public PageNumberFinder(LayoutCollector collector) + { + this.collector = collector; + } + + /// + /// Gets the document this instance works with. + /// + public Document Document => private collector.Documentcollector; + + /// + /// Retrieves 1-based index of a page that the node begins on. + /// + /// + /// The node. + /// + /// + /// Page index. + /// + public int getPage(Node node) + { + return nodeStartPageLookup.containsKey(node) + ? nodeStartPageLookup.get(node) + : collector.GetStartPageIndex(node); + } + + /// + /// Retrieves 1-based index of a page that the node ends on. + /// + /// + /// The node. + /// + /// + /// Page index. + /// + public int getPageEnd(Node node) + { + return nodeEndPageLookup.containsKey(node) + ? nodeEndPageLookup.get(node) + : collector.GetEndPageIndex(node); + } + + /// + /// Returns how many pages the specified node spans over. Returns 1 if the node is contained within one page. + /// + /// + /// The node. + /// + /// + /// Page index. + /// + public int pageSpan(Node node) + { + return getPageEnd(node) - getPage(node) + 1; + } + + /// + /// Returns a list of nodes that are contained anywhere on the specified page or pages which match the specified node type. + /// + /// + /// The start Page. + /// + /// + /// The end Page. + /// + /// + /// The node Type. + /// + /// + /// The . + /// + public ArrayList retrieveAllNodesOnPages(int startPage, int endPage, /*NodeType*/int nodeType) throws Exception + { + if (startPage < 1 || startPage > Document.getPageCount()) + { + throw new IllegalStateException("'startPage' is out of range"); + } + + if (endPage < 1 || endPage > Document.getPageCount() || endPage < startPage) + { + throw new IllegalStateException("'endPage' is out of range"); + } + + checkPageListsPopulated(); + + ArrayList pageNodes = new ArrayList(); + for (int page = startPage; page <= endPage; page++) + { + // Some pages can be empty. + if (!reversePageLookup.containsKey(page)) + { + continue; + } + + for (Node node : reversePageLookup.get(page)) + { + if (node.getParentNode() != null + && (nodeType == NodeType.ANY || node.getNodeType() == nodeType) + && !pageNodes.contains(node)) + { + pageNodes.add(node); + } + } + } + + return pageNodes; + } + + /// + /// Splits nodes that appear over two or more pages into separate nodes so that they still appear in the same way + /// but no longer appear across a page. + /// + public void splitNodesAcrossPages() throws Exception + { + for (Paragraph paragraph : (Iterable) Document.getChildNodes(NodeType.PARAGRAPH, true)) + { + if (getPage(paragraph) != getPageEnd(paragraph)) + { + splitRunsByWords(paragraph); + } + } + + clearCollector(); + + // Visit any composites which are possibly split across pages and split them into separate nodes. + Document.accept(new SectionSplitter(this)); + } + + /// + /// This is called by to update page numbers of split nodes. + /// + /// + /// The node. + /// + /// + /// The start Page. + /// + /// + /// The end Page. + /// + void addPageNumbersForNode(Node node, int startPage, int endPage) + { + if (startPage > 0) + { + nodeStartPageLookup.put(node, startPage); + } + + if (endPage > 0) + { + nodeEndPageLookup.put(node, endPage); + } + } + + private boolean isHeaderFooterType(Node node) + { + return node.getNodeType() == NodeType.HEADER_FOOTER || node.getAncestor(NodeType.HEADER_FOOTER) != null; + } + + private void checkPageListsPopulated() + { + if (reversePageLookup != null) + { + return; + } + + reversePageLookup = new HashMap>(); + + // Add each node to a list that represent the nodes found on each page. + for (Node node : (Iterable) Document.getChildNodes(NodeType.ANY, true)) + { + // Headers/Footers follow sections and are not split by themselves. + if (isHeaderFooterType(node)) + { + continue; + } + + int startPage = getPage(node); + int endPage = getPageEnd(node); + for (int page = startPage; page <= endPage; page++) + { + if (!reversePageLookup.containsKey(page)) + { + msDictionary.add(reversePageLookup, page, new ArrayList()); + } + + reversePageLookup.get(page).add(node); + } + } + } + + private void splitRunsByWords(Paragraph paragraph) + { + for (Run run : (Iterable) paragraph.getRuns()) + { + if (getPage(run) == getPageEnd(run)) + { + continue; + } + + splitRunByWords(run); + } + } + + private void splitRunByWords(Run run) + { + Iterable words = msString.split(run.getText(), ' ').Reverse(); + + for (String word : words) + { + int pos = run.getText().length() - word.length() - 1; + if (pos > 1) + { + splitRun(run, run.getText().length() - word.length() - 1); + } + } + } + + /// + /// Splits text of the specified run into two runs. + /// Inserts the new run just after the specified run. + /// + private void splitRun(Run run, int position) + { + Run afterRun = (Run) run.deepClone(true); + afterRun.setText(run.getText().substring(position)); + run.setText(run.getText().substring((0), (0) + (position))); + run.getParentNode().insertAfter(afterRun, run); + } + + private void clearCollector() throws Exception + { + collector.Clear(); + Document.updatePageLayout(); + + nodeStartPageLookup.clear(); + nodeEndPageLookup.clear(); + } +} + +class PageNumberFinderFactory +{ + public static PageNumberFinder create(Document document) throws Exception + { + LayoutCollector layoutCollector = new LayoutCollector(document); + document.updatePageLayout(); + PageNumberFinder pageNumberFinder = new PageNumberFinder(layoutCollector); + pageNumberFinder.splitNodesAcrossPages(); + return pageNumberFinder; + } +} + +/// +/// Splits a document into multiple sections so that each page begins and ends at a section boundary. +/// +class SectionSplitter extends DocumentVisitor +{ + private /*final*/ PageNumberFinder pageNumberFinder; + + public SectionSplitter(PageNumberFinder pageNumberFinder) + { + this.pageNumberFinder = pageNumberFinder; + } + + public /*override*/ /*VisitorAction*/int visitParagraphStart(Paragraph paragraph) + { + return continueIfCompositeAcrossPageElseSkip(paragraph); + } + + public /*override*/ /*VisitorAction*/int visitTableStart(Table table) + { + return continueIfCompositeAcrossPageElseSkip(table); + } + + public /*override*/ /*VisitorAction*/int visitRowStart(Row row) + { + return continueIfCompositeAcrossPageElseSkip(row); + } + + public /*override*/ /*VisitorAction*/int visitCellStart(Cell cell) + { + return continueIfCompositeAcrossPageElseSkip(cell); + } + + public /*override*/ /*VisitorAction*/int visitStructuredDocumentTagStart(StructuredDocumentTag sdt) + { + return continueIfCompositeAcrossPageElseSkip(sdt); + } + + public /*override*/ /*VisitorAction*/int visitSmartTagStart(SmartTag smartTag) + { + return continueIfCompositeAcrossPageElseSkip(smartTag); + } + + public /*override*/ /*VisitorAction*/int visitSectionStart(Section section) + { + Section previousSection = (Section) section.getPreviousSibling(); + + // If there is a previous section, attempt to copy any linked header footers. + // Otherwise, they will not appear in an extracted document if the previous section is missing. + if (previousSection != null) + { + HeaderFooterCollection previousHeaderFooters = previousSection.getHeadersFooters(); + if (!section.getPageSetup().getRestartPageNumbering()) + { + section.getPageSetup().setRestartPageNumbering(true); + section.getPageSetup().setPageStartingNumber(previousSection.getPageSetup().getPageStartingNumber() + + pageNumberFinder.pageSpan(previousSection)); + } + + for (HeaderFooter previousHeaderFooter : (Iterable) previousHeaderFooters) + { + if (section.getHeadersFooters().getByHeaderFooterType(previousHeaderFooter.getHeaderFooterType()) == null) + { + HeaderFooter newHeaderFooter = + (HeaderFooter) previousHeaderFooters.getByHeaderFooterType(previousHeaderFooter.getHeaderFooterType()).deepClone(true); + section.getHeadersFooters().add(newHeaderFooter); + } + } + } + + return continueIfCompositeAcrossPageElseSkip(section); + } + + public /*override*/ /*VisitorAction*/int visitSmartTagEnd(SmartTag smartTag) + { + splitComposite(smartTag); + return VisitorAction.CONTINUE; + } + + public /*override*/ /*VisitorAction*/int visitStructuredDocumentTagEnd(StructuredDocumentTag sdt) + { + splitComposite(sdt); + return VisitorAction.CONTINUE; + } + + public /*override*/ /*VisitorAction*/int visitCellEnd(Cell cell) + { + splitComposite(cell); + return VisitorAction.CONTINUE; + } + + public /*override*/ /*VisitorAction*/int visitRowEnd(Row row) + { + splitComposite(row); + return VisitorAction.CONTINUE; + } + + public /*override*/ /*VisitorAction*/int visitTableEnd(Table table) + { + splitComposite(table); + return VisitorAction.CONTINUE; + } + + public /*override*/ /*VisitorAction*/int visitParagraphEnd(Paragraph paragraph) + { + // If the paragraph contains only section break, add fake run into. + if (paragraph.isEndOfSection() && paragraph.getChildNodes(NodeType.ANY, false).getCount() == 1 && + "\f".equals(paragraph.getChildNodes(NodeType.ANY, false).get(0).getText())) + { + Run run = new Run(paragraph.getDocument()); + paragraph.appendChild(run); + int currentEndPageNum = pageNumberFinder.getPageEnd(paragraph); + pageNumberFinder.addPageNumbersForNode(run, currentEndPageNum, currentEndPageNum); + } + + for (Paragraph clonePara : (Iterable) splitComposite(paragraph)) + { + // Remove list numbering from the cloned paragraph but leave the indent the same + // as the paragraph is supposed to be part of the item before. + if (paragraph.isListItem()) + { + double textPosition = clonePara.getListFormat().getListLevel().getTextPosition(); + clonePara.getListFormat().removeNumbers(); + clonePara.getParagraphFormat().setLeftIndent(textPosition); + } + + // Reset spacing of split paragraphs in tables as additional spacing may cause them to look different. + if (paragraph.isInCell()) + { + clonePara.getParagraphFormat().setSpaceBefore(0.0); + paragraph.getParagraphFormat().setSpaceAfter(0.0); + } + } + + return VisitorAction.CONTINUE; + } + + public /*override*/ /*VisitorAction*/int visitSectionEnd(Section section) + { + for (Section cloneSection : (Iterable
          ) splitComposite(section)) + { + cloneSection.getPageSetup().setSectionStart(SectionStart.NEW_PAGE); + cloneSection.getPageSetup().setRestartPageNumbering(true); + cloneSection.getPageSetup().setPageStartingNumber(section.getPageSetup().getPageStartingNumber() + + (section.getDocument().indexOf(cloneSection) - + section.getDocument().indexOf(section))); + cloneSection.getPageSetup().setDifferentFirstPageHeaderFooter(false); + + // Corrects page break at the end of the section. + SplitPageBreakCorrector.processSection(cloneSection); + } + + SplitPageBreakCorrector.processSection(section); + + // Add new page numbering for the body of the section as well. + pageNumberFinder.addPageNumbersForNode(section.getBody(), pageNumberFinder.getPage(section), + pageNumberFinder.getPageEnd(section)); + return VisitorAction.CONTINUE; + } + + private /*VisitorAction*/int continueIfCompositeAcrossPageElseSkip(CompositeNode composite) + { + return pageNumberFinder.pageSpan(composite) > 1 + ? VisitorAction.CONTINUE + : VisitorAction.SKIP_THIS_NODE; + } + + private ArrayList splitComposite(CompositeNode composite) + { + ArrayList splitNodes = new ArrayList(); + for (Node splitNode : findChildSplitPositions(composite)) + { + splitNodes.add(splitCompositeAtNode(composite, splitNode)); + } + + return splitNodes; + } + + private Iterable findChildSplitPositions(CompositeNode node) + { + // A node may span across multiple pages, so a list of split positions is returned. + // The split node is the first node on the next page. + ArrayList splitList = new ArrayList(); + + int startingPage = pageNumberFinder.getPage(node); + + Node[] childNodes = node.getNodeType() == NodeType.SECTION + ? ((Section) node).getBody().getChildNodes(NodeType.ANY, false).toArray() + : node.getChildNodes(NodeType.ANY, false).toArray(); + for (Node childNode : childNodes) + { + int pageNum = pageNumberFinder.getPage(childNode); + + if (childNode instanceof Run) + { + pageNum = pageNumberFinder.getPageEnd(childNode); + } + + // If the page of the child node has changed, then this is the split position. + // Add this to the list. + if (pageNum > startingPage) + { + splitList.add(childNode); + startingPage = pageNum; + } + + if (pageNumberFinder.pageSpan(childNode) > 1) + { + pageNumberFinder.addPageNumbersForNode(childNode, pageNum, pageNum); + } + } + + // Split composites backward, so the cloned nodes are inserted in the right order. + Collections.reverse(splitList); + return splitList; + } + + private CompositeNode splitCompositeAtNode(CompositeNode baseNode, Node targetNode) + { + CompositeNode cloneNode = (CompositeNode) baseNode.deepClone(false); + Node node = targetNode; + int currentPageNum = pageNumberFinder.getPage(baseNode); + + // Move all nodes found on the next page into the copied node. Handle row nodes separately. + if (baseNode.getNodeType() != NodeType.ROW) + { + CompositeNode composite = cloneNode; + if (baseNode.getNodeType() == NodeType.SECTION) + { + cloneNode = (CompositeNode) baseNode.deepClone(true); + Section section = (Section) cloneNode; + section.getBody().removeAllChildren(); + composite = section.getBody(); + } + + while (node != null) + { + Node nextNode = node.getNextSibling(); + composite.appendChild(node); + node = nextNode; + } + } + else + { + // If we are dealing with a row, we need to add dummy cells for the cloned row. + int targetPageNum = pageNumberFinder.getPage(targetNode); + + Node[] childNodes = baseNode.getChildNodes(NodeType.ANY, false).toArray(); + for (Node childNode : childNodes) + { + int pageNum = pageNumberFinder.getPage(childNode); + if (pageNum == targetPageNum) + { + if (cloneNode.getNodeType() == NodeType.ROW) + ((Row) cloneNode).ensureMinimum(); + + if (cloneNode.getNodeType() == NodeType.CELL) + ((Cell) cloneNode).ensureMinimum(); + + cloneNode.getLastChild().remove(); + cloneNode.appendChild(childNode); + } + else if (pageNum == currentPageNum) + { + cloneNode.appendChild(childNode.deepClone(false)); + if (cloneNode.getLastChild().getNodeType() != NodeType.CELL) + { + ((CompositeNode) cloneNode.getLastChild()).appendChild( + ((CompositeNode) childNode).getFirstChild().deepClone(false)); + } + } + } + } + + // Insert the split node after the original. + baseNode.getParentNode().insertAfter(cloneNode, baseNode); + + // Update the new page numbers of the base node and the cloned node, including its descendants. + // This will only be a single page as the cloned composite is split to be on one page. + int currentEndPageNum = pageNumberFinder.getPageEnd(baseNode); + pageNumberFinder.addPageNumbersForNode(baseNode, currentPageNum, currentEndPageNum - 1); + pageNumberFinder.addPageNumbersForNode(cloneNode, currentEndPageNum, currentEndPageNum); + for (Node childNode : (Iterable) cloneNode.getChildNodes(NodeType.ANY, true)) + { + pageNumberFinder.addPageNumbersForNode(childNode, currentEndPageNum, currentEndPageNum); + } + + return cloneNode; + } +} + +class SplitPageBreakCorrector +{ + private static final String PAGE_BREAK_STR = "\f"; + private static final char PAGE_BREAK = '\f'; + + public static void processSection(Section section) + { + if (section.getChildNodes(NodeType.ANY, false).getCount() == 0) + { + return; + } + + Body lastBody = section.getChildNodes(NodeType.ANY, false).OfType().LastOrDefault(); + + Run run = lastBody?.GetChildNodes(NodeType.Run, true).OfType() + .FirstOrDefault(p => p.Text.EndsWith(PageBreakStr)); + + if (run != null) + { + removePageBreak(run); + } + } + + public void removePageBreakFromParagraph(Paragraph paragraph) + { + Run run = (Run) paragraph.getFirstChild(); + if (PAGE_BREAK_STR.equals(run.getText())) + { + paragraph.removeChild(run); + } + } + + private void processLastParagraph(Paragraph paragraph) + { + Node lastNode = paragraph.getChildNodes(NodeType.ANY, false).get(paragraph.getChildNodes(NodeType.ANY, false).getCount() - 1); + if (lastNode.getNodeType() != NodeType.RUN) + { + return; + } + + Run run = (Run) lastNode; + removePageBreak(run); + } + + private static void removePageBreak(Run run) + { + Paragraph paragraph = run.getParentParagraph(); + + if (PAGE_BREAK_STR.equals(run.getText())) + { + paragraph.removeChild(run); + } + else if (run.getText().endsWith(PAGE_BREAK_STR)) + { + run.setText(msString.trimEnd(run.getText(), PAGE_BREAK)); + } + + if (paragraph.getChildNodes(NodeType.ANY, false).getCount() == 0) + { + CompositeNode parent = paragraph.getParentNode(); + parent.removeChild(paragraph); + } + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Split_documents/SplitDocument.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Split_documents/SplitDocument.java new file mode 100644 index 00000000..92f11e3d --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Split_documents/SplitDocument.java @@ -0,0 +1,140 @@ +package DocsExamples.Programming_with_Documents.Split_Documents; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.HtmlSaveOptions; +import com.aspose.words.DocumentSplitCriteria; +import com.aspose.words.Section; +import com.aspose.ms.System.IO.Directory; +import com.aspose.ms.System.IO.SearchOption; +import com.aspose.words.DocumentBuilder; +import com.aspose.ms.System.msString; +import com.aspose.words.ImportFormatMode; + + +class SplitDocument extends DocsExamplesBase +{ + @Test + public void byHeadings() throws Exception + { + //ExStart:SplitDocumentByHeadings + //GistId:c0df00d37081f41a7683339fd7ef66c1 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + HtmlSaveOptions options = new HtmlSaveOptions(); + { + // Split a document into smaller parts, in this instance split by heading. + options.setDocumentSplitCriteria(DocumentSplitCriteria.HEADING_PARAGRAPH); + } + + doc.save(getArtifactsDir() + "SplitDocument.ByHeadings.epub", options); + //ExEnd:SplitDocumentByHeadings + } + + @Test + public void bySectionsHtml() throws Exception + { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + //ExStart:SplitDocumentBySectionsHtml + //GistId:6759a1a6b7f448798751d54922a8efcb + HtmlSaveOptions options = new HtmlSaveOptions(); { options.setDocumentSplitCriteria(DocumentSplitCriteria.SECTION_BREAK); } + //ExEnd:SplitDocumentBySectionsHtml + + doc.save(getArtifactsDir() + "SplitDocument.BySections.html", options); + } + + @Test + public void bySections() throws Exception + { + //ExStart:SplitDocumentBySections + //GistId:6759a1a6b7f448798751d54922a8efcb + Document doc = new Document(getMyDir() + "Big document.docx"); + + for (int i = 0; i < doc.getSections().getCount(); i++) + { + // Split a document into smaller parts, in this instance, split by section. + Section section = doc.getSections().get(i).deepClone(); + + Document newDoc = new Document(); + newDoc.getSections().clear(); + + Section newSection = (Section) newDoc.importNode(section, true); + newDoc.getSections().add(newSection); + + // Save each section as a separate document. + newDoc.save(getArtifactsDir() + $"SplitDocument.BySections_{i}.docx"); + } + //ExEnd:SplitDocumentBySections + } + + @Test + public void pageByPage() throws Exception + { + //ExStart:SplitDocumentPageByPage + //GistId:6759a1a6b7f448798751d54922a8efcb + Document doc = new Document(getMyDir() + "Big document.docx"); + + int pageCount = doc.getPageCount(); + + for (int page = 0; page < pageCount; page++) + { + // Save each page as a separate document. + Document extractedPage = doc.extractPages(page, 1); + extractedPage.save(getArtifactsDir() + $"SplitDocument.PageByPage_{page + 1}.docx"); + } + //ExEnd:SplitDocumentPageByPage + + mergeDocuments(); + } + + //ExStart:MergeSplitDocuments + //GistId:6759a1a6b7f448798751d54922a8efcb + private void mergeDocuments() throws Exception + { + // Find documents using for merge. + FileSystemInfo[] documentPaths = new DirectoryInfo(getArtifactsDir()) + .GetFileSystemInfos("SplitDocument.PageByPage_*.docx").OrderBy(f => f.CreationTime).ToArray(); + String sourceDocumentPath = + Directory.getFiles(getArtifactsDir(), "SplitDocument.PageByPage_1.docx", SearchOption.TOP_DIRECTORY_ONLY)[0]; + + // Open the first part of the resulting document. + Document sourceDoc = new Document(sourceDocumentPath); + + // Create a new resulting document. + Document mergedDoc = new Document(); + DocumentBuilder mergedDocBuilder = new DocumentBuilder(mergedDoc); + + // Merge document parts one by one. + for (FileSystemInfo documentPath : documentPaths) + { + if (msString.equals(documentPath.getFullName(), sourceDocumentPath)) + continue; + + mergedDocBuilder.moveToDocumentEnd(); + mergedDocBuilder.insertDocument(sourceDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + sourceDoc = new Document(documentPath.getFullName()); + } + + mergedDoc.save(getArtifactsDir() + "SplitDocument.MergeDocuments.docx"); + } + //ExEnd:MergeSplitDocuments + + @Test + public void byPageRange() throws Exception + { + //ExStart:SplitDocumentByPageRange + //GistId:6759a1a6b7f448798751d54922a8efcb + Document doc = new Document(getMyDir() + "Big document.docx"); + + // Get part of the document. + Document extractedPages = doc.extractPages(3, 6); + extractedPages.save(getArtifactsDir() + "SplitDocument.ByPageRange.docx"); + //ExEnd:SplitDocumentByPageRange + } +} + + diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Split_documents/SplitIntoHtmlPages.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Split_documents/SplitIntoHtmlPages.java new file mode 100644 index 00000000..6434c5cc --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Split_documents/SplitIntoHtmlPages.java @@ -0,0 +1,296 @@ +package DocsExamples.Programming_with_Documents.Split_Documents; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.ms.System.IO.Path; +import com.aspose.ms.System.IO.Directory; +import com.aspose.words.Document; +import java.util.ArrayList; +import com.aspose.words.Paragraph; +import com.aspose.words.NodeCollection; +import com.aspose.words.NodeType; +import com.aspose.words.StyleIdentifier; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.Section; +import com.aspose.words.BreakType; +import com.aspose.words.ImportFormatMode; +import com.aspose.words.HtmlSaveOptions; +import com.aspose.words.ExportHeadersFootersMode; +import com.aspose.words.IFieldMergingCallback; +import com.aspose.words.FieldMergingArgs; +import com.aspose.words.ImageFieldMergingArgs; +import com.aspose.words.IMailMergeDataSource; +import com.aspose.words.ref.Ref; + + +class SplitIntoHtmlPages extends DocsExamplesBase +{ + @Test + public void htmlPages() throws Exception + { + String srcFileName = getMyDir() + "Footnotes and endnotes.docx"; + String tocTemplate = getMyDir() + "Table of content template.docx"; + + String outDir = Path.combine(getArtifactsDir(), "HtmlPages"); + Directory.createDirectory(outDir); + + WordToHtmlConverter w = new WordToHtmlConverter(); + w.execute(srcFileName, tocTemplate, outDir); + } +} + +class WordToHtmlConverter +{ + /// + /// Performs the Word to HTML conversion. + /// + /// The MS Word file to convert. + /// An MS Word file that is used as a template to build a table of contents. + /// This file needs to have a mail merge region called "TOC" defined and one mail merge field called "TocEntry". + /// The output directory where to write HTML files. + void execute(String srcFileName, String tocTemplate, String dstDir) throws Exception + { + mDoc = new Document(srcFileName); + mTocTemplate = tocTemplate; + mDstDir = dstDir; + + ArrayList topicStartParas = selectTopicStarts(); + insertSectionBreaks(topicStartParas); + ArrayList topics = saveHtmlTopics(); + saveTableOfContents(topics); + } + + /// + /// Selects heading paragraphs that must become topic starts. + /// We can't modify them in this loop, so we need to remember them in an array first. + /// + private ArrayList selectTopicStarts() + { + NodeCollection paras = mDoc.getChildNodes(NodeType.PARAGRAPH, true); + ArrayList topicStartParas = new ArrayList(); + + for (Paragraph para : (Iterable) paras) + { + /*StyleIdentifier*/int style = para.getParagraphFormat().getStyleIdentifier(); + if (style == StyleIdentifier.HEADING_1) + topicStartParas.add(para); + } + + return topicStartParas; + } + + //ExStart:InsertSectionBreaks + //GistId:1afca4d3da7cb4240fb91c3d93d8c30d + /// + /// Insert section breaks before the specified paragraphs. + /// + private void insertSectionBreaks(ArrayList topicStartParas) + { + DocumentBuilder builder = new DocumentBuilder(mDoc); + for (Paragraph para : topicStartParas) + { + Section section = para.getParentSection(); + + // Insert section break if the paragraph is not at the beginning of a section already. + if (para != section.getBody().getFirstParagraph()) + { + builder.moveTo(para.getFirstChild()); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + + // This is the paragraph that was inserted at the end of the now old section. + // We don't really need the extra paragraph, we just needed the section. + section.getBody().getLastParagraph().remove(); + } + } + } + //ExEnd:InsertSectionBreaks + + /// + /// Splits the current document into one topic per section and saves each topic + /// as an HTML file. Returns a collection of Topic objects. + /// + private ArrayList saveHtmlTopics() throws Exception + { + ArrayList topics = new ArrayList(); + for (int sectionIdx = 0; sectionIdx < mDoc.getSections().getCount(); sectionIdx++) + { + Section section = mDoc.getSections().get(sectionIdx); + + String paraText = section.getBody().getFirstParagraph().getText(); + + // Use the text of the heading paragraph to generate the HTML file name. + String fileName = makeTopicFileName(paraText); + if ("".equals(fileName)) + fileName = "UNTITLED SECTION " + sectionIdx; + + fileName = Path.combine(mDstDir, fileName + ".html"); + + // Use the text of the heading paragraph to generate the title for the TOC. + String title = makeTopicTitle(paraText); + if ("".equals(title)) + title = "UNTITLED SECTION " + sectionIdx; + + Topic topic = new Topic(title, fileName); + topics.add(topic); + + saveHtmlTopic(section, topic); + } + + return topics; + } + + /// + /// Leaves alphanumeric characters, replaces white space with underscore + /// And removes all other characters from a string. + /// + private String makeTopicFileName(String paraText) + { + StringBuilder b = new StringBuilder(); + for (int i = 0; i < paraText.length(); i++) + { + char c = paraText.charAt(i); + if (Character.isLetterOrDigit(c)) + b.append(c); + else if (c == ' ') + b.append('_'); + } + + return b.toString(); + } + + /// + /// Removes the last character (which is a paragraph break character from the given string). + /// + private String makeTopicTitle(String paraText) + { + return paraText.substring((0), (0) + (paraText.length() - 1)); + } + + /// + /// Saves one section of a document as an HTML file. + /// Any embedded images are saved as separate files in the same folder as the HTML file. + /// + private void saveHtmlTopic(Section section, Topic topic) throws Exception + { + Document dummyDoc = new Document(); + dummyDoc.removeAllChildren(); + dummyDoc.appendChild(dummyDoc.importNode(section, true, ImportFormatMode.KEEP_SOURCE_FORMATTING)); + + dummyDoc.getBuiltInDocumentProperties().setTitle(topic.getTitle()); + + HtmlSaveOptions saveOptions = new HtmlSaveOptions(); + { + saveOptions.setPrettyFormat(true); + saveOptions.setAllowNegativeIndent(true); // This is to allow headings to appear to the left of the main text. + saveOptions.setExportHeadersFootersMode(ExportHeadersFootersMode.NONE); + } + + dummyDoc.save(topic.getFileName(), saveOptions); + } + + /// + /// Generates a table of contents for the topics and saves to contents .html. + /// + private void saveTableOfContents(ArrayList topics) throws Exception + { + Document tocDoc = new Document(mTocTemplate); + + // We use a custom mail merge event handler defined below, + // and a custom mail merge data source based on collecting the topics we created. + tocDoc.getMailMerge().setFieldMergingCallback(new HandleTocMergeField()); + tocDoc.getMailMerge().executeWithRegions(new TocMailMergeDataSource(topics)); + + tocDoc.save(Path.combine(mDstDir, "contents.html")); + } + + private static class HandleTocMergeField implements IFieldMergingCallback + { + public void /*IFieldMergingCallback.*/fieldMerging(FieldMergingArgs e) throws Exception + { + if (mBuilder == null) + mBuilder = new DocumentBuilder(e.getDocument()); + + // Our custom data source returns topic objects. + Topic topic = (Topic) e.getFieldValue(); + + mBuilder.moveToMergeField(e.getFieldName()); + mBuilder.insertHyperlink(topic.getTitle(), topic.getFileName(), false); + + // Signal to the mail merge engine that it does not need to insert text into the field. + e.setText(""); + } + + public void /*IFieldMergingCallback.*/imageFieldMerging(ImageFieldMergingArgs args) + { + // Do nothing. + } + + private DocumentBuilder mBuilder; + } + + private Document mDoc; + private String mTocTemplate; + private String mDstDir; +} + +class Topic +{ + Topic(String title, String fileName) + { + mTitle = title; + mFileName = fileName; + } + + String getTitle() { return mTitle; }; + + private String mTitle; + + String getFileName() { return mFileName; }; + + private String mFileName; +} + +class TocMailMergeDataSource implements IMailMergeDataSource +{ + TocMailMergeDataSource(ArrayList topics) + { + mTopics = topics; + mIndex = -1; + } + + public boolean moveNext() + { + if (mIndex < mTopics.size() - 1) + { + mIndex++; + return true; + } + + return false; + } + + public boolean getValue(String fieldName, /*out*/Ref fieldValue) + { + if ("TocEntry".equals(fieldName)) + { + // The template document is supposed to have only one field called "TocEntry". + fieldValue.set(mTopics.get(mIndex)); + return true; + } + + fieldValue.set(null); + return false; + } + + public String TableName => "TOC"; + + public IMailMergeDataSource getChildDataSource(String tableName) + { + return null; + } + + private /*final*/ ArrayList mTopics; + private int mIndex; +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithComments.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithComments.java new file mode 100644 index 00000000..97a3013d --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithComments.java @@ -0,0 +1,233 @@ +package DocsExamples.Programming_with_Documents; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.Comment; +import com.aspose.ms.System.DateTime; +import com.aspose.words.Paragraph; +import com.aspose.words.Run; +import com.aspose.words.CommentRangeStart; +import com.aspose.words.CommentRangeEnd; +import com.aspose.words.NodeType; +import com.aspose.ms.System.msConsole; +import java.util.ArrayList; +import com.aspose.words.NodeCollection; +import com.aspose.words.SaveFormat; +import com.aspose.ms.System.msString; +import com.aspose.words.Node; + + +class WorkingWithComments extends DocsExamplesBase +{ + @Test + public void addComments() throws Exception + { + //ExStart:AddComments + //GistId:70902b20df8b1f6b0459f676e21623bb + //ExStart:CreateSimpleDocumentUsingDocumentBuilder + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Some text is added."); + //ExEnd:CreateSimpleDocumentUsingDocumentBuilder + + Comment comment = new Comment(doc, "Awais Hafeez", "AH", DateTime.getToday()); + comment.setText("Comment text."); + + builder.getCurrentParagraph().appendChild(comment); + + doc.save(getArtifactsDir() + "WorkingWithComments.AddComments.docx"); + //ExEnd:AddComments + } + + @Test + public void anchorComment() throws Exception + { + //ExStart:AnchorComment + //GistId:70902b20df8b1f6b0459f676e21623bb + Document doc = new Document(); + + Paragraph para1 = new Paragraph(doc); + Run run1 = new Run(doc, "Some "); + Run run2 = new Run(doc, "text "); + para1.appendChild(run1); + para1.appendChild(run2); + doc.getFirstSection().getBody().appendChild(para1); + + Paragraph para2 = new Paragraph(doc); + Run run3 = new Run(doc, "is "); + Run run4 = new Run(doc, "added "); + para2.appendChild(run3); + para2.appendChild(run4); + doc.getFirstSection().getBody().appendChild(para2); + + Comment comment = new Comment(doc, "Awais Hafeez", "AH", DateTime.getToday()); + comment.getParagraphs().add(new Paragraph(doc)); + comment.getFirstParagraph().getRuns().add(new Run(doc, "Comment text.")); + + CommentRangeStart commentRangeStart = new CommentRangeStart(doc, comment.getId()); + CommentRangeEnd commentRangeEnd = new CommentRangeEnd(doc, comment.getId()); + + run1.getParentNode().insertAfter(commentRangeStart, run1); + run3.getParentNode().insertAfter(commentRangeEnd, run3); + commentRangeEnd.getParentNode().insertAfter(comment, commentRangeEnd); + + doc.save(getArtifactsDir() + "WorkingWithComments.AnchorComment.doc"); + //ExEnd:AnchorComment + } + + @Test + public void addRemoveCommentReply() throws Exception + { + //ExStart:AddRemoveCommentReply + //GistId:70902b20df8b1f6b0459f676e21623bb + Document doc = new Document(getMyDir() + "Comments.docx"); + + Comment comment = (Comment) doc.getChild(NodeType.COMMENT, 0, true); + comment.removeReply(comment.getReplies().get(0)); + + comment.addReplyInternal("John Doe", "JD", new DateTime(2017, 9, 25, 12, 15, 0), "New reply"); + + doc.save(getArtifactsDir() + "WorkingWithComments.AddRemoveCommentReply.docx"); + //ExEnd:AddRemoveCommentReply + } + + @Test + public void processComments() throws Exception + { + //ExStart:ProcessComments + //GistId:70902b20df8b1f6b0459f676e21623bb + Document doc = new Document(getMyDir() + "Comments.docx"); + + // Extract the information about the comments of all the authors. + for (String comment : extractComments(doc)) + msConsole.write(comment); + + // Remove comments by the "pm" author. + removeComments(doc, "pm"); + System.out.println("Comments from \"pm\" are removed!"); + + // Extract the information about the comments of the "ks" author. + for (String comment : extractComments(doc, "ks")) + msConsole.write(comment); + + // Read the comment's reply and resolve them. + commentResolvedAndReplies(doc); + + // Remove all comments. + removeComments(doc); + System.out.println("All comments are removed!"); + + doc.save(getArtifactsDir() + "WorkingWithComments.ProcessComments.docx"); + //ExEnd:ProcessComments + } + + //ExStart:ExtractComments + //GistId:70902b20df8b1f6b0459f676e21623bb + private ArrayList extractComments(Document doc) throws Exception + { + ArrayList collectedComments = new ArrayList(); + NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true); + + for (Comment comment : (Iterable) comments) + { + collectedComments.add(comment.getAuthor() + " " + comment.getDateTimeInternal() + " " + + comment.toString(SaveFormat.TEXT)); + } + + return collectedComments; + } + //ExEnd:ExtractComments + + //ExStart:ExtractCommentsByAuthor + //GistId:70902b20df8b1f6b0459f676e21623bb + private ArrayList extractComments(Document doc, String authorName) throws Exception + { + ArrayList collectedComments = new ArrayList(); + NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true); + + for (Comment comment : (Iterable) comments) + { + if (msString.equals(comment.getAuthor(), authorName)) + collectedComments.add(comment.getAuthor() + " " + comment.getDateTimeInternal() + " " + + comment.toString(SaveFormat.TEXT)); + } + + return collectedComments; + } + //ExEnd:ExtractCommentsByAuthor + + //ExStart:RemoveComments + //GistId:70902b20df8b1f6b0459f676e21623bb + private void removeComments(Document doc) + { + NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true); + comments.clear(); + } + //ExEnd:RemoveComments + + //ExStart:RemoveCommentsByAuthor + //GistId:70902b20df8b1f6b0459f676e21623bb + private void removeComments(Document doc, String authorName) + { + NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true); + + // Look through all comments and remove those written by the authorName. + for (int i = comments.getCount() - 1; i >= 0; i--) + { + Comment comment = (Comment) comments.get(i); + if (msString.equals(comment.getAuthor(), authorName)) + comment.remove(); + } + } + //ExEnd:RemoveCommentsByAuthor + + //ExStart:CommentResolvedAndReplies + //GistId:70902b20df8b1f6b0459f676e21623bb + private void commentResolvedAndReplies(Document doc) + { + NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true); + + Comment parentComment = (Comment) comments.get(0); + for (Comment childComment : (Iterable) parentComment.getReplies()) + { + // Get comment parent and status. + msConsole.writeLine(childComment.getAncestor().getId()); + msConsole.writeLine(childComment.getDone()); + + // And update comment Done mark. + childComment.setDone(true); + } + } + //ExEnd:CommentResolvedAndReplies + + @Test + public void removeRangeText() throws Exception + { + //ExStart:RemoveRangeText + //GistId:70902b20df8b1f6b0459f676e21623bb + Document doc = new Document(getMyDir() + "Comments.docx"); + + CommentRangeStart commentStart = (CommentRangeStart)doc.getChild(NodeType.COMMENT_RANGE_START, 0, true); + Node currentNode = commentStart; + + boolean isRemoving = true; + while (currentNode != null && isRemoving) + { + if (currentNode.getNodeType() == NodeType.COMMENT_RANGE_END) + isRemoving = false; + + Node nextNode = currentNode.nextPreOrder(doc); + currentNode.remove(); + currentNode = nextNode; + } + + doc.save(getArtifactsDir() + "WorkingWithComments.RemoveRangeText.docx"); + //ExEnd:RemoveRangeText + } +} + diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithFields.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithFields.java new file mode 100644 index 00000000..0f2f657a --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithFields.java @@ -0,0 +1,828 @@ +package DocsExamples.Programming_with_Documents; + +// ********* THIS FILE IS AUTO PORTED ********* + +import com.aspose.ms.java.collections.StringSwitchMap; +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.Field; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.FieldUpdateCultureSource; +import com.aspose.ms.System.DateTime; +import com.aspose.words.FieldType; +import com.aspose.words.FieldHyperlink; +import com.aspose.words.FieldMergeField; +import com.aspose.words.Paragraph; +import com.aspose.words.FieldTA; +import com.aspose.words.FieldToa; +import com.aspose.words.BreakType; +import com.aspose.words.HeaderFooterType; +import com.aspose.words.NodeType; +import com.aspose.words.FieldAddressBlock; +import com.aspose.words.FieldIncludeText; +import com.aspose.words.FieldUnknown; +import com.aspose.words.FieldBuilder; +import com.aspose.words.FieldArgumentBuilder; +import com.aspose.words.FieldAuthor; +import com.aspose.words.FieldAsk; +import com.aspose.words.FieldAdvance; +import com.aspose.ms.System.msConsole; +import com.aspose.words.IFieldUpdateCultureProvider; +import com.aspose.ms.System.Globalization.msCultureInfo; +import com.aspose.ms.System.Globalization.msDateTimeFormatInfo; +import com.aspose.words.FieldIf; +import com.aspose.words.FieldIfComparisonResult; +import com.aspose.ms.System.Threading.CurrentThread; +import java.util.Date; +import com.aspose.words.CompositeNode; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.IFieldResultFormatter; +import com.aspose.ms.System.msString; +import java.text.MessageFormat; +import com.aspose.words.CalendarType; +import com.aspose.words.GeneralFormat; +import java.util.ArrayList; + + +class WorkingWithFields extends DocsExamplesBase +{ + @Test + public void fieldCode() throws Exception + { + //ExStart:FieldCode + //GistId:7c2b7b650a88375b1d438746f78f0d64 + Document doc = new Document(getMyDir() + "Hyperlinks.docx"); + + for (Field field : doc.getRange().getFields()) + { + String fieldCode = field.getFieldCode(); + String fieldResult = field.getResult(); + } + //ExEnd:FieldCode + } + + @Test + public void changeFieldUpdateCultureSource() throws Exception + { + //ExStart:ChangeFieldUpdateCultureSource + //GistId:9e90defe4a7bcafb004f73a2ef236986 + //ExStart:DocumentBuilderInsertField + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert content with German locale. + builder.getFont().setLocaleId(1031); + builder.insertField("MERGEFIELD Date1 \\@ \"dddd, d MMMM yyyy\""); + builder.write(" - "); + builder.insertField("MERGEFIELD Date2 \\@ \"dddd, d MMMM yyyy\""); + //ExEnd:DocumentBuilderInsertField + + // Shows how to specify where the culture used for date formatting during field update and mail merge is chosen from + // set the culture used during field update to the culture used by the field. + doc.getFieldOptions().setFieldUpdateCultureSource(FieldUpdateCultureSource.FIELD_CODE); + doc.getMailMerge().execute(new String[] { "Date2" }, new Object[] { new DateTime(2011, 1, 1) }); + + doc.save(getArtifactsDir() + "WorkingWithFields.ChangeFieldUpdateCultureSource.docx"); + //ExEnd:ChangeFieldUpdateCultureSource + } + + @Test + public void specifyLocaleAtFieldLevel() throws Exception + { + //ExStart:SpecifyLocaleAtFieldLevel + //GistId:1cf07762df56f15067d6aef90b14b3db + DocumentBuilder builder = new DocumentBuilder(); + + Field field = builder.insertField(FieldType.FIELD_DATE, true); + field.setLocaleId(1049); + + builder.getDocument().save(getArtifactsDir() + "WorkingWithFields.SpecifyLocaleAtFieldLevel.docx"); + //ExEnd:SpecifyLocaleAtFieldLevel + } + + @Test + public void replaceHyperlinks() throws Exception + { + //ExStart:ReplaceHyperlinks + //GistId:0213851d47551e83af42233f4d075cf6 + Document doc = new Document(getMyDir() + "Hyperlinks.docx"); + + for (Field field : doc.getRange().getFields()) + { + if (field.getType() == FieldType.FIELD_HYPERLINK) + { + FieldHyperlink hyperlink = (FieldHyperlink) field; + + // Some hyperlinks can be local (links to bookmarks inside the document), ignore these. + if (hyperlink.getSubAddress() != null) + continue; + + hyperlink.setAddress("http://www.aspose.com"); + hyperlink.setResult("Aspose - The .NET & Java Component Publisher"); + } + } + + doc.save(getArtifactsDir() + "WorkingWithFields.ReplaceHyperlinks.docx"); + //ExEnd:ReplaceHyperlinks + } + + @Test + public void renameMergeFields() throws Exception + { + //ExStart:RenameMergeFields + //GistId:bf0f8a6b40b69a5274ab3553315e147f + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField("MERGEFIELD MyMergeField1 \\* MERGEFORMAT"); + builder.insertField("MERGEFIELD MyMergeField2 \\* MERGEFORMAT"); + + for (Field f : doc.getRange().getFields()) + { + if (f.getType() == FieldType.FIELD_MERGE_FIELD) + { + FieldMergeField mergeField = (FieldMergeField)f; + mergeField.setFieldName(mergeField.getFieldName() + "_Renamed"); + mergeField.update(); + } + } + + doc.save(getArtifactsDir() + "WorkingWithFields.RenameMergeFields.docx"); + //ExEnd:RenameMergeFields + } + + @Test + public void removeField() throws Exception + { + //ExStart:RemoveField + //GistId:8c604665c1b97795df7a1e665f6b44ce + Document doc = new Document(getMyDir() + "Various fields.docx"); + + Field field = doc.getRange().getFields().get(0); + field.remove(); + //ExEnd:RemoveField + } + + @Test + public void unlinkFields() throws Exception + { + //ExStart:UnlinkFields + //GistId:f3592014d179ecb43905e37b2a68bc92 + Document doc = new Document(getMyDir() + "Various fields.docx"); + doc.unlinkFields(); + //ExEnd:UnlinkFields + } + + @Test + public void insertToaFieldWithoutDocumentBuilder() throws Exception + { + //ExStart:InsertToaFieldWithoutDocumentBuilder + //GistId:1cf07762df56f15067d6aef90b14b3db + Document doc = new Document(); + Paragraph para = new Paragraph(doc); + + // We want to insert TA and TOA fields like this: + // { TA \c 1 \l "Value 0" } + // { TOA \c 1 } + + FieldTA fieldTA = (FieldTA) para.appendField(FieldType.FIELD_TOA_ENTRY, false); + fieldTA.setEntryCategory("1"); + fieldTA.setLongCitation("Value 0"); + + doc.getFirstSection().getBody().appendChild(para); + + para = new Paragraph(doc); + + FieldToa fieldToa = (FieldToa) para.appendField(FieldType.FIELD_TOA, false); + fieldToa.setEntryCategory("1"); + doc.getFirstSection().getBody().appendChild(para); + + fieldToa.update(); + + doc.save(getArtifactsDir() + "WorkingWithFields.InsertToaFieldWithoutDocumentBuilder.docx"); + //ExEnd:InsertToaFieldWithoutDocumentBuilder + } + + @Test + public void insertNestedFields() throws Exception + { + //ExStart:InsertNestedFields + //GistId:1cf07762df56f15067d6aef90b14b3db + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + for (int i = 0; i < 5; i++) + builder.insertBreak(BreakType.PAGE_BREAK); + + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + + // We want to insert a field like this: + // { IF {PAGE} <> {NUMPAGES} "See Next Page" "Last Page" } + Field field = builder.insertField("IF "); + builder.moveTo(field.getSeparator()); + builder.insertField("PAGE"); + builder.write(" <> "); + builder.insertField("NUMPAGES"); + builder.write(" \"See Next Page\" \"Last Page\" "); + + field.update(); + + doc.save(getArtifactsDir() + "WorkingWithFields.InsertNestedFields.docx"); + //ExEnd:InsertNestedFields + } + + @Test + public void insertMergeFieldUsingDom() throws Exception + { + //ExStart:InsertMergeFieldUsingDom + //GistId:1cf07762df56f15067d6aef90b14b3db + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Paragraph para = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 0, true); + builder.moveTo(para); + + // We want to insert a merge field like this: + // { " MERGEFIELD Test1 \\b Test2 \\f Test3 \\m \\v" } + FieldMergeField field = (FieldMergeField) builder.insertField(FieldType.FIELD_MERGE_FIELD, false); + // { " MERGEFIELD Test1" } + field.setFieldName("Test1"); + // { " MERGEFIELD Test1 \\b Test2" } + field.setTextBefore("Test2"); + // { " MERGEFIELD Test1 \\b Test2 \\f Test3 } + field.setTextAfter("Test3"); + // { " MERGEFIELD Test1 \\b Test2 \\f Test3 \\m" } + field.isMapped(true); + // { " MERGEFIELD Test1 \\b Test2 \\f Test3 \\m \\v" } + field.isVerticalFormatting(true); + + field.update(); + + doc.save(getArtifactsDir() + "WorkingWithFields.InsertMergeFieldUsingDom.docx"); + //ExEnd:InsertMergeFieldUsingDom + } + + @Test + public void insertAddressBlockFieldUsingDom() throws Exception + { + //ExStart:InsertAddressBlockFieldUsingDom + //GistId:1cf07762df56f15067d6aef90b14b3db + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Paragraph para = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 0, true); + builder.moveTo(para); + + // We want to insert a mail merge address block like this: + // { ADDRESSBLOCK \\c 1 \\d \\e Test2 \\f Test3 \\l \"Test 4\" } + FieldAddressBlock field = (FieldAddressBlock) builder.insertField(FieldType.FIELD_ADDRESS_BLOCK, false); + // { ADDRESSBLOCK \\c 1" } + field.setIncludeCountryOrRegionName("1"); + // { ADDRESSBLOCK \\c 1 \\d" } + field.setFormatAddressOnCountryOrRegion(true); + // { ADDRESSBLOCK \\c 1 \\d \\e Test2 } + field.setExcludedCountryOrRegionName("Test2"); + // { ADDRESSBLOCK \\c 1 \\d \\e Test2 \\f Test3 } + field.setNameAndAddressFormat("Test3"); + // { ADDRESSBLOCK \\c 1 \\d \\e Test2 \\f Test3 \\l \"Test 4\" } + field.setLanguageId("Test 4"); + + field.update(); + + doc.save(getArtifactsDir() + "WorkingWithFields.InsertAddressBlockFieldUsingDom.docx"); + //ExEnd:InsertAddressBlockFieldUsingDom + } + + @Test + public void insertFieldIncludeTextWithoutDocumentBuilder() throws Exception + { + //ExStart:InsertFieldIncludeTextWithoutDocumentBuilder + //GistId:1cf07762df56f15067d6aef90b14b3db + Document doc = new Document(); + + Paragraph para = new Paragraph(doc); + + // We want to insert an INCLUDETEXT field like this: + // { INCLUDETEXT "file path" } + FieldIncludeText fieldIncludeText = (FieldIncludeText) para.appendField(FieldType.FIELD_INCLUDE_TEXT, false); + fieldIncludeText.setBookmarkName("bookmark"); + fieldIncludeText.setSourceFullName(getMyDir() + "IncludeText.docx"); + + doc.getFirstSection().getBody().appendChild(para); + + fieldIncludeText.update(); + + doc.save(getArtifactsDir() + "WorkingWithFields.InsertIncludeFieldWithoutDocumentBuilder.docx"); + //ExEnd:InsertFieldIncludeTextWithoutDocumentBuilder + } + + @Test + public void insertFieldNone() throws Exception + { + //ExStart:InsertFieldNone + //GistId:1cf07762df56f15067d6aef90b14b3db + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + FieldUnknown field = (FieldUnknown) builder.insertField(FieldType.FIELD_NONE, false); + + doc.save(getArtifactsDir() + "WorkingWithFields.InsertFieldNone.docx"); + //ExEnd:InsertFieldNone + } + + @Test + public void insertField() throws Exception + { + //ExStart:InsertField + //GistId:1cf07762df56f15067d6aef90b14b3db + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField("MERGEFIELD MyFieldName \\* MERGEFORMAT"); + + doc.save(getArtifactsDir() + "WorkingWithFields.InsertField.docx"); + //ExEnd:InsertField + } + + @Test + public void insertFieldUsingFieldBuilder() throws Exception + { + //ExStart:InsertFieldUsingFieldBuilder + //GistId:1cf07762df56f15067d6aef90b14b3db + Document doc = new Document(); + + // Prepare IF field with two nested MERGEFIELD fields: { IF "left expression" = "right expression" "Firstname: { MERGEFIELD firstname }" "Lastname: { MERGEFIELD lastname }"} + FieldBuilder fieldBuilder = new FieldBuilder(FieldType.FIELD_IF) + .addArgument("left expression") + .addArgument("=") + .addArgument("right expression") + .addArgument( + new FieldArgumentBuilder() + .addText("Firstname: ") + .addField(new FieldBuilder(FieldType.FIELD_MERGE_FIELD).addArgument("firstname"))) + .addArgument( + new FieldArgumentBuilder() + .addText("Lastname: ") + .addField(new FieldBuilder(FieldType.FIELD_MERGE_FIELD).addArgument("lastname"))); + + // Insert IF field in exact location + Field field = fieldBuilder.buildAndInsert(doc.getFirstSection().getBody().getFirstParagraph()); + field.update(); + + doc.save(getArtifactsDir() + "Field.InsertFieldUsingFieldBuilder.docx"); + //ExEnd:InsertFieldUsingFieldBuilder + } + + @Test + public void insertAuthorField() throws Exception + { + //ExStart:InsertAuthorField + //GistId:1cf07762df56f15067d6aef90b14b3db + Document doc = new Document(); + + Paragraph para = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 0, true); + + // We want to insert an AUTHOR field like this: + // { AUTHOR Test1 } + FieldAuthor field = (FieldAuthor) para.appendField(FieldType.FIELD_AUTHOR, false); + field.setAuthorName("Test1"); + + field.update(); + + doc.save(getArtifactsDir() + "WorkingWithFields.InsertAuthorField.docx"); + //ExEnd:InsertAuthorField + } + + @Test + public void insertAskFieldWithoutDocumentBuilder() throws Exception + { + //ExStart:InsertAskFieldWithoutDocumentBuilder + //GistId:1cf07762df56f15067d6aef90b14b3db + Document doc = new Document(); + + Paragraph para = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 0, true); + // We want to insert an Ask field like this: + // { ASK \"Test 1\" Test2 \\d Test3 \\o } + FieldAsk field = (FieldAsk) para.appendField(FieldType.FIELD_ASK, false); + // { ASK \"Test 1\" " } + field.setBookmarkName("Test 1"); + // { ASK \"Test 1\" Test2 } + field.setPromptText("Test2"); + // { ASK \"Test 1\" Test2 \\d Test3 } + field.setDefaultResponse("Test3"); + // { ASK \"Test 1\" Test2 \\d Test3 \\o } + field.setPromptOnceOnMailMerge(true); + + field.update(); + + doc.save(getArtifactsDir() + "WorkingWithFields.InsertAskFieldWithoutDocumentBuilder.docx"); + //ExEnd:InsertAskFieldWithoutDocumentBuilder + } + + @Test + public void insertAdvanceFieldWithoutDocumentBuilder() throws Exception + { + //ExStart:InsertAdvanceFieldWithoutDocumentBuilder + //GistId:1cf07762df56f15067d6aef90b14b3db + Document doc = new Document(); + + Paragraph para = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 0, true); + // We want to insert an Advance field like this: + // { ADVANCE \\d 10 \\l 10 \\r -3.3 \\u 0 \\x 100 \\y 100 } + FieldAdvance field = (FieldAdvance) para.appendField(FieldType.FIELD_ADVANCE, false); + // { ADVANCE \\d 10 " } + field.setDownOffset("10"); + // { ADVANCE \\d 10 \\l 10 } + field.setLeftOffset("10"); + // { ADVANCE \\d 10 \\l 10 \\r -3.3 } + field.setRightOffset("-3.3"); + // { ADVANCE \\d 10 \\l 10 \\r -3.3 \\u 0 } + field.setUpOffset("0"); + // { ADVANCE \\d 10 \\l 10 \\r -3.3 \\u 0 \\x 100 } + field.setHorizontalPosition("100"); + // { ADVANCE \\d 10 \\l 10 \\r -3.3 \\u 0 \\x 100 \\y 100 } + field.setVerticalPosition("100"); + + field.update(); + + doc.save(getArtifactsDir() + "WorkingWithFields.InsertAdvanceFieldWithoutDocumentBuilder.docx"); + //ExEnd:InsertAdvanceFieldWithoutDocumentBuilder + } + + @Test + public void getMailMergeFieldNames() throws Exception + { + //ExStart:GetFieldNames + //GistId:b4bab1bf22437a86d8062e91cf154494 + Document doc = new Document(); + + String[] fieldNames = doc.getMailMerge().getFieldNames(); + //ExEnd:GetFieldNames + System.out.println("\nDocument have " + fieldNames.length + " fields."); + } + + @Test + public void mappedDataFields() throws Exception + { + //ExStart:MappedDataFields + //GistId:b4bab1bf22437a86d8062e91cf154494 + Document doc = new Document(); + + doc.getMailMerge().getMappedDataFields().add("MyFieldName_InDocument", "MyFieldName_InDataSource"); + //ExEnd:MappedDataFields + } + + @Test + public void deleteFields() throws Exception + { + //ExStart:DeleteFields + //GistId:f39874821cb317d245a769c9ce346fea + Document doc = new Document(); + + doc.getMailMerge().deleteFields(); + //ExEnd:DeleteFields + } + + @Test + public void fieldUpdateCulture() throws Exception + { + //ExStart:FieldUpdateCulture + //GistId:79b46682fbfd7f02f64783b163ed95fc + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField(FieldType.FIELD_TIME, true); + + doc.getFieldOptions().setFieldUpdateCultureSource(FieldUpdateCultureSource.FIELD_CODE); + doc.getFieldOptions().setFieldUpdateCultureProvider(new FieldUpdateCultureProvider()); + + doc.save(getArtifactsDir() + "WorkingWithFields.FieldUpdateCulture.pdf"); + //ExEnd:FieldUpdateCulture + } + + //ExStart:FieldUpdateCultureProvider + //GistId:79b46682fbfd7f02f64783b163ed95fc + private static class FieldUpdateCultureProvider implements IFieldUpdateCultureProvider + { + public msCultureInfo getCulture(String name, Field field) + { + switch (gStringSwitchMap.of(name)) + { + case /*"ru-RU"*/0: + msCultureInfo culture = new msCultureInfo(name, false); + msDateTimeFormatInfo format = culture.getDateTimeFormat(); + + format.setMonthNames(new String[] + { + "месяц 1", "месяц 2", "месяц 3", "месяц 4", "месяц 5", "месяц 6", "месяц 7", "месяц 8", + "месяц 9", "месяц 10", "месяц 11", "месяц 12", "" + }); + format.setMonthGenitiveNames(format.getMonthNames()); + format.setAbbreviatedMonthNames(new String[] + { + "мес 1", "мес 2", "мес 3", "мес 4", "мес 5", "мес 6", "мес 7", "мес 8", "мес 9", "мес 10", + "мес 11", "мес 12", "" + }); + format.setAbbreviatedMonthGenitiveNames(format.getAbbreviatedMonthNames()); + + format.setDayNames(new String[] + { + "день недели 7", "день недели 1", "день недели 2", "день недели 3", "день недели 4", + "день недели 5", "день недели 6" + }); + format.setAbbreviatedDayNames(new String[] + { "день 7", "день 1", "день 2", "день 3", "день 4", "день 5", "день 6" }); + format.setShortestDayNames(new String[] { "д7", "д1", "д2", "д3", "д4", "д5", "д6" }); + + format.setAMDesignator("До полудня"); + format.setPMDesignator("После полудня"); + + final String PATTERN = "yyyy MM (MMMM) dd (dddd) hh:mm:ss tt"; + format.setLongDatePattern(PATTERN); + format.setLongTimePattern(PATTERN); + format.setShortDatePattern(PATTERN); + format.setShortTimePattern(PATTERN); + + return culture; + case /*"en-US"*/1: + return new msCultureInfo(name, false); + default: + return null; + } + } + } + //ExEnd:FieldUpdateCultureProvider + + @Test + public void fieldDisplayResults() throws Exception + { + //ExStart:FieldDisplayResults + //GistId:bf0f8a6b40b69a5274ab3553315e147f + //ExStart:UpdateDocFields + //GistId:08db64c4d86842c4afd1ecb925ed07c4 + Document document = new Document(getMyDir() + "Various fields.docx"); + + document.updateFields(); + //ExEnd:UpdateDocFields + + for (Field field : document.getRange().getFields()) + System.out.println(field.getDisplayResult()); + //ExEnd:FieldDisplayResults + } + + @Test + public void evaluateIfCondition() throws Exception + { + //ExStart:EvaluateIfCondition + //GistId:79b46682fbfd7f02f64783b163ed95fc + DocumentBuilder builder = new DocumentBuilder(); + + FieldIf field = (FieldIf) builder.insertField("IF 1 = 1", null); + /*FieldIfComparisonResult*/int actualResult = field.evaluateCondition(); + + System.out.println(actualResult); + //ExEnd:EvaluateIfCondition + } + + @Test + public void unlinkFieldsInParagraph() throws Exception + { + //ExStart:UnlinkFieldsInParagraph + //GistId:f3592014d179ecb43905e37b2a68bc92 + Document doc = new Document(getMyDir() + "Linked fields.docx"); + + // Pass the appropriate parameters to convert all IF fields to text that are encountered only in the last + // paragraph of the document. + doc.getFirstSection().getBody().getLastParagraph().getRange().getFields().Where(f => f.Type == FieldType.FieldIf).ToList() + .ForEach(f => f.Unlink()); + + doc.save(getArtifactsDir() + "WorkingWithFields.UnlinkFieldsInParagraph.docx"); + //ExEnd:UnlinkFieldsInParagraph + } + + @Test + public void unlinkFieldsInDocument() throws Exception + { + //ExStart:UnlinkFieldsInDocument + //GistId:f3592014d179ecb43905e37b2a68bc92 + Document doc = new Document(getMyDir() + "Linked fields.docx"); + + // Pass the appropriate parameters to convert all IF fields encountered in the document (including headers and footers) to text. + doc.getRange().getFields().Where(f => f.Type == FieldType.FieldIf).ToList().ForEach(f => f.Unlink()); + + // Save the document with fields transformed to disk + doc.save(getArtifactsDir() + "WorkingWithFields.UnlinkFieldsInDocument.docx"); + //ExEnd:UnlinkFieldsInDocument + } + + @Test + public void unlinkFieldsInBody() throws Exception + { + //ExStart:UnlinkFieldsInBody + //GistId:f3592014d179ecb43905e37b2a68bc92 + Document doc = new Document(getMyDir() + "Linked fields.docx"); + + // Pass the appropriate parameters to convert PAGE fields encountered to text only in the body of the first section. + doc.getFirstSection().getBody().getRange().getFields().Where(f => f.Type == FieldType.FieldPage).ToList().ForEach(f => f.Unlink()); + + doc.save(getArtifactsDir() + "WorkingWithFields.UnlinkFieldsInBody.docx"); + //ExEnd:UnlinkFieldsInBody + } + + @Test + public void changeLocale() throws Exception + { + //ExStart:ChangeLocale + //GistId:9e90defe4a7bcafb004f73a2ef236986 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField("MERGEFIELD Date"); + + // Store the current culture so it can be set back once mail merge is complete. + msCultureInfo currentCulture = CurrentThread.getCurrentCulture(); + // Set to German language so dates and numbers are formatted using this culture during mail merge. + CurrentThread.setCurrentCulture(new msCultureInfo("de-DE")); + + doc.getMailMerge().execute(new String[] { "Date" }, new Object[] { new Date }); + + CurrentThread.setCurrentCulture(currentCulture); + + doc.save(getArtifactsDir() + "WorkingWithFields.ChangeLocale.docx"); + //ExEnd:ChangeLocale + } + + //ExStart:ConvertFieldsToStaticText + //GistId:f3592014d179ecb43905e37b2a68bc92 + /// + /// Converts any fields of the specified type found in the descendants of the node into static text. + /// + /// The node in which all descendants of the specified FieldType will be converted to static text. + /// The FieldType of the field to convert to static text. + private void convertFieldsToStaticText(CompositeNode compositeNode, /*FieldType*/int targetFieldType) throws Exception + { + compositeNode.getRange().getFields().Cast().Where(f => f.Type == targetFieldType).ToList().ForEach(f => f.Unlink()); + } + //ExEnd:ConvertFieldsToStaticText + + @Test + public void fieldResultFormatting() throws Exception + { + //ExStart:FieldResultFormatting + //GistId:79b46682fbfd7f02f64783b163ed95fc + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + FieldResultFormatter formatter = new FieldResultFormatter("${0}", "Date: {0}", "Item # {0}:"); + doc.getFieldOptions().setResultFormatter(formatter); + + // Our field result formatter applies a custom format to newly created fields of three types of formats. + // Field result formatters apply new formatting to fields as they are updated, + // which happens as soon as we create them using this InsertField method overload. + // 1 - Numeric: + builder.insertField(" = 2 + 3 \\# $###"); + + Assert.assertEquals("$5", doc.getRange().getFields().get(0).getResult()); + Assert.assertEquals(1, formatter.countFormatInvocations(FieldResultFormatter.FormatInvocationType.NUMERIC)); + + // 2 - Date/time: + builder.insertField("DATE \\@ \"d MMMM yyyy\""); + + Assert.assertTrue(doc.getRange().getFields().get(1).getResult().startsWith("Date: ")); + Assert.assertEquals(1, formatter.countFormatInvocations(FieldResultFormatter.FormatInvocationType.DATE_TIME)); + + // 3 - General: + builder.insertField("QUOTE \"2\" \\* Ordinal"); + + Assert.assertEquals("Item # 2:", doc.getRange().getFields().get(2).getResult()); + Assert.assertEquals(1, formatter.countFormatInvocations(FieldResultFormatter.FormatInvocationType.GENERAL)); + + formatter.printFormatInvocations(); + //ExEnd:FieldResultFormatting + } + + //ExStart:FieldResultFormatter + //GistId:79b46682fbfd7f02f64783b163ed95fc + /// + /// When fields with formatting are updated, this formatter will override their formatting + /// with a custom format, while tracking every invocation. + /// + private static class FieldResultFormatter implements IFieldResultFormatter + { + public FieldResultFormatter(String numberFormat, String dateFormat, String generalFormat) + { + mNumberFormat = numberFormat; + mDateFormat = dateFormat; + mGeneralFormat = generalFormat; + } + + public String formatNumeric(double value, String format) + { + if (msString.isNullOrEmpty(mNumberFormat)) + return null; + + String newValue = MessageFormat.format(mNumberFormat, value); + getFormatInvocations().add(new FormatInvocation(FormatInvocationType.NUMERIC, value, format, newValue)); + return newValue; + } + + public String formatDateTime(DateTime value, String format, /*CalendarType*/int calendarType) + { + if (msString.isNullOrEmpty(mDateFormat)) + return null; + + String newValue = MessageFormat.format(mDateFormat, value); + getFormatInvocations().add(new FormatInvocation(FormatInvocationType.DATE_TIME, $"{value} ({calendarType})", format, newValue)); + return newValue; + } + + public String format(String value, /*GeneralFormat*/int format) + { + return format((Object)value, format); + } + + public String format(double value, /*GeneralFormat*/int format) + { + return format((Object)value, format); + } + + private String format(Object value, /*GeneralFormat*/int format) + { + if (msString.isNullOrEmpty(mGeneralFormat)) + return null; + + String newValue = MessageFormat.format(mGeneralFormat, value); + getFormatInvocations().add(new FormatInvocation(FormatInvocationType.GENERAL, value, GeneralFormat.toString(format), newValue)); + return newValue; + } + + public int countFormatInvocations(/*FormatInvocationType*/int formatInvocationType) + { + if (formatInvocationType == FormatInvocationType.ALL) + return getFormatInvocations().size(); + return getFormatInvocations().Count(f => f.FormatInvocationType == formatInvocationType); + } + + public void printFormatInvocations() + { + for (FormatInvocation f : (Iterable) getFormatInvocations()) + System.out.println("Invocation type:\t{f.FormatInvocationType}\n" + + $"\tOriginal value:\t\t{f.Value}\n" + + $"\tOriginal format:\t{f.OriginalFormat}\n" + + $"\tNew value:\t\t\t{f.NewValue}\n"); + } + + private /*final*/ String mNumberFormat; + private /*final*/ String mDateFormat; + private /*final*/ String mGeneralFormat; + private ArrayList getFormatInvocations() { return mFormatInvocations; }; + + private ArrayList mFormatInvocations !!!Autoporter warning: AutoProperty initialization can't be autoported! = /*new*/ ArrayListlist(); + + private static class FormatInvocation + { + public /*FormatInvocationType*/int getFormatInvocationType() { return mFormatInvocationType; }; + + private /*FormatInvocationType*/int mFormatInvocationType; + public Object getValue() { return mValue; }; + + private Object mValue; + public String getOriginalFormat() { return mOriginalFormat; }; + + private String mOriginalFormat; + public String getNewValue() { return mNewValue; }; + + private String mNewValue; + + public FormatInvocation(/*FormatInvocationType*/int formatInvocationType, Object value, String originalFormat, String newValue) + { + mValue = value; + mFormatInvocationType = formatInvocationType; + mOriginalFormat = originalFormat; + mNewValue = newValue; + } + } + + public /*enum*/ final class FormatInvocationType + { + private FormatInvocationType(){} + + public static final int NUMERIC = 0; + public static final int DATE_TIME = 1; + public static final int GENERAL = 2; + public static final int ALL = 3; + + public static final int length = 4; + } + } + + //JAVA-added for string switch emulation + private static final StringSwitchMap gStringSwitchMap = new StringSwitchMap + ( + "ru-RU", + "en-US" + ); + + //ExEnd:FieldResultFormatter +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithFonts.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithFonts.java new file mode 100644 index 00000000..6fd922b1 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithFonts.java @@ -0,0 +1,504 @@ +package DocsExamples.Programming_with_Documents; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.Font; +import java.awt.Color; +import com.aspose.words.Underline; +import com.aspose.ms.System.msConsole; +import com.aspose.words.RunCollection; +import com.aspose.words.TextDmlEffect; +import com.aspose.ms.System.Drawing.msColor; +import com.aspose.words.EmphasisMark; +import com.aspose.words.FontSettings; +import java.util.ArrayList; +import com.aspose.words.FontSourceBase; +import com.aspose.ms.System.Collections.msArrayList; +import com.aspose.words.FolderFontSource; +import com.aspose.words.SystemFontSource; +import com.aspose.words.TableSubstitutionRule; +import com.aspose.words.LoadOptions; +import com.aspose.words.PhysicalFontInfo; +import com.aspose.words.IWarningCallback; +import com.aspose.words.WarningInfo; +import com.aspose.words.WarningType; +import com.aspose.words.StreamFontSource; +import com.aspose.ms.System.IO.Stream; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.WarningInfoCollection; + + +class WorkingWithFonts extends DocsExamplesBase +{ + @Test + public void fontFormatting() throws Exception + { + //ExStart:WriteAndFont + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Font font = builder.getFont(); + font.setSize(16.0); + font.setBold(true); + font.setColor(Color.BLUE); + font.setName("Arial"); + font.setUnderline(Underline.DASH); + + builder.write("Sample text."); + + doc.save(getArtifactsDir() + "WorkingWithFonts.FontFormatting.docx"); + //ExEnd:WriteAndFont + } + + @Test + public void getFontLineSpacing() throws Exception + { + //ExStart:GetFontLineSpacing + //GistId:7cb86f131b74afcbebc153f0039e3947 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getFont().setName("Calibri"); + builder.writeln("qText"); + + Font font = builder.getDocument().getFirstSection().getBody().getFirstParagraph().getRuns().get(0).getFont(); + System.out.println("lineSpacing = {font.LineSpacing}"); + //ExEnd:GetFontLineSpacing + } + + @Test + public void checkDMLTextEffect() throws Exception + { + //ExStart:CheckDMLTextEffect + Document doc = new Document(getMyDir() + "DrawingML text effects.docx"); + + RunCollection runs = doc.getFirstSection().getBody().getFirstParagraph().getRuns(); + Font runFont = runs.get(0).getFont(); + + // One run might have several Dml text effects applied. + msConsole.writeLine(runFont.hasDmlEffect(TextDmlEffect.SHADOW)); + msConsole.writeLine(runFont.hasDmlEffect(TextDmlEffect.EFFECT_3_D)); + msConsole.writeLine(runFont.hasDmlEffect(TextDmlEffect.REFLECTION)); + msConsole.writeLine(runFont.hasDmlEffect(TextDmlEffect.OUTLINE)); + msConsole.writeLine(runFont.hasDmlEffect(TextDmlEffect.FILL)); + //ExEnd:CheckDMLTextEffect + } + + @Test + public void setFontFormatting() throws Exception + { + //ExStart:SetFontFormatting + //GistId:7cb86f131b74afcbebc153f0039e3947 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Font font = builder.getFont(); + font.setBold(true); + font.setColor(msColor.getDarkBlue()); + font.setItalic(true); + font.setName("Arial"); + font.setSize(24.0); + font.setSpacing(5.0); + font.setUnderline(Underline.DOUBLE); + + builder.writeln("I'm a very nice formatted string."); + + doc.save(getArtifactsDir() + "WorkingWithFonts.SetFontFormatting.docx"); + //ExEnd:SetFontFormatting + } + + @Test + public void setFontEmphasisMark() throws Exception + { + //ExStart:SetFontEmphasisMark + //GistId:7cb86f131b74afcbebc153f0039e3947 + Document document = new Document(); + DocumentBuilder builder = new DocumentBuilder(document); + + builder.getFont().setEmphasisMark(EmphasisMark.UNDER_SOLID_CIRCLE); + + builder.write("Emphasis text"); + builder.writeln(); + builder.getFont().clearFormatting(); + builder.write("Simple text"); + + document.save(getArtifactsDir() + "WorkingWithFonts.SetFontEmphasisMark.docx"); + //ExEnd:SetFontEmphasisMark + } + + @Test + public void enableDisableFontSubstitution() throws Exception + { + //ExStart:EnableDisableFontSubstitution + Document doc = new Document(getMyDir() + "Rendering.docx"); + + FontSettings fontSettings = new FontSettings(); + fontSettings.getSubstitutionSettings().getDefaultFontSubstitution().setDefaultFontName("Arial"); + fontSettings.getSubstitutionSettings().getFontInfoSubstitution().setEnabled(false); + + doc.setFontSettings(fontSettings); + + doc.save(getArtifactsDir() + "WorkingWithFonts.EnableDisableFontSubstitution.pdf"); + //ExEnd:EnableDisableFontSubstitution + } + + @Test + public void fontFallbackSettings() throws Exception + { + //ExStart:FontFallbackSettings + //GistId:a08698f540d47082b4e2dbb1cb67fc1b + Document doc = new Document(getMyDir() + "Rendering.docx"); + + FontSettings fontSettings = new FontSettings(); + fontSettings.getFallbackSettings().load(getMyDir() + "Font fallback rules.xml"); + + doc.setFontSettings(fontSettings); + + doc.save(getArtifactsDir() + "WorkingWithFonts.FontFallbackSettings.pdf"); + //ExEnd:FontFallbackSettings + } + + @Test + public void notoFallbackSettings() throws Exception + { + //ExStart:NotoFallbackSettings + //GistId:a08698f540d47082b4e2dbb1cb67fc1b + Document doc = new Document(getMyDir() + "Rendering.docx"); + + FontSettings fontSettings = new FontSettings(); + fontSettings.getFallbackSettings().loadNotoFallbackSettings(); + + doc.setFontSettings(fontSettings); + + doc.save(getArtifactsDir() + "WorkingWithFonts.NotoFallbackSettings.pdf"); + //ExEnd:NotoFallbackSettings + } + + @Test + public void defaultInstance() throws Exception + { + //ExStart:DefaultInstance + //GistId:7e64f6d40825be58a8c12f1307c12964 + FontSettings.getDefaultInstance().setFontsFolder("C:\\MyFonts\\", true); + //ExEnd:DefaultInstance + + Document doc = new Document(getMyDir() + "Rendering.docx"); + doc.save(getArtifactsDir() + "WorkingWithFonts.DefaultInstance.pdf"); + } + + @Test + public void multipleFolders() throws Exception + { + //ExStart:MultipleFolders + //GistId:7e64f6d40825be58a8c12f1307c12964 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + FontSettings fontSettings = new FontSettings(); + // Note that this setting will override any default font sources that are being searched by default. Now only these folders will be searched for + // fonts when rendering or embedding fonts. To add an extra font source while keeping system font sources then use both FontSettings.GetFontSources and + // FontSettings.SetFontSources instead. + fontSettings.setFontsFolders(new String[] { "C:\\MyFonts\\", "D:\\Misc\\Fonts\\" }, true); + + doc.setFontSettings(fontSettings); + + doc.save(getArtifactsDir() + "WorkingWithFonts.MultipleFolders.pdf"); + //ExEnd:MultipleFolders + } + + @Test + public void setFontsFoldersSystemAndCustomFolder() throws Exception + { + //ExStart:SetFontsFoldersSystemAndCustomFolder + Document doc = new Document(getMyDir() + "Rendering.docx"); + + FontSettings fontSettings = new FontSettings(); + // Retrieve the array of environment-dependent font sources that are searched by default. + // For example this will contain a "Windows\Fonts\" source on a Windows machines. + // We add this array to a new List to make adding or removing font entries much easier. + ArrayList fontSources = msArrayList.ctor(fontSettings.getFontsSources()); + + // Add a new folder source which will instruct Aspose.Words to search the following folder for fonts. + FolderFontSource folderFontSource = new FolderFontSource("C:\\MyFonts\\", true); + // Add the custom folder which contains our fonts to the list of existing font sources. + fontSources.add(folderFontSource); + + FontSourceBase[] updatedFontSources = msArrayList.toArray(fontSources, new FontSourceBase[0]); + fontSettings.setFontsSources(updatedFontSources); + + doc.setFontSettings(fontSettings); + + doc.save(getArtifactsDir() + "WorkingWithFonts.SetFontsFoldersSystemAndCustomFolder.pdf"); + //ExEnd:SetFontsFoldersSystemAndCustomFolder + } + + @Test + public void fontsFoldersWithPriority() throws Exception + { + //ExStart:FontsFoldersWithPriority + //GistId:7e64f6d40825be58a8c12f1307c12964 + FontSettings.getDefaultInstance().setFontsSources(new FontSourceBase[] + { + new SystemFontSource(), new FolderFontSource("C:\\MyFonts\\", true, 1) + }); + //ExEnd:FontsFoldersWithPriority + + Document doc = new Document(getMyDir() + "Rendering.docx"); + doc.save(getArtifactsDir() + "WorkingWithFonts.FontsFoldersWithPriority.pdf"); + } + + @Test + public void trueTypeFontsFolder() throws Exception + { + //ExStart:TrueTypeFontsFolder + //GistId:7e64f6d40825be58a8c12f1307c12964 + Document doc = new Document(getMyDir() + "Rendering.docx"); + + FontSettings fontSettings = new FontSettings(); + // Note that this setting will override any default font sources that are being searched by default. Now only these folders will be searched for + // Fonts when rendering or embedding fonts. To add an extra font source while keeping system font sources then use both FontSettings.GetFontSources and + // FontSettings.SetFontSources instead + fontSettings.setFontsFolder("C:\\MyFonts\\", false); + // Set font settings + doc.setFontSettings(fontSettings); + + doc.save(getArtifactsDir() + "WorkingWithFonts.TrueTypeFontsFolder.pdf"); + //ExEnd:TrueTypeFontsFolder + } + + @Test + public void specifyDefaultFontWhenRendering() throws Exception + { + //ExStart:SpecifyDefaultFontWhenRendering + Document doc = new Document(getMyDir() + "Rendering.docx"); + + FontSettings fontSettings = new FontSettings(); + // If the default font defined here cannot be found during rendering then + // the closest font on the machine is used instead. + fontSettings.getSubstitutionSettings().getDefaultFontSubstitution().setDefaultFontName("Arial Unicode MS"); + + doc.setFontSettings(fontSettings); + + doc.save(getArtifactsDir() + "WorkingWithFonts.SpecifyDefaultFontWhenRendering.pdf"); + //ExEnd:SpecifyDefaultFontWhenRendering + } + + @Test + public void fontSettingsWithLoadOptions() throws Exception + { + //ExStart:FontSettingsWithLoadOptions + FontSettings fontSettings = new FontSettings(); + + TableSubstitutionRule substitutionRule = fontSettings.getSubstitutionSettings().getTableSubstitution(); + // If "UnknownFont1" font family is not available then substitute it by "Comic Sans MS" + substitutionRule.addSubstitutes("UnknownFont1", new String[] { "Comic Sans MS" }); + + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setFontSettings(fontSettings); + + Document doc = new Document(getMyDir() + "Rendering.docx", loadOptions); + //ExEnd:FontSettingsWithLoadOptions + } + + @Test + public void setFontsFolder() throws Exception + { + //ExStart:SetFontsFolder + FontSettings fontSettings = new FontSettings(); + fontSettings.setFontsFolder(getMyDir() + "Fonts", false); + + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setFontSettings(fontSettings); + + Document doc = new Document(getMyDir() + "Rendering.docx", loadOptions); + //ExEnd:SetFontsFolder + } + + @Test + public void loadOptionFontSettings() throws Exception + { + //ExStart:LoadOptionFontSettings + //GistId:a08698f540d47082b4e2dbb1cb67fc1b + LoadOptions loadOptions = new LoadOptions(); + loadOptions.setFontSettings(new FontSettings()); + + Document doc = new Document(getMyDir() + "Rendering.docx", loadOptions); + //ExEnd:LoadOptionFontSettings + } + + @Test + public void fontSettingsDefaultInstance() throws Exception + { + //ExStart:FontsFolders + //GistId:7e64f6d40825be58a8c12f1307c12964 + //ExStart:FontSettingsFontSource + //GistId:a08698f540d47082b4e2dbb1cb67fc1b + //ExStart:FontSettingsDefaultInstance + //GistId:a08698f540d47082b4e2dbb1cb67fc1b + FontSettings fontSettings = FontSettings.getDefaultInstance(); + //ExEnd:FontSettingsDefaultInstance + fontSettings.setFontsSources(new FontSourceBase[] + { + new SystemFontSource(), + new FolderFontSource("C:\\MyFonts\\", true) + }); + //ExEnd:FontSettingsFontSource + + Document doc = new Document(getMyDir() + "Rendering.docx"); + //ExEnd:FontsFolders + } + + @Test + public void availableFonts() + { + //ExStart:AvailableFonts + //GistId:7e64f6d40825be58a8c12f1307c12964 + FontSettings fontSettings = new FontSettings(); + ArrayList fontSources = msArrayList.ctor(fontSettings.getFontsSources()); + + // Add a new folder source which will instruct Aspose.Words to search the following folder for fonts. + FolderFontSource folderFontSource = new FolderFontSource(getMyDir(), true); + // Add the custom folder which contains our fonts to the list of existing font sources. + fontSources.add(folderFontSource); + + FontSourceBase[] updatedFontSources = msArrayList.toArray(fontSources, new FontSourceBase[0]); + + for (PhysicalFontInfo fontInfo : updatedFontSources[0].getAvailableFonts()) + { + System.out.println("FontFamilyName : " + fontInfo.getFontFamilyName()); + System.out.println("FullFontName : " + fontInfo.getFullFontName()); + System.out.println("Version : " + fontInfo.getVersion()); + System.out.println("FilePath : " + fontInfo.getFilePath()); + } + //ExEnd:AvailableFonts + } + + @Test + public void receiveNotificationsOfFonts() throws Exception + { + //ExStart:ReceiveNotificationsOfFonts + Document doc = new Document(getMyDir() + "Rendering.docx"); + + FontSettings fontSettings = new FontSettings(); + + // We can choose the default font to use in the case of any missing fonts. + fontSettings.getSubstitutionSettings().getDefaultFontSubstitution().setDefaultFontName("Arial"); + // For testing we will set Aspose.Words to look for fonts only in a folder which doesn't exist. Since Aspose.Words won't + // find any fonts in the specified directory, then during rendering the fonts in the document will be subsuited with the default + // font specified under FontSettings.DefaultFontName. We can pick up on this subsuition using our callback. + fontSettings.setFontsFolder("", false); + + // Create a new class implementing IWarningCallback which collect any warnings produced during document save. + HandleDocumentWarnings callback = new HandleDocumentWarnings(); + + doc.setWarningCallback(callback); + doc.setFontSettings(fontSettings); + + doc.save(getArtifactsDir() + "WorkingWithFonts.ReceiveNotificationsOfFonts.pdf"); + //ExEnd:ReceiveNotificationsOfFonts + } + + @Test + public void receiveWarningNotification() throws Exception + { + //ExStart:ReceiveWarningNotification + Document doc = new Document(getMyDir() + "Rendering.docx"); + + // When you call UpdatePageLayout the document is rendered in memory. Any warnings that occured during rendering + // are stored until the document save and then sent to the appropriate WarningCallback. + doc.updatePageLayout(); + + HandleDocumentWarnings callback = new HandleDocumentWarnings(); + doc.setWarningCallback(callback); + + // Even though the document was rendered previously, any save warnings are notified to the user during document save. + doc.save(getArtifactsDir() + "WorkingWithFonts.ReceiveWarningNotification.pdf"); + //ExEnd:ReceiveWarningNotification + } + + //ExStart:HandleDocumentWarnings + public static class HandleDocumentWarnings implements IWarningCallback + { + /// + /// Our callback only needs to implement the "Warning" method. This method is called whenever there is a + /// Potential issue during document procssing. The callback can be set to listen for warnings generated + /// during document load and/or document save. + /// + public void warning(WarningInfo info) + { + // We are only interested in fonts being substituted. + if (info.getWarningType() == WarningType.FONT_SUBSTITUTION) + { + System.out.println("Font substitution: " + info.getDescription()); + } + } + } + //ExEnd:HandleDocumentWarnings + + @Test + //ExStart:ResourceSteam + //GistId:7e64f6d40825be58a8c12f1307c12964 + public void resourceSteam() throws Exception + { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + FontSettings.getDefaultInstance().setFontsSources(new FontSourceBase[] + { new SystemFontSource(), new ResourceSteamFontSource() }); + + doc.save(getArtifactsDir() + "WorkingWithFonts.ResourceSteam.pdf"); + } + + static class ResourceSteamFontSource extends StreamFontSource + { + public /*override*/ Stream openFontDataStream() + { + return Assembly.GetExecutingAssembly().GetManifestResourceStream("resourceName"); + } + } + //ExEnd:ResourceSteam + + @Test + //ExStart:GetSubstitutionWithoutSuffixes + //GistId:a08698f540d47082b4e2dbb1cb67fc1b + public void getSubstitutionWithoutSuffixes() throws Exception + { + Document doc = new Document(getMyDir() + "Get substitution without suffixes.docx"); + + DocumentSubstitutionWarnings substitutionWarningHandler = new DocumentSubstitutionWarnings(); + doc.setWarningCallback(substitutionWarningHandler); + + ArrayList fontSources = msArrayList.ctor(FontSettings.getDefaultInstance().getFontsSources()); + + FolderFontSource folderFontSource = new FolderFontSource(getFontsDir(), true); + fontSources.add(folderFontSource); + + FontSourceBase[] updatedFontSources = msArrayList.toArray(fontSources, new FontSourceBase[0]); + FontSettings.getDefaultInstance().setFontsSources(updatedFontSources); + + doc.save(getArtifactsDir() + "WorkingWithFonts.GetSubstitutionWithoutSuffixes.pdf"); + + Assert.assertEquals("Font 'DINOT-Regular' has not been found. Using 'DINOT' font instead. Reason: font name substitution.", substitutionWarningHandler.FontWarnings.get(0).getDescription()); + } + + public static class DocumentSubstitutionWarnings implements IWarningCallback + { + /// + /// Our callback only needs to implement the "Warning" method. + /// This method is called whenever there is a potential issue during document processing. + /// The callback can be set to listen for warnings generated during document load and/or document save. + /// + public void warning(WarningInfo info) + { + // We are only interested in fonts being substituted. + if (info.getWarningType() == WarningType.FONT_SUBSTITUTION) + FontWarnings.warning(info); + } + + public WarningInfoCollection FontWarnings = new WarningInfoCollection(); + } + //ExEnd:GetSubstitutionWithoutSuffixes +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithFootnoteAndEndnote.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithFootnoteAndEndnote.java new file mode 100644 index 00000000..34e48ef5 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithFootnoteAndEndnote.java @@ -0,0 +1,64 @@ +package DocsExamples.Programming_with_Documents; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.FootnotePosition; +import com.aspose.words.EndnotePosition; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.FootnoteType; +import com.aspose.words.EndnoteOptions; +import com.aspose.words.FootnoteNumberingRule; + + +class WorkingWithFootnotes extends DocsExamplesBase +{ + @Test + public void setFootnoteColumns() throws Exception + { + //ExStart:SetFootnoteColumns + //GistId:3b39c2019380ee905e7d9596494916a4 + Document doc = new Document(getMyDir() + "Document.docx"); + + // Specify the number of columns with which the footnotes area is formatted. + doc.getFootnoteOptions().setColumns(3); + + doc.save(getArtifactsDir() + "WorkingWithFootnotes.SetFootnoteColumns.docx"); + //ExEnd:SetFootnoteColumns + } + + @Test + public void setFootnoteAndEndnotePosition() throws Exception + { + //ExStart:SetFootnoteAndEndnotePosition + //GistId:3b39c2019380ee905e7d9596494916a4 + Document doc = new Document(getMyDir() + "Document.docx"); + + doc.getFootnoteOptions().setPosition(FootnotePosition.BENEATH_TEXT); + doc.getEndnoteOptions().setPosition(EndnotePosition.END_OF_SECTION); + + doc.save(getArtifactsDir() + "WorkingWithFootnotes.SetFootnoteAndEndnotePosition.docx"); + //ExEnd:SetFootnoteAndEndnotePosition + } + + @Test + public void setEndnoteOptions() throws Exception + { + //ExStart:SetEndnoteOptions + //GistId:3b39c2019380ee905e7d9596494916a4 + Document doc = new Document(getMyDir() + "Document.docx"); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Some text"); + builder.insertFootnote(FootnoteType.ENDNOTE, "Footnote text."); + + EndnoteOptions option = doc.getEndnoteOptions(); + option.setRestartRule(FootnoteNumberingRule.RESTART_PAGE); + option.setPosition(EndnotePosition.END_OF_SECTION); + + doc.save(getArtifactsDir() + "WorkingWithFootnotes.SetEndnoteOptions.docx"); + //ExEnd:SetEndnoteOptions + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithFormFields.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithFormFields.java new file mode 100644 index 00000000..f323a826 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithFormFields.java @@ -0,0 +1,73 @@ +package DocsExamples.Programming_with_Documents; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.FormField; +import com.aspose.words.FieldType; +import com.aspose.words.FormFieldCollection; +import java.awt.Color; + + +class WorkingWithFormFields extends DocsExamplesBase +{ + @Test + public void insertFormFields() throws Exception + { + //ExStart:InsertFormFields + //GistId:b09907fef4643433271e4e0e912921b0 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + String[] items = { "One", "Two", "Three" }; + builder.insertComboBox("DropDown", items, 0); + //ExEnd:InsertFormFields + } + + @Test + public void formFieldsWorkWithProperties() throws Exception + { + //ExStart:FormFieldsWorkWithProperties + //GistId:b09907fef4643433271e4e0e912921b0 + Document doc = new Document(getMyDir() + "Form fields.docx"); + FormField formField = doc.getRange().getFormFields().get(3); + + if (formField.getType() == FieldType.FIELD_FORM_TEXT_INPUT) + formField.setResult("My name is " + formField.getName()); + //ExEnd:FormFieldsWorkWithProperties + } + + @Test + public void formFieldsGetFormFieldsCollection() throws Exception + { + //ExStart:FormFieldsGetFormFieldsCollection + //GistId:b09907fef4643433271e4e0e912921b0 + Document doc = new Document(getMyDir() + "Form fields.docx"); + + FormFieldCollection formFields = doc.getRange().getFormFields(); + //ExEnd:FormFieldsGetFormFieldsCollection + } + + @Test + public void formFieldsGetByName() throws Exception + { + //ExStart:FormFieldsFontFormatting + //GistId:b09907fef4643433271e4e0e912921b0 + //ExStart:FormFieldsGetByName + //GistId:b09907fef4643433271e4e0e912921b0 + Document doc = new Document(getMyDir() + "Form fields.docx"); + + FormFieldCollection documentFormFields = doc.getRange().getFormFields(); + + FormField formField1 = documentFormFields.get(3); + FormField formField2 = documentFormFields.get("Text2"); + //ExEnd:FormFieldsGetByName + + formField1.getFont().setSize(20.0); + formField2.getFont().setColor(Color.RED); + //ExEnd:FormFieldsFontFormatting + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithHeadersAndFooters.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithHeadersAndFooters.java new file mode 100644 index 00000000..62a49c45 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithHeadersAndFooters.java @@ -0,0 +1,250 @@ +package DocsExamples.Programming_with_Documents; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.HeaderFooterType; +import com.aspose.words.BreakType; +import com.aspose.words.RelativeHorizontalPosition; +import com.aspose.words.RelativeVerticalPosition; +import com.aspose.words.WrapType; +import com.aspose.words.ParagraphAlignment; +import com.aspose.words.Section; +import com.aspose.words.PageSetup; +import com.aspose.words.Orientation; +import com.aspose.words.HeaderFooter; + + +class WorkingWithHeadersAndFooters extends DocsExamplesBase +{ + @Test + public void createHeaderFooter() throws Exception + { + //ExStart:CreateHeaderFooter + //GistId:84cab3a22008f041ee6c1e959da09949 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Use HeaderPrimary and FooterPrimary + // if you want to set header/footer for all document. + // This header/footer type also responsible for odd pages. + //ExStart:HeaderFooterType + //GistId:84cab3a22008f041ee6c1e959da09949 + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.write("Header for page."); + //ExEnd:HeaderFooterType + + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + builder.write("Footer for page."); + + doc.save(getArtifactsDir() + "WorkingWithHeadersAndFooters.CreateHeaderFooter.docx"); + //ExEnd:CreateHeaderFooter + } + + @Test + public void differentFirstPage() throws Exception + { + //ExStart:DifferentFirstPage + //GistId:84cab3a22008f041ee6c1e959da09949 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Specify that we want different headers and footers for first page. + builder.getPageSetup().setDifferentFirstPageHeaderFooter(true); + + builder.moveToHeaderFooter(HeaderFooterType.HEADER_FIRST); + builder.write("Header for the first page."); + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_FIRST); + builder.write("Footer for the first page."); + + builder.moveToSection(0); + builder.writeln("Page 1"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 2"); + + doc.save(getArtifactsDir() + "WorkingWithHeadersAndFooters.DifferentFirstPage.docx"); + //ExEnd:DifferentFirstPage + } + + @Test + public void oddEvenPages() throws Exception + { + //ExStart:OddEvenPages + //GistId:84cab3a22008f041ee6c1e959da09949 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Specify that we want different headers and footers for even and odd pages. + builder.getPageSetup().setOddAndEvenPagesHeaderFooter(true); + + builder.moveToHeaderFooter(HeaderFooterType.HEADER_EVEN); + builder.write("Header for even pages."); + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.write("Header for odd pages."); + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_EVEN); + builder.write("Footer for even pages."); + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + builder.write("Footer for odd pages."); + + builder.moveToSection(0); + builder.writeln("Page 1"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page 2"); + + doc.save(getArtifactsDir() + "WorkingWithHeadersAndFooters.OddEvenPages.docx"); + //ExEnd:OddEvenPages + } + + @Test + public void insertImage() throws Exception + { + //ExStart:InsertImage + //GistId:84cab3a22008f041ee6c1e959da09949 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.insertImage(getImagesDir() + "Logo.jpg", RelativeHorizontalPosition.RIGHT_MARGIN, 10.0, + RelativeVerticalPosition.PAGE, 10.0, 50.0, 50.0, WrapType.THROUGH); + + doc.save(getArtifactsDir() + "WorkingWithHeadersAndFooters.InsertImage.docx"); + //ExEnd:InsertImage + } + + @Test + public void fontProps() throws Exception + { + //ExStart:FontProps + //GistId:84cab3a22008f041ee6c1e959da09949 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.getFont().setName("Arial"); + builder.getFont().setBold(true); + builder.getFont().setSize(14.0); + builder.write("Header for page."); + + doc.save(getArtifactsDir() + "WorkingWithHeadersAndFooters.FontProps.docx"); + //ExEnd:FontProps + } + + @Test + public void pageNumbers() throws Exception + { + //ExStart:PageNumbers + //GistId:84cab3a22008f041ee6c1e959da09949 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.RIGHT); + builder.write("Page "); + builder.insertField("PAGE", ""); + builder.write(" of "); + builder.insertField("NUMPAGES", ""); + + doc.save(getArtifactsDir() + "WorkingWithHeadersAndFooters.PageNumbers.docx"); + //ExEnd:PageNumbers + } + + @Test + public void linkToPreviousHeaderFooter() throws Exception + { + //ExStart:LinkToPreviousHeaderFooter + //GistId:84cab3a22008f041ee6c1e959da09949 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getPageSetup().setDifferentFirstPageHeaderFooter(true); + + builder.moveToHeaderFooter(HeaderFooterType.HEADER_FIRST); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.getFont().setName("Arial"); + builder.getFont().setBold(true); + builder.getFont().setSize(14.0); + builder.write("Header for the first page."); + + builder.moveToDocumentEnd(); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + + Section currentSection = builder.getCurrentSection(); + PageSetup pageSetup = currentSection.getPageSetup(); + pageSetup.setOrientation(Orientation.LANDSCAPE); + // This section does not need a different first-page header/footer we need only one title page in the document, + // and the header/footer for this page has already been defined in the previous section. + pageSetup.setDifferentFirstPageHeaderFooter(false); + + // This section displays headers/footers from the previous section + // by default call currentSection.HeadersFooters.LinkToPrevious(false) to cancel this page width + // is different for the new section. + currentSection.getHeadersFooters().linkToPrevious(false); + currentSection.getHeadersFooters().clear(); + + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.getFont().setName("Arial"); + builder.getFont().setSize(12.0); + builder.write("New Header for the first page."); + + doc.save(getArtifactsDir() + "WorkingWithHeadersAndFooters.LinkToPreviousHeaderFooter.docx"); + //ExEnd:LinkToPreviousHeaderFooter + } + + @Test + public void sectionsWithDifferentHeaders() throws Exception + { + //ExStart:SectionsWithDifferentHeaders + //GistId:1afca4d3da7cb4240fb91c3d93d8c30d + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + PageSetup pageSetup = builder.getCurrentSection().getPageSetup(); + pageSetup.setDifferentFirstPageHeaderFooter(true); + pageSetup.setHeaderDistance(20.0); + + builder.moveToHeaderFooter(HeaderFooterType.HEADER_FIRST); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.getFont().setName("Arial"); + builder.getFont().setBold(true); + builder.getFont().setSize(14.0); + builder.write("Header for the first page."); + + builder.moveToDocumentEnd(); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + // Insert a positioned image into the top/left corner of the header. + // Distance from the top/left edges of the page is set to 10 points. + builder.insertImage(getImagesDir() + "Logo.jpg", RelativeHorizontalPosition.PAGE, 10.0, + RelativeVerticalPosition.PAGE, 10.0, 50.0, 50.0, WrapType.THROUGH); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.RIGHT); + builder.write("Header for odd page."); + + doc.save(getArtifactsDir() + "WorkingWithHeadersAndFooters.SectionsWithDifferentHeaders.docx"); + //ExEnd:SectionsWithDifferentHeaders + } + + //ExStart:CopyHeadersFootersFromPreviousSection + //GistId:84cab3a22008f041ee6c1e959da09949 + /// + /// Clones and copies headers/footers form the previous section to the specified section. + /// + private void copyHeadersFootersFromPreviousSection(Section section) + { + Section previousSection = (Section)section.getPreviousSibling(); + + if (previousSection == null) + return; + + section.getHeadersFooters().clear(); + + for (HeaderFooter headerFooter : (Iterable) previousSection.getHeadersFooters()) + section.getHeadersFooters().add(headerFooter.deepClone(true)); + } + //ExEnd:CopyHeadersFootersFromPreviousSection +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithHyphenation.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithHyphenation.java new file mode 100644 index 00000000..65ceb83b --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithHyphenation.java @@ -0,0 +1,101 @@ +package DocsExamples.Programming_with_Documents; + +// ********* THIS FILE IS AUTO PORTED ********* + +import com.aspose.ms.java.collections.StringSwitchMap; +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.Hyphenation; +import com.aspose.ms.System.IO.Stream; +import java.io.FileInputStream; +import com.aspose.ms.System.IO.File; +import com.aspose.ms.System.msConsole; +import com.aspose.words.IHyphenationCallback; +import com.aspose.ms.System.IO.Path; + + +class WorkingWithHyphenation extends DocsExamplesBase +{ + @Test + public void hyphenateWords() throws Exception + { + //ExStart:HyphenateWords + //GistId:a52aacf87a36f7881ba29d25de92fb83 + Document doc = new Document(getMyDir() + "German text.docx"); + + Hyphenation.registerDictionary("en-US", getMyDir() + "hyph_en_US.dic"); + Hyphenation.registerDictionary("de-CH", getMyDir() + "hyph_de_CH.dic"); + + doc.save(getArtifactsDir() + "WorkingWithHyphenation.HyphenateWords.pdf"); + //ExEnd:HyphenateWords + } + + @Test + public void loadHyphenationDictionary() throws Exception + { + //ExStart:LoadHyphenationDictionary + //GistId:a52aacf87a36f7881ba29d25de92fb83 + Document doc = new Document(getMyDir() + "German text.docx"); + + Stream stream = new FileInputStream(getMyDir() + "hyph_de_CH.dic"); + Hyphenation.registerDictionaryInternal("de-CH", stream); + + doc.save(getArtifactsDir() + "WorkingWithHyphenation.LoadHyphenationDictionary.pdf"); + //ExEnd:LoadHyphenationDictionary + } + + @Test + //ExStart:CustomHyphenation + //GistId:a52aacf87a36f7881ba29d25de92fb83 + public void hyphenationCallback() throws Exception + { + try + { + // Register hyphenation callback. + Hyphenation.setCallback(new CustomHyphenationCallback()); + + Document document = new Document(getMyDir() + "German text.docx"); + document.save(getArtifactsDir() + "WorkingWithHyphenation.HyphenationCallback.pdf"); + } + catch (Exception e) when (e.Message.StartsWith("Missing hyphenation dictionary")) + { + msConsole.WriteLine(e.Message); + } + finally + { + Hyphenation.setCallback(null); + } + } + + public static class CustomHyphenationCallback implements IHyphenationCallback + { + public void requestDictionary(String language) throws Exception + { + String dictionaryFolder = getMyDir(); + String dictionaryFullFileName; + switch (gStringSwitchMap.of(language)) + { + case /*"en-US"*/0: + dictionaryFullFileName = Path.combine(dictionaryFolder, "hyph_en_US.dic"); + break; + case /*"de-CH"*/1: + dictionaryFullFileName = Path.combine(dictionaryFolder, "hyph_de_CH.dic"); + break; + default: + throw new Exception($"Missing hyphenation dictionary for {language}."); + } + // Register dictionary for requested language. + Hyphenation.registerDictionary(language, dictionaryFullFileName); + } + } + + //JAVA-added for string switch emulation + private static final StringSwitchMap gStringSwitchMap = new StringSwitchMap + ( + "en-US", + "de-CH" + ); + + //ExEnd:CustomHyphenation +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithList.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithList.java new file mode 100644 index 00000000..ad4315d4 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithList.java @@ -0,0 +1,120 @@ +package DocsExamples.Programming_with_Documents; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.ListTemplate; +import com.aspose.words.List; +import com.aspose.words.OoxmlSaveOptions; +import com.aspose.words.OoxmlCompliance; +import com.aspose.words.BreakType; +import java.awt.Color; +import com.aspose.words.ListLevelAlignment; + + +class WorkingWithList extends DocsExamplesBase +{ + @Test + public void restartListAtEachSection() throws Exception + { + //ExStart:RestartListAtEachSection + //GistId:a1dfeba1e0480d5b277a61742c8921af + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + doc.getLists().add(ListTemplate.NUMBER_DEFAULT); + + List list = doc.getLists().get(0); + list.isRestartAtEachSection(true); + + // The "IsRestartAtEachSection" property will only be applicable when + // the document's OOXML compliance level is to a standard that is newer than "OoxmlComplianceCore.Ecma376". + OoxmlSaveOptions options = new OoxmlSaveOptions(); + { + options.setCompliance(OoxmlCompliance.ISO_29500_2008_TRANSITIONAL); + } + + builder.getListFormat().setList(list); + + builder.writeln("List item 1"); + builder.writeln("List item 2"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.writeln("List item 3"); + builder.writeln("List item 4"); + + doc.save(getArtifactsDir() + "WorkingWithList.RestartingDocumentList.docx", options); + //ExEnd:RestartListAtEachSection + } + + @Test + public void specifyListLevel() throws Exception + { + //ExStart:SpecifyListLevel + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a numbered list based on one of the Microsoft Word list templates + // and apply it to the document builder's current paragraph. + builder.getListFormat().setList(doc.getLists().add(ListTemplate.NUMBER_ARABIC_DOT)); + + // There are nine levels in this list, let's try them all. + for (int i = 0; i < 9; i++) + { + builder.getListFormat().setListLevelNumber(i); + builder.writeln("Level " + i); + } + + // Create a bulleted list based on one of the Microsoft Word list templates + // and apply it to the document builder's current paragraph. + builder.getListFormat().setList(doc.getLists().add(ListTemplate.BULLET_DIAMONDS)); + + for (int i = 0; i < 9; i++) + { + builder.getListFormat().setListLevelNumber(i); + builder.writeln("Level " + i); + } + + // This is a way to stop list formatting. + builder.getListFormat().setList(null); + + builder.getDocument().save(getArtifactsDir() + "WorkingWithList.SpecifyListLevel.docx"); + //ExEnd:SpecifyListLevel + } + + @Test + public void restartListNumber() throws Exception + { + //ExStart:RestartListNumber + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Create a list based on a template. + List list1 = doc.getLists().add(ListTemplate.NUMBER_ARABIC_PARENTHESIS); + list1.getListLevels().get(0).getFont().setColor(Color.RED); + list1.getListLevels().get(0).setAlignment(ListLevelAlignment.RIGHT); + + builder.writeln("List 1 starts below:"); + builder.getListFormat().setList(list1); + builder.writeln("Item 1"); + builder.writeln("Item 2"); + builder.getListFormat().removeNumbers(); + + // To reuse the first list, we need to restart numbering by creating a copy of the original list formatting. + List list2 = doc.getLists().addCopy(list1); + + // We can modify the new list in any way, including setting a new start number. + list2.getListLevels().get(0).setStartAt(10); + + builder.writeln("List 2 starts below:"); + builder.getListFormat().setList(list2); + builder.writeln("Item 1"); + builder.writeln("Item 2"); + builder.getListFormat().removeNumbers(); + + builder.getDocument().save(getArtifactsDir() + "WorkingWithList.RestartListNumber.docx"); + //ExEnd:RestartListNumber + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithMarkdown.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithMarkdown.java new file mode 100644 index 00000000..3719ccd1 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithMarkdown.java @@ -0,0 +1,434 @@ +package DocsExamples.Programming_with_Documents; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.Style; +import com.aspose.words.StyleType; +import com.aspose.words.Shape; +import com.aspose.words.Document; +import com.aspose.words.Paragraph; +import com.aspose.words.WarningInfoCollection; +import com.aspose.words.WarningInfo; +import com.aspose.words.WarningSource; +import com.aspose.ms.System.msConsole; + + +class WorkingWithMarkdown extends DocsExamplesBase +{ + @Test + public void boldText() throws Exception + { + //ExStart:BoldText + //GistId:0697355b7f872839932388d269ed6a63 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + // Make the text Bold. + builder.getFont().setBold(true); + builder.writeln("This text will be Bold"); + //ExEnd:BoldText + } + + @Test + public void italicText() throws Exception + { + //ExStart:ItalicText + //GistId:0697355b7f872839932388d269ed6a63 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + // Make the text Italic. + builder.getFont().setItalic(true); + builder.writeln("This text will be Italic"); + //ExEnd:ItalicText + } + + @Test + public void strikethrough() throws Exception + { + //ExStart:Strikethrough + //GistId:0697355b7f872839932388d269ed6a63 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + // Make the text Strikethrough. + builder.getFont().setStrikeThrough(true); + builder.writeln("This text will be StrikeThrough"); + //ExEnd:Strikethrough + } + + @Test + public void inlineCode() throws Exception + { + //ExStart:InlineCode + //GistId:51b4cb9c451832f23527892e19c7bca6 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + // Number of backticks is missed, one backtick will be used by default. + Style inlineCode1BackTicks = builder.getDocument().getStyles().add(StyleType.CHARACTER, "InlineCode"); + builder.getFont().setStyle(inlineCode1BackTicks); + builder.writeln("Text with InlineCode style with 1 backtick"); + + // There will be 3 backticks. + Style inlineCode3BackTicks = builder.getDocument().getStyles().add(StyleType.CHARACTER, "InlineCode.3"); + builder.getFont().setStyle(inlineCode3BackTicks); + builder.writeln("Text with InlineCode style with 3 backtick"); + //ExEnd:InlineCode + } + + @Test + public void autolink() throws Exception + { + //ExStart:Autolink + //GistId:0697355b7f872839932388d269ed6a63 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + // Insert hyperlink. + builder.insertHyperlink("https://www.aspose.com", "https://www.aspose.com", false); + builder.insertHyperlink("email@aspose.com", "mailto:email@aspose.com", false); + //ExEnd:Autolink + } + + @Test + public void link() throws Exception + { + //ExStart:Link + //GistId:0697355b7f872839932388d269ed6a63 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + // Insert hyperlink. + builder.insertHyperlink("Aspose", "https://www.aspose.com", false); + //ExEnd:Link + } + + @Test + public void image() throws Exception + { + //ExStart:Image + //GistId:0697355b7f872839932388d269ed6a63 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + // Insert image. + Shape shape = builder.insertImage(getImagesDir() + "Logo.jpg"); + shape.getImageData().setTitle("title"); + //ExEnd:Image + } + + @Test + public void horizontalRule() throws Exception + { + //ExStart:HorizontalRule + //GistId:0697355b7f872839932388d269ed6a63 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + // Insert horizontal rule. + builder.insertHorizontalRule(); + //ExEnd:HorizontalRule + } + + @Test + public void heading() throws Exception + { + //ExStart:Heading + //GistId:0697355b7f872839932388d269ed6a63 + // Use a document builder to add content to the document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // By default Heading styles in Word may have Bold and Italic formatting. + //If we do not want to be emphasized, set these properties explicitly to false. + builder.getFont().setBold(false); + builder.getFont().setItalic(false); + + builder.writeln("The following produces headings:"); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 1")); + builder.writeln("Heading1"); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 2")); + builder.writeln("Heading2"); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 3")); + builder.writeln("Heading3"); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 4")); + builder.writeln("Heading4"); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 5")); + builder.writeln("Heading5"); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 6")); + builder.writeln("Heading6"); + + // Note, emphases are also allowed inside Headings: + builder.getFont().setBold(true); + builder.getParagraphFormat().setStyle(doc.getStyles().get("Heading 1")); + builder.writeln("Bold Heading1"); + + doc.save(getArtifactsDir() + "WorkingWithMarkdown.Heading.md"); + //ExEnd:Heading + } + + @Test + public void setextHeading() throws Exception + { + //ExStart:SetextHeading + //GistId:0697355b7f872839932388d269ed6a63 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + builder.getParagraphFormat().setStyleName("Heading 1"); + builder.writeln("This is an H1 tag"); + + // Reset styles from the previous paragraph to not combine styles between paragraphs. + builder.getFont().setBold(false); + builder.getFont().setItalic(false); + + Style setexHeading1 = builder.getDocument().getStyles().add(StyleType.PARAGRAPH, "SetextHeading1"); + builder.getParagraphFormat().setStyle(setexHeading1); + builder.getDocument().getStyles().get("SetextHeading1").setBaseStyleName("Heading 1"); + builder.writeln("Setext Heading level 1"); + + builder.getParagraphFormat().setStyle(builder.getDocument().getStyles().get("Heading 3")); + builder.writeln("This is an H3 tag"); + + // Reset styles from the previous paragraph to not combine styles between paragraphs. + builder.getFont().setBold(false); + builder.getFont().setItalic(false); + + Style setexHeading2 = builder.getDocument().getStyles().add(StyleType.PARAGRAPH, "SetextHeading2"); + builder.getParagraphFormat().setStyle(setexHeading2); + builder.getDocument().getStyles().get("SetextHeading2").setBaseStyleName("Heading 3"); + + // Setex heading level will be reset to 2 if the base paragraph has a Heading level greater than 2. + builder.writeln("Setext Heading level 2"); + //ExEnd:SetextHeading + + builder.getDocument().save(getArtifactsDir() + "WorkingWithMarkdown.SetextHeading.md"); + } + + @Test + public void indentedCode() throws Exception + { + //ExStart:IndentedCode + //GistId:0697355b7f872839932388d269ed6a63 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + Style indentedCode = builder.getDocument().getStyles().add(StyleType.PARAGRAPH, "IndentedCode"); + builder.getParagraphFormat().setStyle(indentedCode); + builder.writeln("This is an indented code"); + //ExEnd:IndentedCode + } + + @Test + public void fencedCode() throws Exception + { + //ExStart:FencedCode + //GistId:0697355b7f872839932388d269ed6a63 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + Style fencedCode = builder.getDocument().getStyles().add(StyleType.PARAGRAPH, "FencedCode"); + builder.getParagraphFormat().setStyle(fencedCode); + builder.writeln("This is an fenced code"); + + Style fencedCodeWithInfo = builder.getDocument().getStyles().add(StyleType.PARAGRAPH, "FencedCode.C#"); + builder.getParagraphFormat().setStyle(fencedCodeWithInfo); + builder.writeln("This is a fenced code with info string"); + //ExEnd:FencedCode + } + + @Test + public void quote() throws Exception + { + //ExStart:Quote + //GistId:0697355b7f872839932388d269ed6a63 + // Use a document builder to add content to the document. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // By default a document stores blockquote style for the first level. + builder.getParagraphFormat().setStyleName("Quote"); + builder.writeln("Blockquote"); + + // Create styles for nested levels through style inheritance. + Style quoteLevel2 = builder.getDocument().getStyles().add(StyleType.PARAGRAPH, "Quote1"); + builder.getParagraphFormat().setStyle(quoteLevel2); + builder.getDocument().getStyles().get("Quote1").setBaseStyleName("Quote"); + builder.writeln("1. Nested blockquote"); + + doc.save(getArtifactsDir() + "WorkingWithMarkdown.Quote.md"); + //ExEnd:Quote + } + + @Test + public void bulletedList() throws Exception + { + //ExStart:BulletedList + //GistId:0697355b7f872839932388d269ed6a63 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + builder.getListFormat().applyBulletDefault(); + builder.getListFormat().getList().getListLevels().get(0).setNumberFormat("-"); + + builder.writeln("Item 1"); + builder.writeln("Item 2"); + + builder.getListFormat().listIndent(); + + builder.writeln("Item 2a"); + builder.writeln("Item 2b"); + //ExEnd:BulletedList + } + + @Test + public void orderedList() throws Exception + { + //ExStart:OrderedList + //GistId:0697355b7f872839932388d269ed6a63 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getListFormat().applyNumberDefault(); + + builder.writeln("Item 1"); + builder.writeln("Item 2"); + + builder.getListFormat().listIndent(); + + builder.writeln("Item 2a"); + builder.writeln("Item 2b"); + //ExEnd:OrderedList + } + + @Test + public void table() throws Exception + { + //ExStart:Table + //GistId:0697355b7f872839932388d269ed6a63 + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(); + + // Add the first row. + builder.insertCell(); + builder.writeln("a"); + builder.insertCell(); + builder.writeln("b"); + + builder.endRow(); + + // Add the second row. + builder.insertCell(); + builder.writeln("c"); + builder.insertCell(); + builder.writeln("d"); + //ExEnd:Table + } + + @Test + public void readMarkdownDocument() throws Exception + { + //ExStart:ReadMarkdownDocument + //GistId:19de942ef8827201c1dca99f76c59133 + Document doc = new Document(getMyDir() + "Quotes.md"); + + // Let's remove Heading formatting from a Quote in the very last paragraph. + Paragraph paragraph = doc.getFirstSection().getBody().getLastParagraph(); + paragraph.getParagraphFormat().setStyle(doc.getStyles().get("Quote")); + + doc.save(getArtifactsDir() + "WorkingWithMarkdown.ReadMarkdownDocument.md"); + //ExEnd:ReadMarkdownDocument + } + + @Test + public void emphases() throws Exception + { + //ExStart:Emphases + //GistId:19de942ef8827201c1dca99f76c59133 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Markdown treats asterisks (*) and underscores (_) as indicators of emphasis."); + builder.write("You can write "); + + builder.getFont().setBold(true); + builder.write("bold"); + + builder.getFont().setBold(false); + builder.write(" or "); + + builder.getFont().setItalic(true); + builder.write("italic"); + + builder.getFont().setItalic(false); + builder.writeln(" text. "); + + builder.write("You can also write "); + builder.getFont().setBold(true); + + builder.getFont().setItalic(true); + builder.write("BoldItalic"); + + builder.getFont().setBold(false); + builder.getFont().setItalic(false); + builder.write("text."); + + builder.getDocument().save(getArtifactsDir() + "WorkingWithMarkdown.Emphases.md"); + //ExEnd:Emphases + } + + @Test + public void useWarningSource() throws Exception + { + //ExStart:UseWarningSourceMarkdown + Document doc = new Document(getMyDir() + "Emphases markdown warning.docx"); + + WarningInfoCollection warnings = new WarningInfoCollection(); + doc.setWarningCallback(warnings); + + doc.save(getArtifactsDir() + "WorkingWithMarkdown.UseWarningSource.md"); + + for (WarningInfo warningInfo : warnings) + { + if (warningInfo.getSource() == WarningSource.MARKDOWN) + System.out.println(warningInfo.getDescription()); + } + //ExEnd:UseWarningSourceMarkdown + } + + @Test + public void supportedFeatures() throws Exception + { + //ExStart:SupportedFeatures + //GistId:51b4cb9c451832f23527892e19c7bca6 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Specify the "Heading 1" style for the paragraph. + builder.insertParagraph(); + builder.getParagraphFormat().setStyleName("Heading 1"); + builder.write("Heading 1"); + + // Specify the Italic emphasis for the paragraph. + builder.insertParagraph(); + // Reset styles from the previous paragraph to not combine styles between paragraphs. + builder.getParagraphFormat().setStyleName("Normal"); + builder.getFont().setItalic(true); + builder.write("Italic Text"); + // Reset styles from the previous paragraph to not combine styles between paragraphs. + builder.setItalic(false); + + // Specify a Hyperlink for the desired text. + builder.insertParagraph(); + builder.insertHyperlink("Aspose", "https://www.aspose.com", false); + builder.write("Aspose"); + + // Save your document as a Markdown file. + doc.save(getArtifactsDir() + "WorkingWithMarkdown.SupportedFeatures.md"); + //ExEnd:SupportedFeatures + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithNode.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithNode.java new file mode 100644 index 00000000..df9d9bc4 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithNode.java @@ -0,0 +1,152 @@ +package DocsExamples.Programming_with_Documents; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.NodeType; +import com.aspose.words.Node; +import com.aspose.ms.System.msConsole; +import com.aspose.words.Paragraph; +import com.aspose.words.NodeCollection; +import com.aspose.words.Run; +import com.aspose.words.CompositeNode; +import com.aspose.words.Section; +import com.aspose.words.Body; +import com.aspose.words.TableCollection; +import com.aspose.words.Table; + + +class WorkingWithNode extends DocsExamplesBase +{ + @Test + public void getNodeType() throws Exception + { + //ExStart:GetNodeType + //GistId:3e9d92093b2f5995f984791bfc10c944 + Document doc = new Document(); + /*NodeType*/int type = doc.getNodeType(); + //ExEnd:GetNodeType + } + + @Test + public void getParentNode() throws Exception + { + //ExStart:GetParentNode + //GistId:3e9d92093b2f5995f984791bfc10c944 + Document doc = new Document(); + // The section is the first child node of the document. + Node section = doc.getFirstChild(); + // The section's parent node is the document. + System.out.println("Section parent is the document: " + (doc == section.getParentNode())); + //ExEnd:GetParentNode + } + + @Test + public void ownerDocument() throws Exception + { + //ExStart:OwnerDocument + //GistId:3e9d92093b2f5995f984791bfc10c944 + Document doc = new Document(); + + // Creating a new node of any type requires a document passed into the constructor. + Paragraph para = new Paragraph(doc); + // The new paragraph node does not yet have a parent. + System.out.println("Paragraph has no parent node: " + (para.getParentNode() == null)); + // But the paragraph node knows its document. + System.out.println("Both nodes' documents are the same: " + (para.getDocument() == doc)); + // The fact that a node always belongs to a document allows us to access and modify + // properties that reference the document-wide data, such as styles or lists. + para.getParagraphFormat().setStyleName("Heading 1"); + // Now add the paragraph to the main text of the first section. + doc.getFirstSection().getBody().appendChild(para); + + // The paragraph node is now a child of the Body node. + System.out.println("Paragraph has a parent node: " + (para.getParentNode() != null)); + //ExEnd:OwnerDocument + } + + @Test + public void enumerateChildNodes() throws Exception + { + //ExStart:EnumerateChildNodes + //GistId:3e9d92093b2f5995f984791bfc10c944 + Document doc = new Document(); + Paragraph paragraph = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 0, true); + + NodeCollection children = paragraph.getChildNodes(NodeType.ANY, false); + for (Node child : (Iterable) children) + { + // A paragraph may contain children of various types such as runs, shapes, and others. + if (child.getNodeType() == NodeType.RUN) + { + Run run = (Run) child; + System.out.println(run.getText()); + } + } + //ExEnd:EnumerateChildNodes + } + + @Test + //ExStart:RecurseAllNodes + //GistId:3e9d92093b2f5995f984791bfc10c944 + public void recurseAllNodes() throws Exception + { + Document doc = new Document(getMyDir() + "Paragraphs.docx"); + // Invoke the recursive function that will walk the tree. + traverseAllNodes(doc); + } + + /// + /// A simple function that will walk through all children of a specified node recursively + /// and print the type of each node to the screen. + /// + public void traverseAllNodes(CompositeNode parentNode) + { + // This is the most efficient way to loop through immediate children of a node. + for (Node childNode = parentNode.getFirstChild(); childNode != null; childNode = childNode.getNextSibling()) + { + System.out.println(Node.nodeTypeToString(childNode.getNodeType())); + + // Recurse into the node if it is a composite node. + if (childNode.isComposite()) + traverseAllNodes((CompositeNode) childNode); + } + } + //ExEnd:RecurseAllNodes + + @Test + public void typedAccess() throws Exception + { + //ExStart:TypedAccess + //GistId:3e9d92093b2f5995f984791bfc10c944 + Document doc = new Document(); + + Section section = doc.getFirstSection(); + Body body = section.getBody(); + // Quick typed access to all Table child nodes contained in the Body. + TableCollection tables = body.getTables(); + for (Table table : (Iterable) tables) + { + // Quick typed access to the first row of the table. + table.getFirstRow()?.Remove(); + // Quick typed access to the last row of the table. + table.getLastRow()?.Remove(); + } + //ExEnd:TypedAccess + } + + @Test + public void createAndAddParagraphNode() throws Exception + { + //ExStart:CreateAndAddParagraphNode + Document doc = new Document(); + + Paragraph para = new Paragraph(doc); + + Section section = doc.getLastSection(); + section.getBody().appendChild(para); + //ExEnd:CreateAndAddParagraphNode + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithOleObjectsAndActiveX.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithOleObjectsAndActiveX.java new file mode 100644 index 00000000..8148a858 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithOleObjectsAndActiveX.java @@ -0,0 +1,172 @@ +package DocsExamples.Programming_with_Documents; + +// ********* THIS FILE IS AUTO PORTED ********* + +import com.aspose.ms.System.msString; +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.ms.System.IO.File; +import com.aspose.ms.System.IO.Stream; +import com.aspose.ms.System.IO.MemoryStream; +import com.aspose.words.Shape; +import com.aspose.words.OlePackage; +import com.aspose.words.NodeType; +import com.aspose.words.OleControl; +import com.aspose.words.Forms2OleControl; +import com.aspose.ms.System.msConsole; + + +class WorkingWithOleObjectsAndActiveX extends DocsExamplesBase +{ + @Test + public void insertOleObject() throws Exception + { + //ExStart:InsertOleObject + //GistId:4996b573cf231d9f66ab0d1f3f981222 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertOleObjectInternal("http://www.aspose.com", "htmlfile", true, true, null); + + doc.save(getArtifactsDir() + "WorkingWithOleObjectsAndActiveX.InsertOleObject.docx"); + //ExEnd:InsertOleObject + } + + @Test + public void insertOleObjectWithOlePackage() throws Exception + { + //ExStart:InsertOleObjectwithOlePackage + //GistId:4996b573cf231d9f66ab0d1f3f981222 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + byte[] bs = File.readAllBytes(getMyDir() + "Zip file.zip"); + Stream stream = new MemoryStream(bs); + try /*JAVA: was using*/ + { + Shape shape = builder.insertOleObjectInternal(stream, "Package", true, null); + OlePackage olePackage = shape.getOleFormat().getOlePackage(); + olePackage.setFileName("filename.zip"); + olePackage.setDisplayName("displayname.zip"); + + doc.save(getArtifactsDir() + "WorkingWithOleObjectsAndActiveX.InsertOleObjectWithOlePackage.docx"); + } + finally { if (stream != null) stream.close(); } + //ExEnd:InsertOleObjectwithOlePackage + + //ExStart:GetAccessToOleObjectRawData + //GistId:4996b573cf231d9f66ab0d1f3f981222 + Shape oleShape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + byte[] oleRawData = oleShape.getOleFormat().getRawData(); + //ExEnd:GetAccessToOleObjectRawData + } + + @Test + public void insertOleObjectAsIcon() throws Exception + { + //ExStart:InsertOleObjectAsIcon + //GistId:4996b573cf231d9f66ab0d1f3f981222 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertOleObjectAsIcon(getMyDir() + "Presentation.pptx", false, getImagesDir() + "Logo icon.ico", + "My embedded file"); + + doc.save(getArtifactsDir() + "WorkingWithOleObjectsAndActiveX.InsertOleObjectAsIcon.docx"); + //ExEnd:InsertOleObjectAsIcon + } + + @Test + public void insertOleObjectAsIconUsingStream() throws Exception + { + //ExStart:InsertOleObjectAsIconUsingStream + //GistId:4996b573cf231d9f66ab0d1f3f981222 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + MemoryStream stream = new MemoryStream(File.readAllBytes(getMyDir() + "Presentation.pptx")); + try /*JAVA: was using*/ + { + builder.insertOleObjectAsIconInternal(stream, "Package", getImagesDir() + "Logo icon.ico", "My embedded file"); + } + finally { if (stream != null) stream.close(); } + + doc.save(getArtifactsDir() + "WorkingWithOleObjectsAndActiveX.InsertOleObjectAsIconUsingStream.docx"); + //ExEnd:InsertOleObjectAsIconUsingStream + } + + @Test + public void readActiveXControlProperties() throws Exception + { + Document doc = new Document(getMyDir() + "ActiveX controls.docx"); + + String properties = ""; + for (Shape shape : (Iterable) doc.getChildNodes(NodeType.SHAPE, true)) + { + if (shape.getOleFormat() instanceof null) break; + + OleControl oleControl = shape.getOleFormat().getOleControl(); + if (oleControl.isForms2OleControl()) + { + Forms2OleControl checkBox = (Forms2OleControl) oleControl; + properties = properties + "\nCaption: " + checkBox.getCaption(); + properties = properties + "\nValue: " + checkBox.getValue(); + properties = properties + "\nEnabled: " + checkBox.getEnabled(); + properties = properties + "\nType: " + checkBox.getType(); + if (checkBox.getChildNodes() != null) + { + properties = properties + "\nChildNodes: " + checkBox.getChildNodes(); + } + + properties = msString.plusEqOperator(properties, "\n"); + } + } + + properties = properties + "\nTotal ActiveX Controls found: " + doc.getChildNodes(NodeType.SHAPE, true).getCount(); + System.out.println("\n" + properties); + } + + @Test + public void insertOnlineVideo() throws Exception + { + //ExStart:InsertOnlineVideo + //GistId:4996b573cf231d9f66ab0d1f3f981222 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + String url = "https://youtu.be/t_1LYZ102RA"; + double width = 360.0; + double height = 270.0; + + Shape shape = builder.insertOnlineVideo(url, width, height); + + doc.save(getArtifactsDir() + "WorkingWithOleObjectsAndActiveX.InsertOnlineVideo.docx"); + //ExEnd:InsertOnlineVideo + } + + @Test + public void insertOnlineVideoWithEmbedHtml() throws Exception + { + //ExStart:InsertOnlineVideoWithEmbedHtml + //GistId:4996b573cf231d9f66ab0d1f3f981222 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + double width = 360.0; + double height = 270.0; + + String videoUrl = "https://vimeo.com/52477838"; + String videoEmbedCode = + ""; + + byte[] thumbnailImageBytes = File.readAllBytes(getImagesDir() + "Logo.jpg"); + + builder.insertOnlineVideo(videoUrl, videoEmbedCode, thumbnailImageBytes, width, height); + + doc.save(getArtifactsDir() + "WorkingWithOleObjectsAndActiveX.InsertOnlineVideoWithEmbedHtml.docx"); + //ExEnd:InsertOnlineVideoWithEmbedHtml + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithRevisions.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithRevisions.java new file mode 100644 index 00000000..78e69890 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithRevisions.java @@ -0,0 +1,288 @@ +package DocsExamples.Programming_with_Documents; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.Body; +import com.aspose.words.Paragraph; +import com.aspose.words.Run; +import java.util.Date; +import com.aspose.ms.System.DateTime; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.ParagraphCollection; +import com.aspose.ms.System.msConsole; +import com.aspose.words.RevisionGroup; +import com.aspose.words.CommentDisplayMode; +import com.aspose.words.ShowInBalloons; +import com.aspose.words.MeasurementUnits; +import com.aspose.words.HorizontalAlignment; +import com.aspose.words.Revision; +import com.aspose.words.SaveFormat; +import com.aspose.words.RevisionsView; +import com.aspose.words.NodeType; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.Node; +import com.aspose.words.Shape; +import com.aspose.words.ShapeType; +import com.aspose.words.WrapType; +import java.util.ArrayList; + + +class WorkingWithRevisions extends DocsExamplesBase +{ + @Test + public void acceptRevisions() throws Exception + { + //ExStart:AcceptAllRevisions + //GistId:e8d71fde166d275d0fc9471c56c3ad39 + Document doc = new Document(); + Body body = doc.getFirstSection().getBody(); + Paragraph para = body.getFirstParagraph(); + + // Add text to the first paragraph, then add two more paragraphs. + para.appendChild(new Run(doc, "Paragraph 1. ")); + body.appendParagraph("Paragraph 2. "); + body.appendParagraph("Paragraph 3. "); + + // We have three paragraphs, none of which registered as any type of revision + // If we add/remove any content in the document while tracking revisions, + // they will be displayed as such in the document and can be accepted/rejected. + doc.startTrackRevisionsInternal("John Doe", new Date); + + // This paragraph is a revision and will have the according "IsInsertRevision" flag set. + para = body.appendParagraph("Paragraph 4. "); + Assert.assertTrue(para.isInsertRevision()); + + // Get the document's paragraph collection and remove a paragraph. + ParagraphCollection paragraphs = body.getParagraphs(); + Assert.assertEquals(4, paragraphs.getCount()); + para = paragraphs.get(2); + para.remove(); + + // Since we are tracking revisions, the paragraph still exists in the document, will have the "IsDeleteRevision" set + // and will be displayed as a revision in Microsoft Word, until we accept or reject all revisions. + Assert.assertEquals(4, paragraphs.getCount()); + Assert.assertTrue(para.isDeleteRevision()); + + // The delete revision paragraph is removed once we accept changes. + doc.acceptAllRevisions(); + Assert.assertEquals(3, paragraphs.getCount()); + Assert.isEmpty(para); + + // Stopping the tracking of revisions makes this text appear as normal text. + // Revisions are not counted when the document is changed. + doc.stopTrackRevisions(); + + // Save the document. + doc.save(getArtifactsDir() + "WorkingWithRevisions.AcceptRevisions.docx"); + //ExEnd:AcceptAllRevisions + } + + @Test + public void getRevisionTypes() throws Exception + { + //ExStart:GetRevisionTypes + Document doc = new Document(getMyDir() + "Revisions.docx"); + + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + for (int i = 0; i < paragraphs.getCount(); i++) + { + if (paragraphs.get(i).isMoveFromRevision()) + System.out.println("The paragraph {0} has been moved (deleted).",i); + if (paragraphs.get(i).isMoveToRevision()) + System.out.println("The paragraph {0} has been moved (inserted).",i); + } + //ExEnd:GetRevisionTypes + } + + @Test + public void getRevisionGroups() throws Exception + { + //ExStart:GetRevisionGroups + Document doc = new Document(getMyDir() + "Revisions.docx"); + + for (RevisionGroup group : doc.getRevisions().getGroups()) + { + System.out.println("{0}, {1}:",group.getAuthor(),group.getRevisionType()); + System.out.println(group.getText()); + } + //ExEnd:GetRevisionGroups + } + + @Test + public void removeCommentsInPdf() throws Exception + { + //ExStart:RemoveCommentsInPDF + Document doc = new Document(getMyDir() + "Revisions.docx"); + + // Do not render the comments in PDF. + doc.getLayoutOptions().setCommentDisplayMode(CommentDisplayMode.HIDE); + + doc.save(getArtifactsDir() + "WorkingWithRevisions.RemoveCommentsInPdf.pdf"); + //ExEnd:RemoveCommentsInPDF + } + + @Test + public void showRevisionsInBalloons() throws Exception + { + //ExStart:ShowRevisionsInBalloons + //GistId:ce015d9bade4e0294485ffb47462ded4 + //ExStart:SetMeasurementUnit + //ExStart:SetRevisionBarsPosition + Document doc = new Document(getMyDir() + "Revisions.docx"); + + // Renders insert revisions inline, delete and format revisions in balloons. + doc.getLayoutOptions().getRevisionOptions().setShowInBalloons(ShowInBalloons.FORMAT_AND_DELETE); + doc.getLayoutOptions().getRevisionOptions().setMeasurementUnit(MeasurementUnits.INCHES); + // Renders revision bars on the right side of a page. + doc.getLayoutOptions().getRevisionOptions().setRevisionBarsPosition(HorizontalAlignment.RIGHT); + + doc.save(getArtifactsDir() + "WorkingWithRevisions.ShowRevisionsInBalloons.pdf"); + //ExEnd:SetRevisionBarsPosition + //ExEnd:SetMeasurementUnit + //ExEnd:ShowRevisionsInBalloons + } + + @Test + public void getRevisionGroupDetails() throws Exception + { + //ExStart:GetRevisionGroupDetails + Document doc = new Document(getMyDir() + "Revisions.docx"); + + for (Revision revision : doc.getRevisions()) + { + String groupText = revision.getGroup() != null + ? "Revision group text: " + revision.getGroup().getText() + : "Revision has no group"; + + System.out.println("Type: " + revision.getRevisionType()); + System.out.println("Author: " + revision.getAuthor()); + System.out.println("Date: " + revision.getDateTimeInternal()); + System.out.println("Revision text: " + revision.getParentNode().toString(SaveFormat.TEXT)); + System.out.println(groupText); + } + //ExEnd:GetRevisionGroupDetails + } + + @Test + public void accessRevisedVersion() throws Exception + { + //ExStart:AccessRevisedVersion + Document doc = new Document(getMyDir() + "Revisions.docx"); + doc.updateListLabels(); + + // Switch to the revised version of the document. + doc.setRevisionsView(RevisionsView.FINAL); + + for (Revision revision : doc.getRevisions()) + { + if (revision.getParentNode().getNodeType() == NodeType.PARAGRAPH) + { + Paragraph paragraph = (Paragraph) revision.getParentNode(); + if (paragraph.isListItem()) + { + System.out.println(paragraph.getListLabel().getLabelString()); + System.out.println(paragraph.getListFormat().getListLevel()); + } + } + } + //ExEnd:AccessRevisedVersion + } + + @Test + public void moveNodeInTrackedDocument() throws Exception + { + //ExStart:MoveNodeInTrackedDocument + //GistId:e8d71fde166d275d0fc9471c56c3ad39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Paragraph 1"); + builder.writeln("Paragraph 2"); + builder.writeln("Paragraph 3"); + builder.writeln("Paragraph 4"); + builder.writeln("Paragraph 5"); + builder.writeln("Paragraph 6"); + Body body = doc.getFirstSection().getBody(); + System.out.println("Paragraph count: {0}",body.getParagraphs().getCount()); + + // Start tracking revisions. + doc.startTrackRevisionsInternal("Author", new DateTime(2020, 12, 23, 14, 0, 0)); + + // Generate revisions when moving a node from one location to another. + Node node = body.getParagraphs().get(3); + Node endNode = body.getParagraphs().get(5).getNextSibling(); + Node referenceNode = body.getParagraphs().get(0); + while (node != endNode) + { + Node nextNode = node.getNextSibling(); + body.insertBefore(node, referenceNode); + node = nextNode; + } + + // Stop the process of tracking revisions. + doc.stopTrackRevisions(); + + // There are 3 additional paragraphs in the move-from range. + System.out.println("Paragraph count: {0}",body.getParagraphs().getCount()); + doc.save(getArtifactsDir() + "WorkingWithRevisions.MoveNodeInTrackedDocument.docx"); + //ExEnd:MoveNodeInTrackedDocument + } + + @Test + public void shapeRevision() throws Exception + { + //ExStart:ShapeRevision + //GistId:e8d71fde166d275d0fc9471c56c3ad39 + Document doc = new Document(); + + // Insert an inline shape without tracking revisions. + Assert.assertFalse(doc.getTrackRevisions()); + Shape shape = new Shape(doc, ShapeType.CUBE); + shape.setWrapType(WrapType.INLINE); + shape.setWidth(100.0); + shape.setHeight(100.0); + doc.getFirstSection().getBody().getFirstParagraph().appendChild(shape); + + // Start tracking revisions and then insert another shape. + doc.startTrackRevisions("John Doe"); + shape = new Shape(doc, ShapeType.SUN); + shape.setWrapType(WrapType.INLINE); + shape.setWidth(100.0); + shape.setHeight(100.0); + doc.getFirstSection().getBody().getFirstParagraph().appendChild(shape); + + // Get the document's shape collection which includes just the two shapes we added. + ArrayList shapes = doc.getChildNodes(NodeType.SHAPE, true).Cast().ToList(); + Assert.assertEquals(2, shapes.size()); + + // Remove the first shape. + shapes.get(0).remove(); + + // Because we removed that shape while changes were being tracked, the shape counts as a delete revision. + Assert.assertEquals(ShapeType.CUBE, shapes.get(0).getShapeType()); + Assert.assertTrue(shapes.get(0).isDeleteRevision()); + + // And we inserted another shape while tracking changes, so that shape will count as an insert revision. + Assert.assertEquals(ShapeType.SUN, shapes.get(1).getShapeType()); + Assert.assertTrue(shapes.get(1).isInsertRevision()); + + // The document has one shape that was moved, but shape move revisions will have two instances of that shape. + // One will be the shape at its arrival destination and the other will be the shape at its original location. + doc = new Document(getMyDir() + "Revision shape.docx"); + + shapes = doc.getChildNodes(NodeType.SHAPE, true).Cast().ToList(); + Assert.assertEquals(2, shapes.size()); + + // This is the move to revision, also the shape at its arrival destination. + Assert.assertFalse(shapes.get(0).isMoveFromRevision()); + Assert.assertTrue(shapes.get(0).isMoveToRevision()); + + // This is the move from revision, which is the shape at its original location. + Assert.assertTrue(shapes.get(1).isMoveFromRevision()); + Assert.assertFalse(shapes.get(1).isMoveToRevision()); + //ExEnd:ShapeRevision + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithSection.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithSection.java new file mode 100644 index 00000000..b1f54a61 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithSection.java @@ -0,0 +1,261 @@ +package DocsExamples.Programming_with_Documents; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.Section; +import com.aspose.words.BreakType; +import com.aspose.words.PaperSize; +import com.aspose.words.HeaderFooterType; +import com.aspose.words.Node; +import com.aspose.words.NodeType; +import com.aspose.words.Body; +import com.aspose.ms.System.msConsole; +import com.aspose.words.HeaderFooter; +import com.aspose.words.Run; + + +class WorkingWithSection extends DocsExamplesBase +{ + @Test + public void addSection() throws Exception + { + //ExStart:AddSection + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello1"); + builder.writeln("Hello2"); + + Section sectionToAdd = new Section(doc); + doc.getSections().add(sectionToAdd); + //ExEnd:AddSection + } + + @Test + public void deleteSection() throws Exception + { + //ExStart:DeleteSection + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello1"); + doc.appendChild(new Section(doc)); + builder.writeln("Hello2"); + doc.appendChild(new Section(doc)); + + doc.getSections().removeAt(0); + //ExEnd:DeleteSection + } + + @Test + public void deleteAllSections() throws Exception + { + //ExStart:DeleteAllSections + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Hello1"); + doc.appendChild(new Section(doc)); + builder.writeln("Hello2"); + doc.appendChild(new Section(doc)); + + doc.getSections().clear(); + //ExEnd:DeleteAllSections + } + + @Test + public void appendSectionContent() throws Exception + { + //ExStart:AppendSectionContent + //GistId:1afca4d3da7cb4240fb91c3d93d8c30d + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Section 1"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.write("Section 2"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.write("Section 3"); + + Section section = doc.getSections().get(2); + + // Insert the contents of the first section to the beginning of the third section. + Section sectionToPrepend = doc.getSections().get(0); + section.prependContent(sectionToPrepend); + + // Insert the contents of the second section to the end of the third section. + Section sectionToAppend = doc.getSections().get(1); + section.appendContent(sectionToAppend); + //ExEnd:AppendSectionContent + } + + @Test + public void cloneSection() throws Exception + { + //ExStart:CloneSection + //GistId:1afca4d3da7cb4240fb91c3d93d8c30d + Document doc = new Document(getMyDir() + "Document.docx"); + Section cloneSection = doc.getSections().get(0).deepClone(); + //ExEnd:CloneSection + } + + @Test + public void copySection() throws Exception + { + //ExStart:CopySection + //GistId:1afca4d3da7cb4240fb91c3d93d8c30d + Document srcDoc = new Document(getMyDir() + "Document.docx"); + Document dstDoc = new Document(); + + Section sourceSection = srcDoc.getSections().get(0); + Section newSection = (Section)dstDoc.importNode(sourceSection, true); + dstDoc.getSections().add(newSection); + + dstDoc.save(getArtifactsDir() + "WorkingWithSection.CopySection.docx"); + //ExEnd:CopySection + } + + @Test + public void deleteHeaderFooterContent() throws Exception + { + //ExStart:DeleteHeaderFooterContent + //GistId:1afca4d3da7cb4240fb91c3d93d8c30d + Document doc = new Document(getMyDir() + "Document.docx"); + + Section section = doc.getSections().get(0); + section.clearHeadersFooters(); + //ExEnd:DeleteHeaderFooterContent + } + + @Test + public void deleteHeaderFooterShapes() throws Exception + { + //ExStart:DeleteHeaderFooterShapes + //GistId:1afca4d3da7cb4240fb91c3d93d8c30d + Document doc = new Document(getMyDir() + "Document.docx"); + + Section section = doc.getSections().get(0); + section.deleteHeaderFooterShapes(); + //ExEnd:DeleteHeaderFooterShapes + } + + @Test + public void deleteSectionContent() throws Exception + { + //ExStart:DeleteSectionContent + Document doc = new Document(getMyDir() + "Document.docx"); + + Section section = doc.getSections().get(0); + section.clearContent(); + //ExEnd:DeleteSectionContent + } + + @Test + public void modifyPageSetupInAllSections() throws Exception + { + //ExStart:ModifyPageSetupInAllSections + //GistId:1afca4d3da7cb4240fb91c3d93d8c30d + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Section 1"); + doc.appendChild(new Section(doc)); + builder.writeln("Section 2"); + doc.appendChild(new Section(doc)); + builder.writeln("Section 3"); + doc.appendChild(new Section(doc)); + builder.writeln("Section 4"); + + // It is important to understand that a document can contain many sections, + // and each section has its page setup. In this case, we want to modify them all. + for (Section section : (Iterable
          ) doc) + section.getPageSetup().setPaperSize(PaperSize.LETTER); + + doc.save(getArtifactsDir() + "WorkingWithSection.ModifyPageSetupInAllSections.doc"); + //ExEnd:ModifyPageSetupInAllSections + } + + @Test + public void sectionsAccessByIndex() throws Exception + { + //ExStart:SectionsAccessByIndex + Document doc = new Document(getMyDir() + "Document.docx"); + + Section section = doc.getSections().get(0); + section.getPageSetup().setLeftMargin(90.0); // 3.17 cm + section.getPageSetup().setRightMargin(90.0); // 3.17 cm + section.getPageSetup().setTopMargin(72.0); // 2.54 cm + section.getPageSetup().setBottomMargin(72.0); // 2.54 cm + section.getPageSetup().setHeaderDistance(35.4); // 1.25 cm + section.getPageSetup().setFooterDistance(35.4); // 1.25 cm + section.getPageSetup().getTextColumns().setSpacing(35.4); // 1.25 cm + //ExEnd:SectionsAccessByIndex + } + + @Test + public void sectionChildNodes() throws Exception + { + //ExStart:SectionChildNodes + //GistId:1afca4d3da7cb4240fb91c3d93d8c30d + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Section 1"); + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.write("Primary header"); + builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); + builder.write("Primary footer"); + + Section section = doc.getFirstSection(); + + // A Section is a composite node and can contain child nodes, + // but only if those child nodes are of a "Body" or "HeaderFooter" node type. + for (Node node : (Iterable) section) + { + switch (node.getNodeType()) + { + case NodeType.BODY: + { + Body body = (Body)node; + + System.out.println("Body:"); + System.out.println("\t\"{body.GetText().Trim()}\""); + break; + } + case NodeType.HEADER_FOOTER: + { + HeaderFooter headerFooter = (HeaderFooter)node; + + System.out.println("HeaderFooter type: {headerFooter.HeaderFooterType}:"); + System.out.println("\t\"{headerFooter.GetText().Trim()}\""); + break; + } + default: + { + throw new Exception("Unexpected node type in a section."); + } + } + } + //ExEnd:SectionChildNodes + } + + @Test + public void ensureMinimum() throws Exception + { + //ExStart:EnsureMinimum + //GistId:1afca4d3da7cb4240fb91c3d93d8c30d + Document doc = new Document(); + + // If we add a new section like this, it will not have a body, or any other child nodes. + doc.getSections().add(new Section(doc)); + // Run the "EnsureMinimum" method to add a body and a paragraph to this section to begin editing it. + doc.getLastSection().ensureMinimum(); + + doc.getSections().get(0).getBody().getFirstParagraph().appendChild(new Run(doc, "Hello world!")); + //ExEnd:EnsureMinimum + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithTextboxes.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithTextboxes.java new file mode 100644 index 00000000..a9c29670 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithTextboxes.java @@ -0,0 +1,74 @@ +package DocsExamples.Programming_with_Documents; + +// ********* THIS FILE IS AUTO PORTED ********* + +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.Shape; +import com.aspose.words.ShapeType; +import com.aspose.words.TextBox; +import com.aspose.ms.System.msConsole; + + +class WorkingWithTextboxes +{ + @Test + public void createLink() throws Exception + { + //ExStart:CreateLink + //GistId:68b6041746b3d6bf5137cff8e6385b5f + Document doc = new Document(); + + Shape shape1 = new Shape(doc, ShapeType.TEXT_BOX); + Shape shape2 = new Shape(doc, ShapeType.TEXT_BOX); + + TextBox textBox1 = shape1.getTextBox(); + TextBox textBox2 = shape2.getTextBox(); + + if (textBox1.isValidLinkTarget(textBox2)) + textBox1.setNext(textBox2); + //ExEnd:CreateLink + } + + @Test + public void checkSequence() throws Exception + { + //ExStart:CheckSequence + //GistId:68b6041746b3d6bf5137cff8e6385b5f + Document doc = new Document(); + + Shape shape = new Shape(doc, ShapeType.TEXT_BOX); + TextBox textBox = shape.getTextBox(); + + if (textBox.getNext() != null && textBox.getPrevious() == null) + System.out.println("The head of the sequence"); + + if (textBox.getNext() != null && textBox.getPrevious() != null) + System.out.println("The Middle of the sequence."); + + if (textBox.getNext() == null && textBox.getPrevious() != null) + System.out.println("The Tail of the sequence."); + //ExEnd:CheckSequence + } + + @Test + public void breakLink() throws Exception + { + //ExStart:BreakLink + //GistId:68b6041746b3d6bf5137cff8e6385b5f + Document doc = new Document(); + + Shape shape = new Shape(doc, ShapeType.TEXT_BOX); + TextBox textBox = shape.getTextBox(); + + // Break a forward link. + textBox.breakForwardLink(); + + // Break a forward link by setting a null. + textBox.setNext(null); + + // Break a link, which leads to this textbox. + textBox.getPrevious()?.BreakForwardLink(); + //ExEnd:BreakLink + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithVBAMacros.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithVBAMacros.java new file mode 100644 index 00000000..346a44dd --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/WorkingWithVBAMacros.java @@ -0,0 +1,176 @@ +package DocsExamples.Programming_with_Documents; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.VbaProject; +import com.aspose.words.VbaModule; +import com.aspose.words.VbaModuleType; +import com.aspose.ms.System.msConsole; +import com.aspose.words.VbaReferenceCollection; +import com.aspose.words.VbaReference; +import com.aspose.words.VbaReferenceType; +import com.aspose.ms.System.msString; + + +class WorkingWithVba extends DocsExamplesBase +{ + @Test + public void createVbaProject() throws Exception + { + //ExStart:CreateVbaProject + //GistId:d9bac4ed890f81ea3de392ecfeedbc55 + Document doc = new Document(); + + VbaProject project = new VbaProject(); + project.setName("AsposeProject"); + doc.setVbaProject(project); + + // Create a new module and specify a macro source code. + VbaModule module = new VbaModule(); + module.setName("AsposeModule"); + module.setType(VbaModuleType.PROCEDURAL_MODULE); + module.setSourceCode("New source code"); + + // Add module to the VBA project. + doc.getVbaProject().getModules().add(module); + + doc.save(getArtifactsDir() + "WorkingWithVba.CreateVbaProject.docm"); + //ExEnd:CreateVbaProject + } + + @Test + public void readVbaMacros() throws Exception + { + //ExStart:ReadVbaMacros + //GistId:d9bac4ed890f81ea3de392ecfeedbc55 + Document doc = new Document(getMyDir() + "VBA project.docm"); + + if (doc.getVbaProject() != null) + { + for (VbaModule module : doc.getVbaProject().getModules()) + { + System.out.println(module.getSourceCode()); + } + } + //ExEnd:ReadVbaMacros + } + + @Test + public void modifyVbaMacros() throws Exception + { + //ExStart:ModifyVbaMacros + //GistId:d9bac4ed890f81ea3de392ecfeedbc55 + Document doc = new Document(getMyDir() + "VBA project.docm"); + + VbaProject project = doc.getVbaProject(); + + final String NEW_SOURCE_CODE = "Test change source code"; + project.getModules().get(0).setSourceCode(NEW_SOURCE_CODE); + //ExEnd:ModifyVbaMacros + + doc.save(getArtifactsDir() + "WorkingWithVba.ModifyVbaMacros.docm"); + //ExEnd:ModifyVbaMacros + } + + @Test + public void cloneVbaProject() throws Exception + { + //ExStart:CloneVbaProject + //GistId:d9bac4ed890f81ea3de392ecfeedbc55 + Document doc = new Document(getMyDir() + "VBA project.docm"); + Document destDoc = new Document(); { destDoc.setVbaProject(doc.getVbaProject().deepClone()); } + + destDoc.save(getArtifactsDir() + "WorkingWithVba.CloneVbaProject.docm"); + //ExEnd:CloneVbaProject + } + + @Test + public void cloneVbaModule() throws Exception + { + //ExStart:CloneVbaModule + //GistId:d9bac4ed890f81ea3de392ecfeedbc55 + Document doc = new Document(getMyDir() + "VBA project.docm"); + Document destDoc = new Document(); { destDoc.setVbaProject(new VbaProject()); } + + VbaModule copyModule = doc.getVbaProject().getModules().get("Module1").deepClone(); + destDoc.getVbaProject().getModules().add(copyModule); + + destDoc.save(getArtifactsDir() + "WorkingWithVba.CloneVbaModule.docm"); + //ExEnd:CloneVbaModule + } + + @Test + public void removeVbaReferences() throws Exception + { + //ExStart:RemoveVbaReferences + //GistId:d9bac4ed890f81ea3de392ecfeedbc55 + Document doc = new Document(getMyDir() + "VBA project.docm"); + + // Find and remove the reference with some LibId path. + final String BROKEN_PATH = "brokenPath.dll"; + VbaReferenceCollection references = doc.getVbaProject().getReferences(); + for (int i = references.getCount() - 1; i >= 0; i--) + { + VbaReference reference = doc.getVbaProject().getReferences().ElementAt(i); + + String path = getLibIdPath(reference); + if (BROKEN_PATH.equals(path)) + references.removeAt(i); + } + + doc.save(getArtifactsDir() + "WorkingWithVba.RemoveVbaReferences.docm"); + //ExEnd:RemoveVbaReferences + } + //ExStart:GetLibIdAndReferencePath + //GistId:d9bac4ed890f81ea3de392ecfeedbc55 + /// + /// Returns string representing LibId path of a specified reference. + /// + private String getLibIdPath(VbaReference reference) + { + switch (reference.getType()) + { + case VbaReferenceType.REGISTERED: + case VbaReferenceType.ORIGINAL: + case VbaReferenceType.CONTROL: + return getLibIdReferencePath(reference.getLibId()); + case VbaReferenceType.PROJECT: + return getLibIdProjectPath(reference.getLibId()); + default: + throw new IllegalArgumentException(); + } + } + + /// + /// Returns path from a specified identifier of an Automation type library. + /// + /// + /// Please see details for the syntax at [MS-OVBA], 2.1.1.8 LibidReference. + /// + private String getLibIdReferencePath(String libIdReference) + { + if (libIdReference != null) + { + String[] refParts = msString.split(libIdReference, '#'); + if (refParts.length > 3) + return refParts[3]; + } + + return ""; + } + + /// + /// Returns path from a specified identifier of an Automation type library. + /// + /// + /// Please see details for the syntax at [MS-OVBA], 2.1.1.12 ProjectReference. + /// + private String getLibIdProjectPath(String libIdProject) + { + return (libIdProject != null) ? libIdProject.substring(3) : ""; + } + //ExEnd:GetLibIdAndReferencePath +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/AddContentUsingDocumentBuilder.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/AddContentUsingDocumentBuilder.java new file mode 100644 index 00000000..9ed7d15d --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/AddContentUsingDocumentBuilder.java @@ -0,0 +1,627 @@ +package DocsExamples.Programming_with_Documents.Working_with_Document; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.Table; +import com.aspose.words.CellVerticalAlignment; +import com.aspose.words.HeightRule; +import com.aspose.words.TextOrientation; +import com.aspose.words.AutoFitBehavior; +import com.aspose.words.Shape; +import com.aspose.words.HorizontalRuleFormat; +import com.aspose.words.HorizontalRuleAlignment; +import java.awt.Color; +import com.aspose.words.BreakType; +import com.aspose.words.TextFormFieldType; +import com.aspose.words.StyleIdentifier; +import com.aspose.words.RelativeHorizontalPosition; +import com.aspose.words.RelativeVerticalPosition; +import com.aspose.words.WrapType; +import com.aspose.words.Font; +import com.aspose.words.Underline; +import com.aspose.words.ParagraphFormat; +import com.aspose.words.ParagraphAlignment; +import com.aspose.words.FindReplaceOptions; +import com.aspose.ms.System.Drawing.msColor; +import com.aspose.ms.System.Text.RegularExpressions.Regex; +import com.aspose.words.IReplacingCallback; +import com.aspose.words.ReplaceAction; +import com.aspose.words.ReplacingArgs; +import com.aspose.ms.System.msString; +import com.aspose.words.Node; +import com.aspose.words.Paragraph; +import com.aspose.ms.System.msConsole; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.NodeType; +import com.aspose.words.Section; +import com.aspose.words.ParagraphCollection; +import com.aspose.words.HeaderFooterType; +import com.aspose.words.Field; + + +class AddContentUsingDocumentBuilder extends DocsExamplesBase +{ + @Test + public void createNewDocument() throws Exception + { + //ExStart:CreateNewDocument + //GistId:1d626c7186a318d22d022dc96dd91d55 + Document doc = new Document(); + + // Use a document builder to add content to the document. + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("Hello World!"); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.CreateNewDocument.docx"); + //ExEnd:CreateNewDocument + } + + @Test + public void insertBookmark() throws Exception + { + //ExStart:InsertBookmark + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startBookmark("FineBookmark"); + builder.writeln("This is just a fine bookmark."); + builder.endBookmark("FineBookmark"); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertBookmark.docx"); + //ExEnd:InsertBookmark + } + + @Test + public void buildTable() throws Exception + { + //ExStart:BuildTable + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + + builder.getCellFormat().setVerticalAlignment(CellVerticalAlignment.CENTER); + builder.write("This is row 1 cell 1"); + + builder.insertCell(); + builder.write("This is row 1 cell 2"); + + builder.endRow(); + + builder.insertCell(); + + builder.getRowFormat().setHeight(100.0); + builder.getRowFormat().setHeightRule(HeightRule.EXACTLY); + builder.getCellFormat().setOrientation(TextOrientation.UPWARD); + builder.writeln("This is row 2 cell 1"); + + builder.insertCell(); + builder.getCellFormat().setOrientation(TextOrientation.DOWNWARD); + builder.writeln("This is row 2 cell 2"); + + builder.endRow(); + builder.endTable(); + + table.autoFit(AutoFitBehavior.FIXED_COLUMN_WIDTHS); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.BuildTable.docx"); + //ExEnd:BuildTable + } + + @Test + public void insertHorizontalRule() throws Exception + { + //ExStart:InsertHorizontalRule + //GistId:ad463bf5f128fe6e6c1485df3c046a4c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("Insert a horizontal rule shape into the document."); + builder.insertHorizontalRule(); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertHorizontalRule.docx"); + //ExEnd:InsertHorizontalRule + } + + @Test + public void horizontalRuleFormat() throws Exception + { + //ExStart:HorizontalRuleFormat + //GistId:ad463bf5f128fe6e6c1485df3c046a4c + DocumentBuilder builder = new DocumentBuilder(); + + Shape shape = builder.insertHorizontalRule(); + + HorizontalRuleFormat horizontalRuleFormat = shape.getHorizontalRuleFormat(); + horizontalRuleFormat.setAlignment(HorizontalRuleAlignment.CENTER); + horizontalRuleFormat.setWidthPercent(70.0); + horizontalRuleFormat.setHeight(3.0); + horizontalRuleFormat.setColor(Color.BLUE); + horizontalRuleFormat.setNoShade(true); + + builder.getDocument().save(getArtifactsDir() + "AddContentUsingDocumentBuilder.HorizontalRuleFormat.docx"); + //ExEnd:HorizontalRuleFormat + } + + @Test + public void insertBreak() throws Exception + { + //ExStart:InsertBreak + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.writeln("This is page 1."); + builder.insertBreak(BreakType.PAGE_BREAK); + + builder.writeln("This is page 2."); + builder.insertBreak(BreakType.PAGE_BREAK); + + builder.writeln("This is page 3."); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertBreak.docx"); + //ExEnd:InsertBreak + } + + @Test + public void insertTextInputFormField() throws Exception + { + //ExStart:InsertTextInputFormField + //GistId:b09907fef4643433271e4e0e912921b0 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", "Hello", 0); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertTextInputFormField.docx"); + //ExEnd:InsertTextInputFormField + } + + @Test + public void insertCheckBoxFormField() throws Exception + { + //ExStart:InsertCheckBoxFormField + //GistId:b09907fef4643433271e4e0e912921b0 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertCheckBox("CheckBox", true, true, 0); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertCheckBoxFormField.docx"); + //ExEnd:InsertCheckBoxFormField + } + + @Test + public void insertComboBoxFormField() throws Exception + { + //ExStart:InsertComboBoxFormField + //GistId:b09907fef4643433271e4e0e912921b0 + String[] items = { "One", "Two", "Three" }; + + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertComboBox("DropDown", items, 0); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertComboBoxFormField.docx"); + //ExEnd:InsertComboBoxFormField + } + + @Test + public void insertHtml() throws Exception + { + //ExStart:InsertHtml + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertHtml( + "

          Paragraph right

          " + + "Implicit paragraph left" + + "
          Div center
          " + + "

          Heading 1 left.

          "); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertHtml.docx"); + //ExEnd:InsertHtml + } + + @Test + public void insertHyperlink() throws Exception + { + //ExStart:InsertHyperlink + //GistId:0213851d47551e83af42233f4d075cf6 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.write("Please make sure to visit "); + + builder.getFont().setStyle(doc.getStyles().getByStyleIdentifier(StyleIdentifier.HYPERLINK)); + builder.insertHyperlink("Aspose Website", "http://www.aspose.com", false); + builder.getFont().clearFormatting(); + + builder.write(" for more information."); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertHyperlink.docx"); + //ExEnd:InsertHyperlink + } + + @Test + public void insertTableOfContents() throws Exception + { + //ExStart:InsertTableOfContents + //GistId:db118a3e1559b9c88355356df9d7ea10 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertTableOfContents("\\o \"1-3\" \\h \\z \\u"); + + // Start the actual document content on the second page. + builder.insertBreak(BreakType.PAGE_BREAK); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + + builder.writeln("Heading 1"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); + + builder.writeln("Heading 1.1"); + builder.writeln("Heading 1.2"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); + + builder.writeln("Heading 2"); + builder.writeln("Heading 3"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); + + builder.writeln("Heading 3.1"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_3); + + builder.writeln("Heading 3.1.1"); + builder.writeln("Heading 3.1.2"); + builder.writeln("Heading 3.1.3"); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); + + builder.writeln("Heading 3.2"); + builder.writeln("Heading 3.3"); + + //ExStart:UpdateFields + //GistId:db118a3e1559b9c88355356df9d7ea10 + // The newly inserted table of contents will be initially empty. + // It needs to be populated by updating the fields in the document. + doc.updateFields(); + //ExEnd:UpdateFields + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertTableOfContents.docx"); + //ExEnd:InsertTableOfContents + } + + @Test + public void insertInlineImage() throws Exception + { + //ExStart:InsertInlineImage + //GistId:6f849e51240635a6322ab0460938c922 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertImage(getImagesDir() + "Transparent background logo.png"); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertInlineImage.docx"); + //ExEnd:InsertInlineImage + } + + @Test + public void insertFloatingImage() throws Exception + { + //ExStart:InsertFloatingImage + //GistId:6f849e51240635a6322ab0460938c922 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertImage(getImagesDir() + "Transparent background logo.png", + RelativeHorizontalPosition.MARGIN, + 100.0, + RelativeVerticalPosition.MARGIN, + 100.0, + 200.0, + 100.0, + WrapType.SQUARE); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertFloatingImage.docx"); + //ExEnd:InsertFloatingImage + } + + @Test + public void insertParagraph() throws Exception + { + //ExStart:InsertParagraph + //GistId:ecf2c438314e6c8318ca9833c7f62326 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Font font = builder.getFont(); + font.setSize(16.0); + font.setBold(true); + font.setColor(Color.BLUE); + font.setName("Arial"); + font.setUnderline(Underline.DASH); + + ParagraphFormat paragraphFormat = builder.getParagraphFormat(); + paragraphFormat.setFirstLineIndent(8.0); + paragraphFormat.setAlignment(ParagraphAlignment.JUSTIFY); + paragraphFormat.setKeepTogether(true); + + builder.writeln("A whole paragraph."); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertParagraph.docx"); + //ExEnd:InsertParagraph + } + + @Test + public void insertTcField() throws Exception + { + //ExStart:InsertTcField + //GistId:db118a3e1559b9c88355356df9d7ea10 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertField("TC \"Entry Text\" \\f t"); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.InsertTcField.docx"); + //ExEnd:InsertTcField + } + + @Test + public void insertTcFieldsAtText() throws Exception + { + //ExStart:InsertTcFieldsAtText + //GistId:db118a3e1559b9c88355356df9d7ea10 + Document doc = new Document(); + + FindReplaceOptions options = new FindReplaceOptions(); + options.getApplyFont().setHighlightColor(msColor.getDarkOrange()); + options.setReplacingCallback(new InsertTCFieldHandler("Chapter 1", "\\l 1")); + + doc.getRange().replaceInternal(new Regex("The Beginning"), "", options); + //ExEnd:InsertTcFieldsAtText + } + + //ExStart:InsertTCFieldHandler + public final static class InsertTCFieldHandler implements IReplacingCallback + { + // Store the text and switches to be used for the TC fields. + private /*final*/ String mFieldText; + private /*final*/ String mFieldSwitches; + + /// + /// The display text and switches to use for each TC field. Display name can be an empty string or null. + /// + public InsertTCFieldHandler(String text, String switches) + { + mFieldText = text; + mFieldSwitches = switches; + } + + public /*ReplaceAction*/int /*IReplacingCallback.*/replacing(ReplacingArgs args) throws Exception + { + DocumentBuilder builder = new DocumentBuilder((Document) args.getMatchNode().getDocument()); + builder.moveTo(args.getMatchNode()); + + // If the user-specified text to be used in the field as display text, then use that, + // otherwise use the match string as the display text. + String insertText = !msString.isNullOrEmpty(mFieldText) ? mFieldText : args.getMatchInternal().getValue(); + + builder.insertField($"TC \"{insertText}\" {mFieldSwitches}"); + + return ReplaceAction.SKIP; + } + } + //ExEnd:InsertTCFieldHandler + + @Test + public void cursorPosition() throws Exception + { + //ExStart:CursorPosition + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Node curNode = builder.getCurrentNode(); + Paragraph curParagraph = builder.getCurrentParagraph(); + //ExEnd:CursorPosition + + System.out.println("\nCursor move to paragraph: " + curParagraph.getText()); + } + + @Test + public void moveToNode() throws Exception + { + //ExStart:MoveToNode + //GistId:1a2c340d1a9dde6fe70c2733084d9aab + //ExStart:MoveToBookmark + //GistId:1a2c340d1a9dde6fe70c2733084d9aab + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Start a bookmark and add content to it using a DocumentBuilder. + builder.startBookmark("MyBookmark"); + builder.writeln("Bookmark contents."); + builder.endBookmark("MyBookmark"); + + // The node that the DocumentBuilder is currently at is past the boundaries of the bookmark. + Assert.assertEquals(doc.getRange().getBookmarks().get(0).getBookmarkEnd(), builder.getCurrentParagraph().getFirstChild()); + + // If we wish to revise the content of our bookmark with the DocumentBuilder, we can move back to it like this. + builder.moveToBookmark("MyBookmark"); + + // Now we're located between the bookmark's BookmarkStart and BookmarkEnd nodes, so any text the builder adds will be within it. + Assert.assertEquals(doc.getRange().getBookmarks().get(0).getBookmarkStart(), builder.getCurrentParagraph().getFirstChild()); + + // We can move the builder to an individual node, + // which in this case will be the first node of the first paragraph, like this. + builder.moveTo(doc.getFirstSection().getBody().getFirstParagraph().getChildNodes(NodeType.ANY, false).get(0)); + //ExEnd:MoveToBookmark + + Assert.assertEquals(NodeType.BOOKMARK_START, builder.getCurrentNode().getNodeType()); + Assert.assertTrue(builder.isAtStartOfParagraph()); + + // A shorter way of moving the very start/end of a document is with these methods. + builder.moveToDocumentEnd(); + Assert.assertTrue(builder.isAtEndOfParagraph()); + builder.moveToDocumentStart(); + Assert.assertTrue(builder.isAtStartOfParagraph()); + //ExEnd:MoveToNode + } + + @Test + public void moveToDocumentStartEnd() throws Exception + { + //ExStart:MoveToDocumentStartEnd + //GistId:1a2c340d1a9dde6fe70c2733084d9aab + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Move the cursor position to the beginning of your document. + builder.moveToDocumentStart(); + System.out.println("\nThis is the beginning of the document."); + + // Move the cursor position to the end of your document. + builder.moveToDocumentEnd(); + System.out.println("\nThis is the end of the document."); + //ExEnd:MoveToDocumentStartEnd + } + + @Test + public void moveToSection() throws Exception + { + //ExStart:MoveToSection + //GistId:1a2c340d1a9dde6fe70c2733084d9aab + Document doc = new Document(); + doc.appendChild(new Section(doc)); + + // Move a DocumentBuilder to the second section and add text. + DocumentBuilder builder = new DocumentBuilder(doc); + builder.moveToSection(1); + builder.writeln("Text added to the 2nd section."); + + // Create document with paragraphs. + doc = new Document(getMyDir() + "Paragraphs.docx"); + ParagraphCollection paragraphs = doc.getFirstSection().getBody().getParagraphs(); + Assert.assertEquals(22, paragraphs.getCount()); + + // When we create a DocumentBuilder for a document, its cursor is at the very beginning of the document by default, + // and any content added by the DocumentBuilder will just be prepended to the document. + builder = new DocumentBuilder(doc); + Assert.assertEquals(0, paragraphs.indexOf(builder.getCurrentParagraph())); + + // You can move the cursor to any position in a paragraph. + builder.moveToParagraph(2, 10); + Assert.assertEquals(2, paragraphs.indexOf(builder.getCurrentParagraph())); + builder.writeln("This is a new third paragraph. "); + Assert.assertEquals(3, paragraphs.indexOf(builder.getCurrentParagraph())); + //ExEnd:MoveToSection + } + + @Test + public void moveToHeadersFooters() throws Exception + { + //ExStart:MoveToHeadersFooters + //GistId:1a2c340d1a9dde6fe70c2733084d9aab + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Specify that we want headers and footers different for first, even and odd pages. + builder.getPageSetup().setDifferentFirstPageHeaderFooter(true); + builder.getPageSetup().setOddAndEvenPagesHeaderFooter(true); + + // Create the headers. + builder.moveToHeaderFooter(HeaderFooterType.HEADER_FIRST); + builder.write("Header for the first page"); + builder.moveToHeaderFooter(HeaderFooterType.HEADER_EVEN); + builder.write("Header for even pages"); + builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); + builder.write("Header for all other pages"); + + // Create two pages in the document. + builder.moveToSection(0); + builder.writeln("Page1"); + builder.insertBreak(BreakType.PAGE_BREAK); + builder.writeln("Page2"); + + doc.save(getArtifactsDir() + "AddContentUsingDocumentBuilder.MoveToHeadersFooters.docx"); + //ExEnd:MoveToHeadersFooters + } + + @Test + public void moveToParagraph() throws Exception + { + //ExStart:MoveToParagraph + Document doc = new Document(getMyDir() + "Paragraphs.docx"); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.moveToParagraph(2, 0); + builder.writeln("This is the 3rd paragraph."); + //ExEnd:MoveToParagraph + } + + @Test + public void moveToTableCell() throws Exception + { + //ExStart:MoveToTableCell + //GistId:1a2c340d1a9dde6fe70c2733084d9aab + Document doc = new Document(getMyDir() + "Tables.docx"); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Move the builder to row 3, cell 4 of the first table. + builder.moveToCell(0, 2, 3, 0); + builder.write("\nCell contents added by DocumentBuilder"); + Table table = (Table)doc.getChild(NodeType.TABLE, 0, true); + + Assert.assertEquals(table.getRows().get(2).getCells().get(3), builder.getCurrentNode().getParentNode().getParentNode()); + Assert.assertEquals("Cell contents added by DocumentBuilderCell 3 contents\u0007", table.getRows().get(2).getCells().get(3).getText().trim()); + //ExEnd:MoveToTableCell + } + + @Test + public void moveToBookmarkEnd() throws Exception + { + //ExStart:MoveToBookmarkEnd + //GistId:ecf2c438314e6c8318ca9833c7f62326 + Document doc = new Document(getMyDir() + "Bookmarks.docx"); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.moveToBookmark("MyBookmark1", false, true); + builder.writeln("This is a bookmark."); + //ExEnd:MoveToBookmarkEnd + } + + @Test + public void moveToMergeField() throws Exception + { + //ExStart:MoveToMergeField + //GistId:1a2c340d1a9dde6fe70c2733084d9aab + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a field using the DocumentBuilder and add a run of text after it. + Field field = builder.insertField("MERGEFIELD field"); + builder.write(" Text after the field."); + + // The builder's cursor is currently at end of the document. + Assert.assertNull(builder.getCurrentNode()); + // We can move the builder to a field like this, placing the cursor at immediately after the field. + builder.moveToField(field, true); + + // Note that the cursor is at a place past the FieldEnd node of the field, meaning that we are not actually inside the field. + // If we wish to move the DocumentBuilder to inside a field, + // we will need to move it to a field's FieldStart or FieldSeparator node using the DocumentBuilder.MoveTo() method. + Assert.assertEquals(field.getEnd(), builder.getCurrentNode().getPreviousSibling()); + builder.write(" Text immediately after the field."); + //ExEnd:MoveToMergeField + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/CloneAndCombineDocuments.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/CloneAndCombineDocuments.java new file mode 100644 index 00000000..652ea610 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/CloneAndCombineDocuments.java @@ -0,0 +1,299 @@ +package DocsExamples.Programming_with_Documents.Working_with_Document; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.BreakType; +import org.testng.Assert; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.Section; +import com.aspose.words.FindReplaceOptions; +import com.aspose.words.FindReplaceDirection; +import com.aspose.ms.System.Text.RegularExpressions.Regex; +import com.aspose.words.Bookmark; +import com.aspose.words.Node; +import com.aspose.words.NodeType; +import com.aspose.words.CompositeNode; +import com.aspose.words.NodeImporter; +import com.aspose.words.ImportFormatMode; +import com.aspose.words.Paragraph; +import com.aspose.words.IFieldMergingCallback; +import com.aspose.words.FieldMergingArgs; +import com.aspose.words.ImageFieldMergingArgs; +import com.aspose.ms.System.IO.MemoryStream; +import com.aspose.words.IReplacingCallback; +import com.aspose.words.ReplaceAction; +import com.aspose.words.ReplacingArgs; + + +class CloneAndCombineDocuments extends DocsExamplesBase +{ + @Test + public void cloneDocument() throws Exception + { + //ExStart:CloneDocument + //GistId:b2f62f736a2090163de7b0f221cf46d4 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + builder.writeln("This is the original document before applying the clone method"); + + // Clone the document. + Document clone = doc.deepClone(); + + // Edit the cloned document. + builder = new DocumentBuilder(clone); + builder.write("Section 1"); + builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); + builder.write("Section 2"); + + // This shows what is in the document originally. The document has two sections. + Assert.assertEquals("Section 1\fSection 2This is the original document before applying the clone method", clone.getText().trim()); + + // Duplicate the last section and append the copy to the end of the document. + int lastSectionIdx = clone.getSections().getCount() - 1; + Section newSection = clone.getSections().get(lastSectionIdx).deepClone(); + clone.getSections().add(newSection); + + // Check what the document contains after we changed it. + Assert.assertEquals("Section 1\fSection 2This is the original document before applying the clone method" + + "\r\fSection 2This is the original document before applying the clone method", clone.getText().trim()); + clone.save(getArtifactsDir() + "CloneAndCombineDocuments.CloningDocument.docx"); + //ExEnd:CloneDocument + } + + @Test + public void insertDocumentAtReplace() throws Exception + { + //ExStart:InsertDocumentAtReplace + //GistId:db2dfc4150d7c714bcac3782ae241d03 + Document mainDoc = new Document(getMyDir() + "Document insertion 1.docx"); + + FindReplaceOptions options = new FindReplaceOptions(); + { + options.setDirection(FindReplaceDirection.BACKWARD); + options.setReplacingCallback(new InsertDocumentAtReplaceHandler()); + } + + mainDoc.getRange().replaceInternal(new Regex("\\[MY_DOCUMENT\\]"), "", options); + mainDoc.save(getArtifactsDir() + "CloneAndCombineDocuments.InsertDocumentAtReplace.docx"); + //ExEnd:InsertDocumentAtReplace + } + + @Test + public void insertDocumentAtBookmark() throws Exception + { + //ExStart:InsertDocumentAtBookmark + //GistId:db2dfc4150d7c714bcac3782ae241d03 + Document mainDoc = new Document(getMyDir() + "Document insertion 1.docx"); + Document subDoc = new Document(getMyDir() + "Document insertion 2.docx"); + + Bookmark bookmark = mainDoc.getRange().getBookmarks().get("insertionPlace"); + insertDocument(bookmark.getBookmarkStart().getParentNode(), subDoc); + + mainDoc.save(getArtifactsDir() + "CloneAndCombineDocuments.InsertDocumentAtBookmark.docx"); + //ExEnd:InsertDocumentAtBookmark + } + + @Test + public void insertDocumentAtMailMerge() throws Exception + { + //ExStart:InsertDocumentAtMailMerge + //GistId:db2dfc4150d7c714bcac3782ae241d03 + Document mainDoc = new Document(getMyDir() + "Document insertion 1.docx"); + + mainDoc.getMailMerge().setFieldMergingCallback(new InsertDocumentAtMailMergeHandler()); + // The main document has a merge field in it called "Document_1". + // The corresponding data for this field contains a fully qualified path to the document. + // That should be inserted to this field. + mainDoc.getMailMerge().execute(new String[] { "Document_1" }, new Object[] { getMyDir() + "Document insertion 2.docx" }); + + mainDoc.save(getArtifactsDir() + "CloneAndCombineDocuments.InsertDocumentAtMailMerge.doc"); + //ExEnd:InsertDocumentAtMailMerge + } + + //ExStart:InsertDocumentAsNodes + //GistId:db2dfc4150d7c714bcac3782ae241d03 + /// + /// Inserts content of the external document after the specified node. + /// Section breaks and section formatting of the inserted document are ignored. + /// + /// Node in the destination document after which the content + /// Should be inserted. This node should be a block level node (paragraph or table). + /// The document to insert. + private static void insertDocument(Node insertionDestination, Document docToInsert) + { + if (insertionDestination.getNodeType() == NodeType.PARAGRAPH || insertionDestination.getNodeType() == NodeType.TABLE) + { + CompositeNode destinationParent = insertionDestination.getParentNode(); + + NodeImporter importer = + new NodeImporter(docToInsert, insertionDestination.getDocument(), ImportFormatMode.KEEP_SOURCE_FORMATTING); + + // Loop through all block-level nodes in the section's body, + // then clone and insert every node that is not the last empty paragraph of a section. + for (Section srcSection : docToInsert.getSections().
          OfType() !!Autoporter error: Undefined expression type ) + for (Node srcNode : (Iterable) srcSection.getBody()) + { + if (srcNode.getNodeType() == NodeType.PARAGRAPH) + { + Paragraph para = (Paragraph)srcNode; + if (para.isEndOfSection() && !para.hasChildNodes()) + continue; + } + + Node newNode = importer.importNode(srcNode, true); + + destinationParent.insertAfter(newNode, insertionDestination); + insertionDestination = newNode; + } + } + else + { + throw new IllegalArgumentException("The destination node should be either a paragraph or table."); + } + } + //ExEnd:InsertDocumentAsNodes + + //ExStart:InsertDocumentWithSectionFormatting + /// + /// Inserts content of the external document after the specified node. + /// + /// Node in the destination document after which the content + /// Should be inserted. This node should be a block level node (paragraph or table). + /// The document to insert. + private void insertDocumentWithSectionFormatting(Node insertAfterNode, Document srcDoc) + { + if (insertAfterNode.getNodeType() != NodeType.PARAGRAPH && + insertAfterNode.getNodeType() != NodeType.TABLE) + throw new IllegalArgumentException("The destination node should be either a paragraph or table."); + + Document dstDoc = (Document) insertAfterNode.getDocument(); + // To retain section formatting, split the current section into two at the marker node and then import the content + // from srcDoc as whole sections. The section of the node to which the insert marker node belongs. + Section currentSection = (Section) insertAfterNode.getAncestor(NodeType.SECTION); + + // Don't clone the content inside the section, we just want the properties of the section retained. + Section cloneSection = (Section) currentSection.deepClone(false); + + // However, make sure the clone section has a body but no empty first paragraph. + cloneSection.ensureMinimum(); + cloneSection.getBody().getFirstParagraph().remove(); + + insertAfterNode.getDocument().insertAfter(cloneSection, currentSection); + + // Append all nodes after the marker node to the new section. This will split the content at the section level at. + // The marker so the sections from the other document can be inserted directly. + Node currentNode = insertAfterNode.getNextSibling(); + while (currentNode != null) + { + Node nextNode = currentNode.getNextSibling(); + cloneSection.getBody().appendChild(currentNode); + currentNode = nextNode; + } + + // This object will be translating styles and lists during the import. + NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.USE_DESTINATION_STYLES); + + for (Section srcSection : (Iterable
          ) srcDoc.getSections()) + { + Node newNode = importer.importNode(srcSection, true); + + dstDoc.insertAfter(newNode, currentSection); + currentSection = (Section) newNode; + } + } + //ExEnd:InsertDocumentWithSectionFormatting + + //ExStart:InsertDocumentAtMailMergeHandler + //GistId:db2dfc4150d7c714bcac3782ae241d03 + private static class InsertDocumentAtMailMergeHandler implements IFieldMergingCallback + { + // This handler makes special processing for the "Document_1" field. + // The field value contains the path to load the document. + // We load the document and insert it into the current merge field. + public void /*IFieldMergingCallback.*/fieldMerging(FieldMergingArgs args) throws Exception + { + if ("Document_1".equals(args.getDocumentFieldName())) + { + // Use document builder to navigate to the merge field with the specified name. + DocumentBuilder builder = new DocumentBuilder(args.getDocument()); + builder.moveToMergeField(args.getDocumentFieldName()); + + // The name of the document to load and insert is stored in the field value. + Document subDoc = new Document((String)args.getFieldValue()); + + insertDocument(builder.getCurrentParagraph(), subDoc); + + // The paragraph that contained the merge field might be empty now, and you probably want to delete it. + if (!builder.getCurrentParagraph().hasChildNodes()) + builder.getCurrentParagraph().remove(); + + // Indicate to the mail merge engine that we have inserted what we wanted. + args.setText(null); + } + } + + public void /*IFieldMergingCallback.*/imageFieldMerging(ImageFieldMergingArgs args) + { + // Do nothing. + } + } + //ExEnd:InsertDocumentAtMailMergeHandler + + //ExStart:InsertDocumentAtMailMergeBlobHandler + private static class InsertDocumentAtMailMergeBlobHandler implements IFieldMergingCallback + { + /// + /// This handler makes special processing for the "Document_1" field. + /// The field value contains the path to load the document. + /// We load the document and insert it into the current merge field. + /// + public void /*IFieldMergingCallback.*/fieldMerging(FieldMergingArgs e) throws Exception + { + if ("Document_1".equals(e.getDocumentFieldName())) + { + DocumentBuilder builder = new DocumentBuilder(e.getDocument()); + builder.moveToMergeField(e.getDocumentFieldName()); + + MemoryStream stream = new MemoryStream((byte[]) e.getFieldValue()); + Document subDoc = new Document(stream); + + insertDocument(builder.getCurrentParagraph(), subDoc); + + // The paragraph that contained the merge field might be empty now, and you probably want to delete it. + if (!builder.getCurrentParagraph().hasChildNodes()) + builder.getCurrentParagraph().remove(); + + e.setText(null); + } + } + + public void /*IFieldMergingCallback.*/imageFieldMerging(ImageFieldMergingArgs args) + { + // Do nothing. + } + } + //ExEnd:InsertDocumentAtMailMergeBlobHandler + + //ExStart:InsertDocumentAtReplaceHandler + //GistId:db2dfc4150d7c714bcac3782ae241d03 + private static class InsertDocumentAtReplaceHandler implements IReplacingCallback + { + public /*ReplaceAction*/int /*IReplacingCallback.*/replacing(ReplacingArgs args) throws Exception + { + Document subDoc = new Document(getMyDir() + "Document insertion 2.docx"); + + // Insert a document after the paragraph, containing the match text. + Paragraph para = (Paragraph)args.getMatchNode().getParentNode(); + insertDocument(para, subDoc); + + // Remove the paragraph with the match text. + para.remove(); + return ReplaceAction.SKIP; + } + } + //ExEnd:InsertDocumentAtReplaceHandler +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/CompareDocuments.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/CompareDocuments.java new file mode 100644 index 00000000..8282a197 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/CompareDocuments.java @@ -0,0 +1,89 @@ +package DocsExamples.Programming_with_Documents.Working_with_Document; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import java.util.Date; +import com.aspose.ms.System.DateTime; +import com.aspose.ms.System.msConsole; +import com.aspose.words.CompareOptions; +import com.aspose.words.ComparisonTargetType; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.Granularity; + + +class CompareDocument extends DocsExamplesBase +{ + @Test + public void compareForEqual() throws Exception + { + //ExStart:CompareForEqual + //GistId:66cba61d079d8ef1e676820633ba4586 + Document docA = new Document(getMyDir() + "Document.docx"); + Document docB = docA.deepClone(); + + // DocA now contains changes as revisions. + docA.compareInternal(docB, "user", new Date); + + System.out.println(docA.getRevisions().getCount() == 0 ? "Documents are equal" : "Documents are not equal"); + //ExEnd:CompareForEqual + } + + @Test + public void compareOptions() throws Exception + { + //ExStart:CompareOptions + //GistId:66cba61d079d8ef1e676820633ba4586 + Document docA = new Document(getMyDir() + "Document.docx"); + Document docB = docA.deepClone(); + + CompareOptions options = new CompareOptions(); + { + options.setIgnoreFormatting(true); + options.setIgnoreHeadersAndFooters(true); + options.setIgnoreCaseChanges(true); + options.setIgnoreTables(true); + options.setIgnoreFields(true); + options.setIgnoreComments(true); + options.setIgnoreTextboxes(true); + options.setIgnoreFootnotes(true); + } + + docA.compareInternal(docB, "user", new Date, options); + + System.out.println(docA.getRevisions().getCount() == 0 ? "Documents are equal" : "Documents are not equal"); + //ExEnd:CompareOptions + } + + @Test + public void comparisonTarget() throws Exception + { + //ExStart:ComparisonTarget + Document docA = new Document(getMyDir() + "Document.docx"); + Document docB = docA.deepClone(); + + // Relates to Microsoft Word "Show changes in" option in "Compare Documents" dialog box. + CompareOptions options = new CompareOptions(); { options.setIgnoreFormatting(true); options.setTarget(ComparisonTargetType.NEW); } + + docA.compareInternal(docB, "user", new Date, options); + //ExEnd:ComparisonTarget + } + + @Test + public void comparisonGranularity() throws Exception + { + //ExStart:ComparisonGranularity + DocumentBuilder builderA = new DocumentBuilder(new Document()); + DocumentBuilder builderB = new DocumentBuilder(new Document()); + + builderA.writeln("This is A simple word"); + builderB.writeln("This is B simple words"); + + CompareOptions compareOptions = new CompareOptions(); { compareOptions.setGranularity(Granularity.CHAR_LEVEL); } + + builderA.getDocument().compareInternal(builderB.getDocument(), "author", new Date, compareOptions); + //ExEnd:ComparisonGranularity + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/DocumentFormatting.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/DocumentFormatting.java new file mode 100644 index 00000000..a64d81b6 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/DocumentFormatting.java @@ -0,0 +1,293 @@ +package DocsExamples.Programming_with_Documents.Working_with_Document; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.ParagraphFormat; +import com.aspose.words.ParagraphAlignment; +import com.aspose.words.StyleIdentifier; +import com.aspose.words.BorderCollection; +import com.aspose.words.BorderType; +import com.aspose.words.LineStyle; +import com.aspose.words.Shading; +import com.aspose.words.TextureIndex; +import com.aspose.ms.System.Drawing.msColor; +import java.awt.Color; +import com.aspose.words.Paragraph; +import com.aspose.words.NodeType; +import com.aspose.ms.System.msConsole; +import com.aspose.words.LayoutCollector; +import com.aspose.words.LayoutEnumerator; +import com.aspose.words.Node; +import com.aspose.words.Table; + + +class DocumentFormatting extends DocsExamplesBase +{ + @Test + public void spaceBetweenAsianAndLatinText() throws Exception + { + //ExStart:SpaceBetweenAsianAndLatinText + //GistId:4f54ffd5c7580f0d146b53e52d986f38 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + ParagraphFormat paragraphFormat = builder.getParagraphFormat(); + paragraphFormat.setAddSpaceBetweenFarEastAndAlpha(true); + paragraphFormat.setAddSpaceBetweenFarEastAndDigit(true); + + builder.writeln("Automatically adjust space between Asian and Latin text"); + builder.writeln("Automatically adjust space between Asian text and numbers"); + + doc.save(getArtifactsDir() + "DocumentFormatting.SpaceBetweenAsianAndLatinText.docx"); + //ExEnd:SpaceBetweenAsianAndLatinText + } + + @Test + public void asianTypographyLineBreakGroup() throws Exception + { + //ExStart:AsianTypographyLineBreakGroup + //GistId:4f54ffd5c7580f0d146b53e52d986f38 + Document doc = new Document(getMyDir() + "Asian typography.docx"); + + ParagraphFormat format = doc.getFirstSection().getBody().getParagraphs().get(0).getParagraphFormat(); + format.setFarEastLineBreakControl(false); + format.setWordWrap(true); + format.setHangingPunctuation(false); + + doc.save(getArtifactsDir() + "DocumentFormatting.AsianTypographyLineBreakGroup.docx"); + //ExEnd:AsianTypographyLineBreakGroup + } + + @Test + public void paragraphFormatting() throws Exception + { + //ExStart:ParagraphFormatting + //GistId:4b5526c3c0d9cad73e05fb4b18d2c3d2 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + ParagraphFormat paragraphFormat = builder.getParagraphFormat(); + paragraphFormat.setAlignment(ParagraphAlignment.CENTER); + paragraphFormat.setLeftIndent(50.0); + paragraphFormat.setRightIndent(50.0); + paragraphFormat.setSpaceAfter(25.0); + + builder.writeln( + "I'm a very nice formatted paragraph. I'm intended to demonstrate how the left and right indents affect word wrapping."); + builder.writeln( + "I'm another nice formatted paragraph. I'm intended to demonstrate how the space after paragraph looks like."); + + doc.save(getArtifactsDir() + "DocumentFormatting.ParagraphFormatting.docx"); + //ExEnd:ParagraphFormatting + } + + @Test + public void multilevelListFormatting() throws Exception + { + //ExStart:MultilevelListFormatting + //GistId:a1dfeba1e0480d5b277a61742c8921af + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getListFormat().applyNumberDefault(); + builder.writeln("Item 1"); + builder.writeln("Item 2"); + + builder.getListFormat().listIndent(); + builder.writeln("Item 2.1"); + builder.writeln("Item 2.2"); + + builder.getListFormat().listIndent(); + builder.writeln("Item 2.2.1"); + builder.writeln("Item 2.2.2"); + + builder.getListFormat().listOutdent(); + builder.writeln("Item 2.3"); + + builder.getListFormat().listOutdent(); + builder.writeln("Item 3"); + + builder.getListFormat().removeNumbers(); + + doc.save(getArtifactsDir() + "DocumentFormatting.MultilevelListFormatting.docx"); + //ExEnd:MultilevelListFormatting + } + + @Test + public void applyParagraphStyle() throws Exception + { + //ExStart:ApplyParagraphStyle + //GistId:4b5526c3c0d9cad73e05fb4b18d2c3d2 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.TITLE); + builder.write("Hello"); + + doc.save(getArtifactsDir() + "DocumentFormatting.ApplyParagraphStyle.docx"); + //ExEnd:ApplyParagraphStyle + } + + @Test + public void applyBordersAndShadingToParagraph() throws Exception + { + //ExStart:ApplyBordersAndShadingToParagraph + //GistId:4b5526c3c0d9cad73e05fb4b18d2c3d2 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + BorderCollection borders = builder.getParagraphFormat().getBorders(); + borders.setDistanceFromText(20.0); + borders.getByBorderType(BorderType.LEFT).setLineStyle(LineStyle.DOUBLE); + borders.getByBorderType(BorderType.RIGHT).setLineStyle(LineStyle.DOUBLE); + borders.getByBorderType(BorderType.TOP).setLineStyle(LineStyle.DOUBLE); + borders.getByBorderType(BorderType.BOTTOM).setLineStyle(LineStyle.DOUBLE); + + Shading shading = builder.getParagraphFormat().getShading(); + shading.setTexture(TextureIndex.TEXTURE_DIAGONAL_CROSS); + shading.setBackgroundPatternColor(msColor.getLightCoral()); + shading.setForegroundPatternColor(java.awt.Color.LightSalmon); + + builder.write("I'm a formatted paragraph with double border and nice shading."); + + doc.save(getArtifactsDir() + "DocumentFormatting.ApplyBordersAndShadingToParagraph.doc"); + //ExEnd:ApplyBordersAndShadingToParagraph + } + + @Test + public void changeAsianParagraphSpacingAndIndents() throws Exception + { + //ExStart:ChangeAsianParagraphSpacingAndIndents + Document doc = new Document(getMyDir() + "Asian typography.docx"); + + ParagraphFormat format = doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat(); + format.setCharacterUnitLeftIndent(10.0); // ParagraphFormat.LeftIndent will be updated + format.setCharacterUnitRightIndent(10.0); // ParagraphFormat.RightIndent will be updated + format.setCharacterUnitFirstLineIndent(20.0); // ParagraphFormat.FirstLineIndent will be updated + format.setLineUnitBefore(5.0); // ParagraphFormat.SpaceBefore will be updated + format.setLineUnitAfter(10.0); // ParagraphFormat.SpaceAfter will be updated + + doc.save(getArtifactsDir() + "DocumentFormatting.ChangeAsianParagraphSpacingAndIndents.doc"); + //ExEnd:ChangeAsianParagraphSpacingAndIndents + } + + @Test + public void snapToGrid() throws Exception + { + //ExStart:SetSnapToGrid + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Optimize the layout when typing in Asian characters. + Paragraph par = doc.getFirstSection().getBody().getFirstParagraph(); + par.getParagraphFormat().setSnapToGrid(true); + + builder.writeln("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod " + + "tempor incididunt ut labore et dolore magna aliqua."); + + par.getRuns().get(0).getFont().setSnapToGrid(true); + + doc.save(getArtifactsDir() + "Paragraph.SnapToGrid.docx"); + //ExEnd:SetSnapToGrid + } + + @Test + public void getParagraphStyleSeparator() throws Exception + { + //ExStart:GetParagraphStyleSeparator + //GistId:4b5526c3c0d9cad73e05fb4b18d2c3d2 + Document doc = new Document(getMyDir() + "Document.docx"); + + for (Paragraph paragraph : (Iterable) doc.getChildNodes(NodeType.PARAGRAPH, true)) + { + if (paragraph.getBreakIsStyleSeparator()) + { + System.out.println("Separator Found!"); + } + } + //ExEnd:GetParagraphStyleSeparator + } + + @Test + //ExStart:GetParagraphLines + //GistId:4b5526c3c0d9cad73e05fb4b18d2c3d2 + public void getParagraphLines() throws Exception + { + Document doc = new Document(getMyDir() + "Properties.docx"); + + LayoutCollector collector = new LayoutCollector(doc); + LayoutEnumerator enumerator = new LayoutEnumerator(doc); + for (Paragraph paragraph : (Iterable) doc.getChildNodes(NodeType.PARAGRAPH, true)) + { + processParagraph(paragraph, collector, enumerator); + } + } + + private static void processParagraph(Paragraph paragraph, LayoutCollector collector, LayoutEnumerator enumerator) throws Exception + { + Object paragraphBreak = collector.getEntity(paragraph); + if (paragraphBreak == null) + return; + + Object stopEntity = getStopEntity(paragraph, collector, enumerator); + + enumerator.setCurrent(paragraphBreak); + enumerator.moveParent(); + + int lineCount = countLines(enumerator, stopEntity); + + String paragraphText = getTruncatedText(paragraph.getText()); + System.out.println("Paragraph '{paragraphText}' has {lineCount} line(-s)."); + } + + private static Object getStopEntity(Paragraph paragraph, LayoutCollector collector, LayoutEnumerator enumerator) throws Exception + { + Node previousNode = paragraph.getPreviousSibling(); + if (previousNode == null) + return null; + + if (previousNode instanceof Paragraph prevParagraph) + { + enumerator.setCurrent(collector.GetEntity(prevParagraph)); // Para break. + enumerator.moveParent(); // Last line. + return enumerator.getCurrent(); + } + else if (previousNode instanceof Table table) + { + enumerator.setCurrent(collector.GetEntity(table.LastRow.LastCell.LastParagraph)); // Cell break. + enumerator.moveParent(); // Cell. + enumerator.moveParent(); // Row. + return enumerator.getCurrent(); + } + else + { + throw new IllegalStateException("Unsupported node type encountered."); + } + } + /// + /// We move from line to line in a paragraph. + /// When paragraph spans multiple pages the we will follow across them. + /// + private static int countLines(LayoutEnumerator enumerator, Object stopEntity) + { + int count = 1; + while (enumerator.getCurrent() != stopEntity) + { + if (!enumerator.movePreviousLogical()) + break; + count++; + } + return count; + } + + private static String getTruncatedText(String text) + { + int MaxChars = 16; + return text.length() > MaxChars ? $"{text.Substring(0, MaxChars)}..." : text; + } + //ExEnd:GetParagraphLines +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/JoinAndAppendDocuments.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/JoinAndAppendDocuments.java new file mode 100644 index 00000000..567630c7 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/JoinAndAppendDocuments.java @@ -0,0 +1,679 @@ +package DocsExamples.Programming_with_Documents.Working_with_Document; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.ImportFormatMode; +import com.aspose.words.Section; +import com.aspose.words.Node; +import com.aspose.words.ImportFormatOptions; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.NodeType; +import com.aspose.words.FieldStart; +import com.aspose.words.FieldType; +import com.aspose.words.Field; +import com.aspose.ms.System.Text.msStringBuilder; +import com.aspose.words.SectionStart; +import com.aspose.words.Paragraph; +import java.util.HashMap; +import com.aspose.words.List; +import com.aspose.ms.System.Collections.msDictionary; +import com.aspose.words.Style; +import com.aspose.words.StyleType; +import java.awt.Color; +import com.aspose.words.BreakType; +import com.aspose.words.BookmarkStart; +import com.aspose.words.BookmarkEnd; +import org.testng.Assert; +import com.aspose.ms.System.msString; +import com.aspose.ms.NUnit.Framework.msAssert; +import com.aspose.words.NodeImporter; +import com.aspose.words.ParagraphCollection; + + +class JoinAndAppendDocuments extends DocsExamplesBase +{ + @Test + public void simpleAppendDocument() throws Exception + { + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // Append the source document to the destination document using no extra options. + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.SimpleAppendDocument.docx"); + } + + @Test + public void appendDocument() throws Exception + { + //ExStart:AppendDocumentManually + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // Loop through all sections in the source document. + // Section nodes are immediate children of the Document node so we can just enumerate the Document. + for (Section srcSection : (Iterable
          ) srcDoc) + { + // Because we are copying a section from one document to another, + // it is required to import the Section node into the destination document. + // This adjusts any document-specific references to styles, lists, etc. + // + // Importing a node creates a copy of the original node, but the copy + // ss ready to be inserted into the destination document. + Node dstSection = dstDoc.importNode(srcSection, true, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + // Now the new section node can be appended to the destination document. + dstDoc.appendChild(dstSection); + } + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.AppendDocument.docx"); + //ExEnd:AppendDocumentManually + } + + @Test + public void appendDocumentToBlank() throws Exception + { + //ExStart:AppendDocumentToBlank + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(); + + // The destination document is not empty, often causing a blank page to appear before the appended document. + // This is due to the base document having an empty section and the new document being started on the next page. + // Remove all content from the destination document before appending. + dstDoc.removeAllChildren(); + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.AppendDocumentToBlank.docx"); + //ExEnd:AppendDocumentToBlank + } + + @Test + public void appendWithImportFormatOptions() throws Exception + { + //ExStart:AppendWithImportFormatOptions + Document srcDoc = new Document(getMyDir() + "Document source with list.docx"); + Document dstDoc = new Document(getMyDir() + "Document destination with list.docx"); + + // Specify that if numbering clashes in source and destination documents, + // then numbering from the source document will be used. + ImportFormatOptions options = new ImportFormatOptions(); { options.setKeepSourceNumbering(true); } + + dstDoc.appendDocument(srcDoc, ImportFormatMode.USE_DESTINATION_STYLES, options); + //ExEnd:AppendWithImportFormatOptions + } + + @Test + public void convertNumPageFields() throws Exception + { + //ExStart:ConvertNumPageFields + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // Restart the page numbering on the start of the source document. + srcDoc.getFirstSection().getPageSetup().setRestartPageNumbering(true); + srcDoc.getFirstSection().getPageSetup().setPageStartingNumber(1); + + // Append the source document to the end of the destination document. + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + // After joining the documents the NUMPAGE fields will now display the total number of pages which + // is undesired behavior. Call this method to fix them by replacing them with PAGEREF fields. + convertNumPageFieldsToPageRef(dstDoc); + + // This needs to be called in order to update the new fields with page numbers. + dstDoc.updatePageLayout(); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.ConvertNumPageFields.docx"); + //ExEnd:ConvertNumPageFields + } + + //ExStart:ConvertNumPageFieldsToPageRef + public void convertNumPageFieldsToPageRef(Document doc) throws Exception + { + // This is the prefix for each bookmark, which signals where page numbering restarts. + // The underscore "_" at the start inserts this bookmark as hidden in MS Word. + final String BOOKMARK_PREFIX = "_SubDocumentEnd"; + final String NUM_PAGES_FIELD_NAME = "NUMPAGES"; + final String PAGE_REF_FIELD_NAME = "PAGEREF"; + + // Defines the number of page restarts encountered and, therefore, + // the number of "sub" documents found within this document. + int subDocumentCount = 0; + + DocumentBuilder builder = new DocumentBuilder(doc); + + for (Section section : (Iterable
          ) doc.getSections()) + { + // This section has its page numbering restarted to treat this as the start of a sub-document. + // Any PAGENUM fields in this inner document must be converted to special PAGEREF fields to correct numbering. + if (section.getPageSetup().getRestartPageNumbering()) + { + // Don't do anything if this is the first section of the document. + // This part of the code will insert the bookmark marking the end of the previous sub-document so, + // therefore, it does not apply to the first section in the document. + if (!section.equals(doc.getFirstSection())) + { + // Get the previous section and the last node within the body of that section. + Section prevSection = (Section) section.getPreviousSibling(); + Node lastNode = prevSection.getBody().getLastChild(); + + builder.moveTo(lastNode); + + // This bookmark represents the end of the sub-document. + builder.startBookmark(BOOKMARK_PREFIX + subDocumentCount); + builder.endBookmark(BOOKMARK_PREFIX + subDocumentCount); + + // Increase the sub-document count to insert the correct bookmarks. + subDocumentCount++; + } + } + + // The last section needs the ending bookmark to signal that it is the end of the current sub-document. + if (section.equals(doc.getLastSection())) + { + // Insert the bookmark at the end of the body of the last section. + // Don't increase the count this time as we are just marking the end of the document. + Node lastNode = doc.getLastSection().getBody().getLastChild(); + + builder.moveTo(lastNode); + builder.startBookmark(BOOKMARK_PREFIX + subDocumentCount); + builder.endBookmark(BOOKMARK_PREFIX + subDocumentCount); + } + + // Iterate through each NUMPAGES field in the section and replace it with a PAGEREF field + // referring to the bookmark of the current sub-document. This bookmark is positioned at the end + // of the sub-document but does not exist yet. It is inserted when a section with restart page numbering + // or the last section is encountered. + Node[] nodes = section.getChildNodes(NodeType.FIELD_START, true).toArray(); + + for (FieldStart fieldStart : nodes) + { + if (fieldStart.getFieldType() == FieldType.FIELD_NUM_PAGES) + { + String fieldCode = getFieldCode(fieldStart); + // Since the NUMPAGES field does not take any additional parameters, + // we can assume the field's remaining part. Code after the field name is the switches. + // We will use these to help recreate the NUMPAGES field as a PAGEREF field. + String fieldSwitches = fieldCode.replace(NUM_PAGES_FIELD_NAME, "").trim(); + + // Inserting the new field directly at the FieldStart node of the original field will cause + // the new field not to pick up the original field's formatting. To counter this, + // insert the field just before the original field if a previous run cannot be found, + // we are forced to use the FieldStart node. + Node previousNode = (fieldStart.getPreviousSibling() != null ? fieldStart.getPreviousSibling() : fieldStart); + + // Insert a PAGEREF field at the same position as the field. + builder.moveTo(previousNode); + + Field newField = builder.insertField( + $" {pageRefFieldName} {bookmarkPrefix}{subDocumentCount} {fieldSwitches} "); + + // The field will be inserted before the referenced node. Move the node before the field instead. + previousNode.getParentNode().insertBefore(previousNode, newField.getStart()); + + // Remove the original NUMPAGES field from the document. + removeField(fieldStart); + } + } + } + } + //ExEnd:ConvertNumPageFieldsToPageRef + + //ExStart:GetRemoveField + private void removeField(FieldStart fieldStart) + { + boolean isRemoving = true; + + Node currentNode = fieldStart; + while (currentNode != null && isRemoving) + { + if (currentNode.getNodeType() == NodeType.FIELD_END) + isRemoving = false; + + Node nextNode = currentNode.nextPreOrder(currentNode.getDocument()); + currentNode.remove(); + currentNode = nextNode; + } + } + + private String getFieldCode(FieldStart fieldStart) + { + StringBuilder builder = new StringBuilder(); + + for (Node node = fieldStart; + node != null && node.getNodeType() != NodeType.FIELD_SEPARATOR && + node.getNodeType() != NodeType.FIELD_END; + node = node.nextPreOrder(node.getDocument())) + { + // Use text only of Run nodes to avoid duplication. + if (node.getNodeType() == NodeType.RUN) + msStringBuilder.append(builder, node.getText()); + } + + return builder.toString(); + } + //ExEnd:GetRemoveField + + @Test + public void differentPageSetup() throws Exception + { + //ExStart:DifferentPageSetup + //GistId:db2dfc4150d7c714bcac3782ae241d03 + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // Set the source document to continue straight after the end of the destination document. + srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.CONTINUOUS); + + // Restart the page numbering on the start of the source document. + srcDoc.getFirstSection().getPageSetup().setRestartPageNumbering(true); + srcDoc.getFirstSection().getPageSetup().setPageStartingNumber(1); + + // To ensure this does not happen when the source document has different page setup settings, make sure the + // settings are identical between the last section of the destination document. + // If there are further continuous sections that follow on in the source document, + // this will need to be repeated for those sections. + srcDoc.getFirstSection().getPageSetup().setPageWidth(dstDoc.getLastSection().getPageSetup().getPageWidth()); + srcDoc.getFirstSection().getPageSetup().setPageHeight(dstDoc.getLastSection().getPageSetup().getPageHeight()); + srcDoc.getFirstSection().getPageSetup().setOrientation(dstDoc.getLastSection().getPageSetup().getOrientation()); + + // Iterate through all sections in the source document. + for (Paragraph para : (Iterable) srcDoc.getChildNodes(NodeType.PARAGRAPH, true)) + { + para.getParagraphFormat().setKeepWithNext(true); + } + + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.DifferentPageSetup.docx"); + //ExEnd:DifferentPageSetup + } + + @Test + public void joinContinuous() throws Exception + { + //ExStart:JoinContinuous + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // Make the document appear straight after the destination documents content. + srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.CONTINUOUS); + // Append the source document using the original styles found in the source document. + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.JoinContinuous.docx"); + //ExEnd:JoinContinuous + } + + @Test + public void joinNewPage() throws Exception + { + //ExStart:JoinNewPage + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // Set the appended document to start on a new page. + srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.NEW_PAGE); + // Append the source document using the original styles found in the source document. + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.JoinNewPage.docx"); + //ExEnd:JoinNewPage + } + + @Test + public void keepSourceFormatting() throws Exception + { + //ExStart:KeepSourceFormatting + //GistId:db2dfc4150d7c714bcac3782ae241d03 + Document dstDoc = new Document(); + dstDoc.getFirstSection().getBody().appendParagraph("Destination document text. "); + + Document srcDoc = new Document(); + srcDoc.getFirstSection().getBody().appendParagraph("Source document text. "); + + // Append the source document to the destination document. + // Pass format mode to retain the original formatting of the source document when importing it. + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.KeepSourceFormatting.docx"); + //ExEnd:KeepSourceFormatting + } + + @Test + public void keepSourceTogether() throws Exception + { + //ExStart:KeepSourceTogether + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Document destination with list.docx"); + + // Set the source document to appear straight after the destination document's content. + srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.CONTINUOUS); + + for (Paragraph para : (Iterable) srcDoc.getChildNodes(NodeType.PARAGRAPH, true)) + { + para.getParagraphFormat().setKeepWithNext(true); + } + + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.KeepSourceTogether.docx"); + //ExEnd:KeepSourceTogether + } + + @Test + public void listKeepSourceFormatting() throws Exception + { + //ExStart:ListKeepSourceFormatting + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Document destination with list.docx"); + + // Append the content of the document so it flows continuously. + srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.CONTINUOUS); + + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.ListKeepSourceFormatting.docx"); + //ExEnd:ListKeepSourceFormatting + } + + @Test + public void listUseDestinationStyles() throws Exception + { + //ExStart:ListUseDestinationStyles + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Document destination with list.docx"); + + // Set the source document to continue straight after the end of the destination document. + srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.CONTINUOUS); + + // Keep track of the lists that are created. + HashMap newLists = new HashMap(); + + for (Paragraph para : (Iterable) srcDoc.getChildNodes(NodeType.PARAGRAPH, true)) + { + if (para.isListItem()) + { + int listId = para.getListFormat().getList().getListId(); + + // Check if the destination document contains a list with this ID already. If it does, then this may + // cause the two lists to run together. Create a copy of the list in the source document instead. + if (dstDoc.getLists().getListByListId(listId) != null) + { + List currentList; + // A newly copied list already exists for this ID, retrieve the stored list, + // and use it on the current paragraph. + if (newLists.containsKey(listId)) + { + currentList = newLists.get(listId); + } + else + { + // Add a copy of this list to the document and store it for later reference. + currentList = srcDoc.getLists().addCopy(para.getListFormat().getList()); + msDictionary.add(newLists, listId, currentList); + } + + // Set the list of this paragraph to the copied list. + para.getListFormat().setList(currentList); + } + } + } + + // Append the source document to end of the destination document. + dstDoc.appendDocument(srcDoc, ImportFormatMode.USE_DESTINATION_STYLES); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.ListUseDestinationStyles.docx"); + //ExEnd:ListUseDestinationStyles + } + + @Test + public void restartPageNumbering() throws Exception + { + //ExStart:RestartPageNumbering + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.NEW_PAGE); + srcDoc.getFirstSection().getPageSetup().setRestartPageNumbering(true); + + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.RestartPageNumbering.docx"); + //ExEnd:RestartPageNumbering + } + + @Test + public void updatePageLayout() throws Exception + { + //ExStart:UpdatePageLayout + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // If the destination document is rendered to PDF, image etc. + // or UpdatePageLayout is called before the source document. Is appended, + // then any changes made after will not be reflected in the rendered output + dstDoc.updatePageLayout(); + + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + // For the changes to be updated to rendered output, UpdatePageLayout must be called again. + // If not called again, the appended document will not appear in the output of the next rendering. + dstDoc.updatePageLayout(); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.UpdatePageLayout.docx"); + //ExEnd:UpdatePageLayout + } + + @Test + public void useDestinationStyles() throws Exception + { + //ExStart:UseDestinationStyles + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // Append the source document using the styles of the destination document. + dstDoc.appendDocument(srcDoc, ImportFormatMode.USE_DESTINATION_STYLES); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.UseDestinationStyles.docx"); + //ExEnd:UseDestinationStyles + } + + @Test + public void smartStyleBehavior() throws Exception + { + //ExStart:SmartStyleBehavior + Document dstDoc = new Document(); + DocumentBuilder builder = new DocumentBuilder(dstDoc); + + Style myStyle = builder.getDocument().getStyles().add(StyleType.PARAGRAPH, "MyStyle"); + myStyle.getFont().setSize(14.0); + myStyle.getFont().setName("Courier New"); + myStyle.getFont().setColor(Color.BLUE); + + builder.getParagraphFormat().setStyleName(myStyle.getName()); + builder.writeln("Hello world!"); + + // Clone the document and edit the clone's "MyStyle" style, so it is a different color than that of the original. + // If we insert the clone into the original document, the two styles with the same name will cause a clash. + Document srcDoc = dstDoc.deepClone(); + srcDoc.getStyles().get("MyStyle").getFont().setColor(Color.RED); + + // When we enable SmartStyleBehavior and use the KeepSourceFormatting import format mode, + // Aspose.Words will resolve style clashes by converting source document styles. + // with the same names as destination styles into direct paragraph attributes. + ImportFormatOptions options = new ImportFormatOptions(); + options.setSmartStyleBehavior(true); + + builder.insertDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING, options); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.SmartStyleBehavior.docx"); + //ExEnd:SmartStyleBehavior + } + + @Test + public void insertDocument() throws Exception + { + //ExStart:InsertDocumentWithBuilder + //GistId:db2dfc4150d7c714bcac3782ae241d03 + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + DocumentBuilder builder = new DocumentBuilder(dstDoc); + + builder.moveToDocumentEnd(); + builder.insertBreak(BreakType.PAGE_BREAK); + + builder.insertDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + builder.getDocument().save(getArtifactsDir() + "JoinAndAppendDocuments.InsertDocument.docx"); + //ExEnd:InsertDocumentWithBuilder + } + + @Test + public void insertDocumentInline() throws Exception + { + //ExStart:InsertDocumentInlineWithBuilder + //GistId:db2dfc4150d7c714bcac3782ae241d03 + DocumentBuilder srcDoc = new DocumentBuilder(); + srcDoc.write("[src content]"); + + // Create destination document. + DocumentBuilder dstDoc = new DocumentBuilder(); + dstDoc.write("Before "); + dstDoc.insertNode(new BookmarkStart(dstDoc.getDocument(), "src_place")); + dstDoc.insertNode(new BookmarkEnd(dstDoc.getDocument(), "src_place")); + dstDoc.write(" after"); + + Assert.assertEquals("Before after", msString.trimEnd(dstDoc.getDocument().getText())); + + // Insert source document into destination inline. + dstDoc.moveToBookmark("src_place"); + dstDoc.insertDocumentInline(srcDoc.getDocument(), ImportFormatMode.USE_DESTINATION_STYLES, new ImportFormatOptions()); + + Assert.assertEquals("Before [src content] after", msString.trimEnd(dstDoc.getDocument().getText())); + //ExEnd:InsertDocumentInlineWithBuilder + } + + @Test + public void keepSourceNumbering() throws Exception + { + //ExStart:KeepSourceNumbering + Document srcDoc = new Document(getMyDir() + "List source.docx"); + Document dstDoc = new Document(getMyDir() + "List destination.docx"); + + ImportFormatOptions options = new ImportFormatOptions(); + // If there is a clash of list styles, apply the list format of the source document. + // Set the "KeepSourceNumbering" property to "false" to not import any list numbers into the destination document. + // Set the "KeepSourceNumbering" property to "true" import all clashing + // list style numbering with the same appearance that it had in the source document. + options.setKeepSourceNumbering(true); + + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING, options); + dstDoc.updateListLabels(); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.KeepSourceNumbering.docx"); + //ExEnd:KeepSourceNumbering + } + + @Test + public void ignoreTextBoxes() throws Exception + { + //ExStart:IgnoreTextBoxes + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // Keep the source text boxes formatting when importing. + ImportFormatOptions importFormatOptions = new ImportFormatOptions(); { importFormatOptions.setIgnoreTextBoxes(false); } + + NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING, + importFormatOptions); + + ParagraphCollection srcParas = srcDoc.getFirstSection().getBody().getParagraphs(); + for (Paragraph srcPara : (Iterable) srcParas) + { + Node importedNode = importer.importNode(srcPara, true); + dstDoc.getFirstSection().getBody().appendChild(importedNode); + } + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.IgnoreTextBoxes.docx"); + //ExEnd:IgnoreTextBoxes + } + + @Test + public void ignoreHeaderFooter() throws Exception + { + //ExStart:IgnoreHeaderFooter + Document srcDocument = new Document(getMyDir() + "Document source.docx"); + Document dstDocument = new Document(getMyDir() + "Northwind traders.docx"); + + ImportFormatOptions importFormatOptions = new ImportFormatOptions(); { importFormatOptions.setIgnoreHeaderFooter(false); } + + dstDocument.appendDocument(srcDocument, ImportFormatMode.KEEP_SOURCE_FORMATTING, importFormatOptions); + + dstDocument.save(getArtifactsDir() + "JoinAndAppendDocuments.IgnoreHeaderFooter.docx"); + //ExEnd:IgnoreHeaderFooter + } + + @Test + public void linkHeadersFooters() throws Exception + { + //ExStart:LinkHeadersFooters + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // Set the appended document to appear on a new page. + srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.NEW_PAGE); + // Link the headers and footers in the source document to the previous section. + // This will override any headers or footers already found in the source document. + srcDoc.getFirstSection().getHeadersFooters().linkToPrevious(true); + + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.LinkHeadersFooters.docx"); + //ExEnd:LinkHeadersFooters + } + + @Test + public void removeSourceHeadersFooters() throws Exception + { + //ExStart:RemoveSourceHeadersFooters + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // Remove the headers and footers from each of the sections in the source document. + for (Section section : (Iterable
          ) srcDoc.getSections()) + { + section.clearHeadersFooters(); + } + + // Even after the headers and footers are cleared from the source document, the "LinkToPrevious" setting + // for HeadersFooters can still be set. This will cause the headers and footers to continue from the destination + // document. This should set to false to avoid this behavior. + srcDoc.getFirstSection().getHeadersFooters().linkToPrevious(false); + + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.RemoveSourceHeadersFooters.docx"); + //ExEnd:RemoveSourceHeadersFooters + } + + @Test + public void unlinkHeadersFooters() throws Exception + { + //ExStart:UnlinkHeadersFooters + Document srcDoc = new Document(getMyDir() + "Document source.docx"); + Document dstDoc = new Document(getMyDir() + "Northwind traders.docx"); + + // Unlink the headers and footers in the source document to stop this + // from continuing the destination document's headers and footers. + srcDoc.getFirstSection().getHeadersFooters().linkToPrevious(false); + + dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); + + dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.UnlinkHeadersFooters.docx"); + //ExEnd:UnlinkHeadersFooters + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/WorkingWithDocumentOptionsAndSettings.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/WorkingWithDocumentOptionsAndSettings.java new file mode 100644 index 00000000..e85d957c --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/WorkingWithDocumentOptionsAndSettings.java @@ -0,0 +1,225 @@ +package DocsExamples.Programming_with_Documents.Working_with_Document; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.MsWordVersion; +import com.aspose.ms.System.msConsole; +import com.aspose.words.CleanupOptions; +import com.aspose.words.ViewType; +import com.aspose.words.SectionLayoutMode; +import com.aspose.words.LoadOptions; +import com.aspose.words.EditingLanguage; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.Orientation; +import com.aspose.words.PaperSize; +import com.aspose.words.PageSetup; +import com.aspose.words.PageBorderDistanceFrom; +import com.aspose.words.PageBorderAppliesTo; +import com.aspose.words.Border; +import com.aspose.words.BorderType; +import com.aspose.words.LineStyle; +import java.awt.Color; + + +class WorkingWithDocumentOptionsAndSettings extends DocsExamplesBase +{ + @Test + public void optimizeFor() throws Exception + { + //ExStart:OptimizeFor + //GistId:5d2997d42c1f1fad79b18873f170855f + Document doc = new Document(getMyDir() + "Document.docx"); + + doc.getCompatibilityOptions().optimizeFor(MsWordVersion.WORD_2016); + + doc.save(getArtifactsDir() + "WorkingWithDocumentOptionsAndSettings.OptimizeFor.docx"); + //ExEnd:OptimizeFor + } + + @Test + public void showGrammaticalAndSpellingErrors() throws Exception + { + //ExStart:ShowGrammaticalAndSpellingErrors + Document doc = new Document(getMyDir() + "Document.docx"); + + doc.setShowGrammaticalErrors(true); + doc.setShowSpellingErrors(true); + + doc.save(getArtifactsDir() + "WorkingWithDocumentOptionsAndSettings.ShowGrammaticalAndSpellingErrors.docx"); + //ExEnd:ShowGrammaticalAndSpellingErrors + } + + @Test + public void cleanupUnusedStylesAndLists() throws Exception + { + //ExStart:CleanupUnusedStylesAndLists + //GistId:669f3d08f45b14f75f9d2cb17fa1056a + Document doc = new Document(getMyDir() + "Unused styles.docx"); + + // Combined with the built-in styles, the document now has eight styles. + // A custom style is marked as "used" while there is any text within the document + // formatted in that style. This means that the 4 styles we added are currently unused. + System.out.println("Count of styles before Cleanup: {doc.Styles.Count}\n" + + $"Count of lists before Cleanup: {doc.Lists.Count}"); + + // Cleans unused styles and lists from the document depending on given CleanupOptions. + CleanupOptions cleanupOptions = new CleanupOptions(); { cleanupOptions.setUnusedLists(false); cleanupOptions.setUnusedStyles(true); } + doc.cleanup(cleanupOptions); + + System.out.println("Count of styles after Cleanup was decreased: {doc.Styles.Count}\n" + + $"Count of lists after Cleanup is the same: {doc.Lists.Count}"); + + doc.save(getArtifactsDir() + "WorkingWithDocumentOptionsAndSettings.CleanupUnusedStylesAndLists.docx"); + //ExEnd:CleanupUnusedStylesAndLists + } + + @Test + public void cleanupDuplicateStyle() throws Exception + { + //ExStart:CleanupDuplicateStyle + //GistId:669f3d08f45b14f75f9d2cb17fa1056a + Document doc = new Document(getMyDir() + "Document.docx"); + + // Count of styles before Cleanup. + msConsole.writeLine(doc.getStyles().getCount()); + + // Cleans duplicate styles from the document. + CleanupOptions options = new CleanupOptions(); { options.setDuplicateStyle(true); } + doc.cleanup(options); + + // Count of styles after Cleanup was decreased. + msConsole.writeLine(doc.getStyles().getCount()); + + doc.save(getArtifactsDir() + "WorkingWithDocumentOptionsAndSettings.CleanupDuplicateStyle.docx"); + //ExEnd:CleanupDuplicateStyle + } + + @Test + public void viewOptions() throws Exception + { + //ExStart:SetViewOption + //GistId:5d2997d42c1f1fad79b18873f170855f + Document doc = new Document(getMyDir() + "Document.docx"); + + doc.getViewOptions().setViewType(ViewType.PAGE_LAYOUT); + doc.getViewOptions().setZoomPercent(50); + + doc.save(getArtifactsDir() + "WorkingWithDocumentOptionsAndSettings.ViewOptions.docx"); + //ExEnd:SetViewOption + } + + @Test + public void documentPageSetup() throws Exception + { + //ExStart:DocumentPageSetup + //GistId:5d2997d42c1f1fad79b18873f170855f + Document doc = new Document(getMyDir() + "Document.docx"); + + // Set the layout mode for a section allowing to define the document grid behavior. + // Note that the Document Grid tab becomes visible in the Page Setup dialog of MS Word + // if any Asian language is defined as editing language. + doc.getFirstSection().getPageSetup().setLayoutMode(SectionLayoutMode.GRID); + doc.getFirstSection().getPageSetup().setCharactersPerLine(30); + doc.getFirstSection().getPageSetup().setLinesPerPage(10); + + doc.save(getArtifactsDir() + "WorkingWithDocumentOptionsAndSettings.DocumentPageSetup.docx"); + //ExEnd:DocumentPageSetup + } + + @Test + public void addEditingLanguage() throws Exception + { + //ExStart:AddEditingLanguage + //GistId:40be8275fc43f78f5e5877212e4e1bf3 + LoadOptions loadOptions = new LoadOptions(); + // Set language preferences that will be used when document is loading. + loadOptions.getLanguagePreferences().addEditingLanguage(EditingLanguage.JAPANESE); + + Document doc = new Document(getMyDir() + "No default editing language.docx", loadOptions); + //ExEnd:AddEditingLanguage + + int localeIdFarEast = doc.getStyles().getDefaultFont().getLocaleIdFarEast(); + System.out.println(localeIdFarEast == (int) EditingLanguage.JAPANESE + ? "The document either has no any FarEast language set in defaults or it was set to Japanese originally." + : "The document default FarEast language was set to another than Japanese language originally, so it is not overridden."); + } + + @Test + public void setRussianAsDefaultEditingLanguage() throws Exception + { + //ExStart:SetRussianAsDefaultEditingLanguage + //GistId:5d2997d42c1f1fad79b18873f170855f + LoadOptions loadOptions = new LoadOptions(); + loadOptions.getLanguagePreferences().setDefaultEditingLanguage(EditingLanguage.RUSSIAN); + + Document doc = new Document(getMyDir() + "No default editing language.docx", loadOptions); + + int localeId = doc.getStyles().getDefaultFont().getLocaleId(); + System.out.println(localeId == (int) EditingLanguage.RUSSIAN + ? "The document either has no any language set in defaults or it was set to Russian originally." + : "The document default language was set to another than Russian language originally, so it is not overridden."); + //ExEnd:SetRussianAsDefaultEditingLanguage + } + + @Test + public void pageSetupAndSectionFormatting() throws Exception + { + //ExStart:PageSetupAndSectionFormatting + //GistId:1afca4d3da7cb4240fb91c3d93d8c30d + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.getPageSetup().setOrientation(Orientation.LANDSCAPE); + builder.getPageSetup().setLeftMargin(50.0); + builder.getPageSetup().setPaperSize(PaperSize.PAPER_10_X_14); + + doc.save(getArtifactsDir() + "WorkingWithDocumentOptionsAndSettings.PageSetupAndSectionFormatting.docx"); + //ExEnd:PageSetupAndSectionFormatting + } + + @Test + public void pageBorderProperties() throws Exception + { + //ExStart:PageBorderProperties + Document doc = new Document(); + + PageSetup pageSetup = doc.getSections().get(0).getPageSetup(); + pageSetup.setBorderAlwaysInFront(false); + pageSetup.setBorderDistanceFrom(PageBorderDistanceFrom.PAGE_EDGE); + pageSetup.setBorderAppliesTo(PageBorderAppliesTo.FIRST_PAGE); + + Border border = pageSetup.getBorders().getByBorderType(BorderType.TOP); + border.setLineStyle(LineStyle.SINGLE); + border.setLineWidth(30.0); + border.setColor(Color.BLUE); + border.setDistanceFromText(0.0); + + doc.save(getArtifactsDir() + "WorkingWithDocumentOptionsAndSettings.PageBorderProperties.docx"); + //ExEnd:PageBorderProperties + } + + @Test + public void lineGridSectionLayoutMode() throws Exception + { + //ExStart:LineGridSectionLayoutMode + //GistId:1afca4d3da7cb4240fb91c3d93d8c30d + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Enable pitching, and then use it to set the number of lines per page in this section. + // A large enough font size will push some lines down onto the next page to avoid overlapping characters. + builder.getPageSetup().setLayoutMode(SectionLayoutMode.LINE_GRID); + builder.getPageSetup().setLinesPerPage(15); + + builder.getParagraphFormat().setSnapToGrid(true); + + for (int i = 0; i < 30; i++) + builder.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "); + + doc.save(getArtifactsDir() + "WorkingWithDocumentOptionsAndSettings.LinesPerPage.docx"); + //ExEnd:LineGridSectionLayoutMode + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/WorkingWithDocumentProperties.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/WorkingWithDocumentProperties.java new file mode 100644 index 00000000..b1698316 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/WorkingWithDocumentProperties.java @@ -0,0 +1,155 @@ +package DocsExamples.Programming_with_Documents.Working_with_Document; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import java.util.Map; +import com.aspose.ms.System.msConsole; +import com.aspose.words.DocumentProperty; +import com.aspose.words.CustomDocumentProperties; +import com.aspose.ms.System.DateTime; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.PageSetup; +import com.aspose.words.ConvertUtil; +import com.aspose.words.ControlChar; + + +class DocumentPropertiesAndVariables extends DocsExamplesBase +{ + @Test + public void getVariables() throws Exception + { + //ExStart:GetVariables + //GistId:0593a8803015363f3026f648332e7026 + Document doc = new Document(getMyDir() + "Document.docx"); + + String variables = ""; + for (Map.Entry entry : doc.getVariables()) + { + String name = entry.getKey(); + String value = entry.getValue(); + if ("".equals(variables)) + variables = "Name: " + name + "," + "Value: {1}" + value; + else + variables = variables + "Name: " + name + "," + "Value: {1}" + value; + } + + System.out.println("\nDocument have following variables " + variables); + //ExEnd:GetVariables + } + + @Test + public void enumerateProperties() throws Exception + { + //ExStart:EnumerateProperties + //GistId:0593a8803015363f3026f648332e7026 + Document doc = new Document(getMyDir() + "Properties.docx"); + + System.out.println("1. Document name: {0}",doc.getOriginalFileName()); + System.out.println("2. Built-in Properties"); + + for (DocumentProperty prop : (Iterable) doc.getBuiltInDocumentProperties()) + System.out.println("{0} : {1}",prop.getName(),prop.getValue()); + + System.out.println("3. Custom Properties"); + + for (DocumentProperty prop : (Iterable) doc.getCustomDocumentProperties()) + System.out.println("{0} : {1}",prop.getName(),prop.getValue()); + //ExEnd:EnumerateProperties + } + + @Test + public void addCustomProperties() throws Exception + { + //ExStart:AddCustomProperties + //GistId:0593a8803015363f3026f648332e7026 + Document doc = new Document(getMyDir() + "Properties.docx"); + + CustomDocumentProperties customDocumentProperties = doc.getCustomDocumentProperties(); + + if (customDocumentProperties.get("Authorized") != null) return; + + customDocumentProperties.add("Authorized", true); + customDocumentProperties.add("Authorized By", "John Smith"); + customDocumentProperties.addInternal("Authorized Date", DateTime.getToday()); + customDocumentProperties.add("Authorized Revision", doc.getBuiltInDocumentProperties().getRevisionNumber()); + customDocumentProperties.add("Authorized Amount", 123.45); + //ExEnd:AddCustomProperties + } + + @Test + public void removeCustomProperties() throws Exception + { + //ExStart:RemoveCustomProperties + //GistId:0593a8803015363f3026f648332e7026 + Document doc = new Document(getMyDir() + "Properties.docx"); + doc.getCustomDocumentProperties().remove("Authorized Date"); + //ExEnd:RemoveCustomProperties + } + + @Test + public void removePersonalInformation() throws Exception + { + //ExStart:RemovePersonalInformation + //GistId:0593a8803015363f3026f648332e7026 + Document doc = new Document(getMyDir() + "Properties.docx"); { doc.setRemovePersonalInformation(true); } + + doc.save(getArtifactsDir() + "DocumentPropertiesAndVariables.RemovePersonalInformation.docx"); + //ExEnd:RemovePersonalInformation + } + + @Test + public void configuringLinkToContent() throws Exception + { + //ExStart:ConfiguringLinkToContent + //GistId:0593a8803015363f3026f648332e7026 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startBookmark("MyBookmark"); + builder.writeln("Text inside a bookmark."); + builder.endBookmark("MyBookmark"); + + // Retrieve a list of all custom document properties from the file. + CustomDocumentProperties customProperties = doc.getCustomDocumentProperties(); + // Add linked to content property. + DocumentProperty customProperty = customProperties.addLinkToContent("Bookmark", "MyBookmark"); + customProperty = customProperties.get("Bookmark"); + + boolean isLinkedToContent = customProperty.isLinkToContent(); + String linkSource = customProperty.getLinkSource(); + String customPropertyValue = customProperty.getValue().toString(); + //ExEnd:ConfiguringLinkToContent + } + + @Test + public void convertBetweenMeasurementUnits() throws Exception + { + //ExStart:ConvertBetweenMeasurementUnits + //GistId:f266e937d2c656f9441071e9a7b053c1 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + PageSetup pageSetup = builder.getPageSetup(); + pageSetup.setTopMargin(ConvertUtil.inchToPoint(1.0)); + pageSetup.setBottomMargin(ConvertUtil.inchToPoint(1.0)); + pageSetup.setLeftMargin(ConvertUtil.inchToPoint(1.5)); + pageSetup.setRightMargin(ConvertUtil.inchToPoint(1.5)); + pageSetup.setHeaderDistance(ConvertUtil.inchToPoint(0.2)); + pageSetup.setFooterDistance(ConvertUtil.inchToPoint(0.2)); + //ExEnd:ConvertBetweenMeasurementUnits + } + + @Test + public void useControlCharacters() + { + //ExStart:UseControlCharacters + //GistId:6269ddb6427f9ad20623d975774a615e + final String TEXT = "test\r"; + // Replace "\r" control character with "\r\n". + String replace = TEXT.replace(ControlChar.CR, ControlChar.CR_LF); + //ExEnd:UseControlCharacters + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/WorkingWithWebExtension.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/WorkingWithWebExtension.java new file mode 100644 index 00000000..9685cdc3 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_document/WorkingWithWebExtension.java @@ -0,0 +1,58 @@ +package DocsExamples.Programming_with_Documents.Working_with_Document; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.TaskPane; +import com.aspose.words.TaskPaneDockState; +import com.aspose.words.WebExtensionStoreType; +import com.aspose.words.WebExtensionProperty; +import com.aspose.words.WebExtensionBinding; +import com.aspose.words.WebExtensionBindingType; +import com.aspose.ms.System.msConsole; +import com.aspose.words.WebExtensionReference; + + +class WorkingWithWebExtension extends DocsExamplesBase +{ + @Test + public void webExtensionTaskPanes() throws Exception + { + //ExStart:WebExtensionTaskPanes + //GistId:8c31c018ea71c92828223776b1a113f7 + Document doc = new Document(); + + TaskPane taskPane = new TaskPane(); + doc.getWebExtensionTaskPanes().add(taskPane); + + taskPane.setDockState(TaskPaneDockState.RIGHT); + taskPane.isVisible(true); + taskPane.setWidth(300.0); + + taskPane.getWebExtension().getReference().setId("wa102923726"); + taskPane.getWebExtension().getReference().setVersion("1.0.0.0"); + taskPane.getWebExtension().getReference().setStoreType(WebExtensionStoreType.OMEX); + taskPane.getWebExtension().getReference().setStore("th-TH"); + taskPane.getWebExtension().getProperties().add(new WebExtensionProperty("mailchimpCampaign", "mailchimpCampaign")); + taskPane.getWebExtension().getBindings().add(new WebExtensionBinding("UnnamedBinding_0_1506535429545", + WebExtensionBindingType.TEXT, "194740422")); + + doc.save(getArtifactsDir() + "WorkingWithWebExtension.WebExtensionTaskPanes.docx"); + //ExEnd:WebExtensionTaskPanes + + //ExStart:GetListOfAddins + //GistId:8c31c018ea71c92828223776b1a113f7 + doc = new Document(getArtifactsDir() + "WorkingWithWebExtension.WebExtensionTaskPanes.docx"); + + System.out.println("Task panes sources:\n"); + + for (TaskPane taskPaneInfo : (Iterable) doc.getWebExtensionTaskPanes()) + { + WebExtensionReference reference = taskPaneInfo.getWebExtension().getReference(); + System.out.println("Provider: \"{reference.Store}\", version: \"{reference.Version}\", catalog identifier: \"{reference.Id}\";"); + } + //ExEnd:GetListOfAddins + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_graphic_elements/CustomBarcodeGenerator.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_graphic_elements/CustomBarcodeGenerator.java new file mode 100644 index 00000000..91d7fade --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_graphic_elements/CustomBarcodeGenerator.java @@ -0,0 +1,329 @@ +// Copyright (c) 2001-2024 Aspose Pty Ltd. All Rights Reserved. +// +// This file is part of Aspose.Words. The source code in this file +// is only intended as a supplement to the documentation, and is provided +// "as is", without warranty of any kind, either expressed or implied. +////////////////////////////////////////////////////////////////////////// + +package DocsExamples; + +// ********* THIS FILE IS AUTO PORTED ********* + +import com.aspose.ms.java.collections.StringSwitchMap; +import java.lang.Integer; +import com.aspose.barcode.SymbologyEncodeType; +import com.aspose.barcode.EncodeTypes; +import java.awt.Color; +import com.aspose.ms.System.msString; +import com.aspose.ms.System.Convert; +import java.awt.image.BufferedImage; +import java.awt.Graphics2D; +import com.aspose.ms.System.Drawing.msFont; +import java.awt.Font; +import com.aspose.ms.System.Drawing.FontStyle; +import com.aspose.ms.System.Drawing.Rectangle; +import com.aspose.words.IBarcodeGenerator; +import com.aspose.words.BarcodeParameters; +import com.aspose.ms.System.msMath; +import com.aspose.ms.System.Drawing.RectangleF; + + +class CustomBarcodeGeneratorUtils +{ + /// + /// Converts a height value in twips to pixels using a default DPI of 96. + /// + /// The height value in twips. + /// The default value to return if the conversion fails. + /// The height value in pixels. + public static double twipsToPixels(String heightInTwips, double defVal) + { + return twipsToPixels(heightInTwips, 96.0, defVal); + } + + /// + /// Converts a height value in twips to pixels based on the given resolution. + /// + /// The height value in twips to be converted. + /// The resolution in pixels per inch. + /// The default value to be returned if the conversion fails. + /// The converted height value in pixels. + public static double twipsToPixels(String heightInTwips, double resolution, double defVal) + { + try + { + int lVal = Integer.parseInt(heightInTwips); + return (lVal / 1440.0) * resolution; + } + catch(Exception e) + { + return defVal; + } + } + + /// + /// Gets the rotation angle in degrees based on the given rotation angle string. + /// + /// The rotation angle string. + /// The default value to return if the rotation angle is not recognized. + /// The rotation angle in degrees. + public static float getRotationAngle(String rotationAngle, float defVal) + { + switch (gStringSwitchMap.of(rotationAngle)) + { + case /*"0"*/0: + return 0f; + case /*"1"*/1: + return 270f; + case /*"2"*/2: + return 180f; + case /*"3"*/3: + return 90f; + default: + return defVal; + } + } + + /// + /// Converts a string representation of an error correction level to a QRErrorLevel enum value. + /// + /// The string representation of the error correction level. + /// The default error correction level to return if the input is invalid. + /// The corresponding QRErrorLevel enum value. + public static QRErrorLevel getQRCorrectionLevel(String errorCorrectionLevel, QRErrorLevel def) + { + switch (gStringSwitchMap.of(errorCorrectionLevel)) + { + case /*"0"*/0: + return QRErrorLevel.LevelL; + case /*"1"*/1: + return QRErrorLevel.LevelM; + case /*"2"*/2: + return QRErrorLevel.LevelQ; + case /*"3"*/3: + return QRErrorLevel.LevelH; + default: + return def; + } + } + + /// + /// Gets the barcode encode type based on the given encode type from Word. + /// + /// The encode type from Word. + /// The barcode encode type. + public static SymbologyEncodeType getBarcodeEncodeType(String encodeTypeFromWord) + { + // https://support.microsoft.com/en-au/office/field-codes-displaybarcode-6d81eade-762d-4b44-ae81-f9d3d9e07be3 + switch (gStringSwitchMap.of(encodeTypeFromWord)) + { + case /*"QR"*/4: + return EncodeTypes.QR; + case /*"CODE128"*/5: + return EncodeTypes.CODE_128; + case /*"CODE39"*/6: + return EncodeTypes.Code39; + case /*"JPPOST"*/7: + return EncodeTypes.RM_4_SCC; + case /*"EAN8"*/8: + case /*"JAN8"*/9: + return EncodeTypes.EAN_8; + case /*"EAN13"*/10: + case /*"JAN13"*/11: + return EncodeTypes.EAN_13; + case /*"UPCA"*/12: + return EncodeTypes.UPCA; + case /*"UPCE"*/13: + return EncodeTypes.UPCE; + case /*"CASE"*/14: + case /*"ITF14"*/15: + return EncodeTypes.ITF_14; + case /*"NW7"*/16: + return EncodeTypes.CODABAR; + default: + return EncodeTypes.None; + } + } + + /// + /// Converts a hexadecimal color string to a Color object. + /// + /// The hexadecimal color string to convert. + /// The default Color value to return if the conversion fails. + /// The Color object representing the converted color, or the default value if the conversion fails. + public static Color convertColor(String inputColor, Color defVal) + { + if (msString.isNullOrEmpty(inputColor)) return defVal; + try + { + int color = Convert.toInt32(inputColor, 16); + // Return Color.FromArgb((color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF); + return new Color((color & 0xFF), ((color >> 8) & 0xFF), ((color >> 16) & 0xFF)); + } + catch(Exception e) + { + return defVal; + } + } + + /// + /// Calculates the scale factor based on the provided string representation. + /// + /// The string representation of the scale factor. + /// The default value to return if the scale factor cannot be parsed. + /// + /// The scale factor as a decimal value between 0 and 1, or the default value if the scale factor cannot be parsed. + /// + public static double scaleFactor(String scaleFactor, double defVal) + { + try + { + int scale = Integer.parseInt(scaleFactor); + return scale / 100.0; + } + catch(Exception e) + { + return defVal; + } + } + + /// + /// Sets the position code style for a barcode generator. + /// + /// The barcode generator. + /// The position code style to set. + /// The barcode value. + public static void setPosCodeStyle(BarcodeGenerator gen, String posCodeStyle, String barcodeValue) + { + switch (gStringSwitchMap.of(posCodeStyle)) + { + // STD default and without changes. + case /*"SUP2"*/17: + gen.CodeText = barcodeValue.substring((0), (0) + (barcodeValue.length() - 2)); + gen.Parameters.Barcode.Supplement.SupplementData = barcodeValue.substring((barcodeValue.length() - 2), (barcodeValue.length() - 2) + (2)); + break; + case /*"SUP5"*/18: + gen.CodeText = barcodeValue.substring((0), (0) + (barcodeValue.length() - 5)); + gen.Parameters.Barcode.Supplement.SupplementData = barcodeValue.substring((barcodeValue.length() - 5), (barcodeValue.length() - 5) + (5)); + break; + case /*"CASE"*/14: + gen.Parameters.Border.Visible = true; + gen.Parameters.Border.Color = gen.Parameters.Barcode.BarColor; + gen.Parameters.Border.DashStyle = BorderDashStyle.Solid; + gen.Parameters.Border.Width.Pixels = gen.Parameters.Barcode.XDimension.Pixels * 5; + break; + } + } + + public static final double DEFAULT_QRX_DIMENSION_IN_PIXELS = 4.0; + public static final double DEFAULT_1_DX_DIMENSION_IN_PIXELS = 1.0; + + /// + /// Draws an error image with the specified exception message. + /// + /// The exception containing the error message. + /// A Bitmap object representing the error image. + public static BufferedImage drawErrorImage(Exception error) + { + BufferedImage bmp = new BufferedImage(100, 100); + + Graphics2D grf = Graphics2D.FromImage(bmp); + try /*JAVA: was using*/ + { + grf.DrawString(error.getMessage(), msFont.newFont("Microsoft Sans Serif", 8f, FontStyle.REGULAR), Brushes.Red, RectangleF.fromRectangle(new Rectangle(0, 0, bmp.getWidth(), bmp.getHeight()))); + } + finally { if (grf != null) grf.close(); } + return bmp; + } + + public static BufferedImage convertImageToWord(BufferedImage bmp) + { + return bmp; + } + + //JAVA-added for string switch emulation + private static final StringSwitchMap gStringSwitchMap = new StringSwitchMap + ( + "0", + "1", + "2", + "3", + "QR", + "CODE128", + "CODE39", + "JPPOST", + "EAN8", + "JAN8", + "EAN13", + "JAN13", + "UPCA", + "UPCE", + "CASE", + "ITF14", + "NW7", + "SUP2", + "SUP5" + ); + +} + +class CustomBarcodeGenerator implements IBarcodeGenerator +{ + public BufferedImage getBarcodeImage(BarcodeParameters parameters) + { + try + { + BarcodeGenerator gen = new BarcodeGenerator(CustomBarcodeGeneratorUtils.getBarcodeEncodeType(parameters.getBarcodeType()), parameters.getBarcodeValue()); + + // Set color. + gen.Parameters.Barcode.BarColor = CustomBarcodeGeneratorUtils.ConvertColor(parameters.getForegroundColor(), gen.Parameters.Barcode.BarColor); + gen.Parameters.BackColor = CustomBarcodeGeneratorUtils.ConvertColor(parameters.getBackgroundColor(), gen.Parameters.BackColor); + + // Set display or hide text. + if (!parameters.getDisplayText()) + gen.Parameters.Barcode.CodeTextParameters.Location = CodeLocation.None; + else + gen.Parameters.Barcode.CodeTextParameters.Location = CodeLocation.Below; + + // Set QR Code error correction level.s + gen.Parameters.Barcode.QR.QrErrorLevel = QRErrorLevel.LevelH; + if (!msString.isNullOrEmpty(parameters.getErrorCorrectionLevel())) + gen.Parameters.Barcode.QR.QrErrorLevel = CustomBarcodeGeneratorUtils.GetQRCorrectionLevel(parameters.getErrorCorrectionLevel(), gen.Parameters.Barcode.QR.QrErrorLevel); + + // Set rotation angle. + if (!msString.isNullOrEmpty(parameters.getSymbolRotation())) + gen.Parameters.RotationAngle = CustomBarcodeGeneratorUtils.GetRotationAngle(parameters.getSymbolRotation(), gen.Parameters.RotationAngle); + + // Set scaling factor. + double scalingFactor = 1.0; + if (!msString.isNullOrEmpty(parameters.getScalingFactor())) + scalingFactor = CustomBarcodeGeneratorUtils.scaleFactor(parameters.getScalingFactor(), scalingFactor); + + // Set size. + if (gen.BarcodeType == EncodeTypes.QR) + gen.Parameters.Barcode.XDimension.Pixels = (float)Math.max(1.0, msMath.round(CustomBarcodeGeneratorUtils.DEFAULT_QRX_DIMENSION_IN_PIXELS * scalingFactor)); + else + gen.Parameters.Barcode.XDimension.Pixels = (float)Math.max(1.0, msMath.round(CustomBarcodeGeneratorUtils.DEFAULT_1_DX_DIMENSION_IN_PIXELS * scalingFactor)); + + //Set height. + if (!msString.isNullOrEmpty(parameters.getSymbolHeight())) + gen.Parameters.Barcode.BarHeight.Pixels = (float)Math.Max(5.0, Math.Round(CustomBarcodeGeneratorUtils.TwipsToPixels(parameters.getSymbolHeight(), gen.Parameters.Barcode.BarHeight.Pixels) * scalingFactor)); + + // Set style of a Point-of-Sale barcode. + if (!msString.isNullOrEmpty(parameters.getPosCodeStyle())) + CustomBarcodeGeneratorUtils.setPosCodeStyle(gen, parameters.getPosCodeStyle(), parameters.getBarcodeValue()); + + return CustomBarcodeGeneratorUtils.ConvertImageToWord(gen.GenerateBarCodeImage()); + } + catch (Exception e) + { + return CustomBarcodeGeneratorUtils.convertImageToWord(CustomBarcodeGeneratorUtils.drawErrorImage(e)); + } + } + + public BufferedImage getOldBarcodeImage(BarcodeParameters parameters) + { + throw new UnsupportedOperationException(); + } +} + diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_graphic_elements/WorkingWithBarcodeGenerator.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_graphic_elements/WorkingWithBarcodeGenerator.java new file mode 100644 index 00000000..7b185c48 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_graphic_elements/WorkingWithBarcodeGenerator.java @@ -0,0 +1,25 @@ +package DocsExamples.Programming_with_Documents.Working_with_Graphic_Elements; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import DocsExamples.CustomBarcodeGenerator; + + +class WorkingWithBarcodeGenerator extends DocsExamplesBase +{ + @Test + public void barcodeGenerator() throws Exception + { + //ExStart:BarcodeGenerator + //GistId:00d34dba66626dbc0175b60bb3b71c8a + Document doc = new Document(getMyDir() + "Field sample - BARCODE.docx"); + + doc.getFieldOptions().setBarcodeGenerator(new CustomBarcodeGenerator()); + + doc.save(getArtifactsDir() + "WorkingWithBarcodeGenerator.BarcodeGenerator.pdf"); + //ExEnd:BarcodeGenerator + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_graphic_elements/WorkingWithCharts.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_graphic_elements/WorkingWithCharts.java new file mode 100644 index 00000000..2df3e382 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_graphic_elements/WorkingWithCharts.java @@ -0,0 +1,597 @@ +package DocsExamples.Programming_with_Documents.Working_with_Graphic_Elements; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.Shape; +import com.aspose.words.ChartType; +import com.aspose.words.Chart; +import com.aspose.words.ChartSeries; +import com.aspose.words.LegendPosition; +import com.aspose.words.ChartSeriesCollection; +import com.aspose.ms.System.msConsole; +import com.aspose.ms.System.DateTime; +import com.aspose.words.ChartAxis; +import com.aspose.words.AxisCategoryType; +import com.aspose.words.AxisCrosses; +import com.aspose.words.AxisTickMark; +import com.aspose.words.AxisTickLabelPosition; +import com.aspose.words.AxisBuiltInUnit; +import com.aspose.words.AxisBound; +import com.aspose.words.ParagraphAlignment; +import com.aspose.words.ChartDataLabelCollection; +import com.aspose.words.ChartDataPointCollection; +import com.aspose.words.ChartDataPoint; +import com.aspose.words.MarkerSymbol; +import java.awt.Color; +import com.aspose.ms.System.Drawing.msColor; + + +class WorkingWithCharts extends DocsExamplesBase +{ + @Test + public void formatNumberOfDataLabel() throws Exception + { + //ExStart:FormatNumberOfDataLabel + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.LINE, 432.0, 252.0); + + Chart chart = shape.getChart(); + chart.getTitle().setText("Data Labels With Different Number Format"); + + // Delete default generated series. + chart.getSeries().clear(); + + ChartSeries series1 = chart.getSeries().add("Aspose Series 1", + new String[] { "Category 1", "Category 2", "Category 3" }, + new double[] { 2.5, 1.5, 3.5 }); + + series1.hasDataLabels(true); + series1.getDataLabels().setShowValue(true); + series1.getDataLabels().get(0).getNumberFormat().setFormatCode("\"$\"#,##0.00"); + series1.getDataLabels().get(1).getNumberFormat().setFormatCode("dd/mm/yyyy"); + series1.getDataLabels().get(2).getNumberFormat().setFormatCode("0.00%"); + + // Or you can set format code to be linked to a source cell, + // in this case NumberFormat will be reset to general and inherited from a source cell. + series1.getDataLabels().get(2).getNumberFormat().isLinkedToSource(true); + + doc.save(getArtifactsDir() + "WorkingWithCharts.FormatNumberOfDataLabel.docx"); + //ExEnd:FormatNumberOfDataLabel + } + + @Test + public void createChartUsingShape() throws Exception + { + //ExStart:CreateChartUsingShape + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.LINE, 432.0, 252.0); + + Chart chart = shape.getChart(); + chart.getTitle().setShow(true); + chart.getTitle().setText("Line Chart Title"); + chart.getTitle().setOverlay(false); + + // Please note if null or empty value is specified as title text, auto generated title will be shown. + + chart.getLegend().setPosition(LegendPosition.LEFT); + chart.getLegend().setOverlay(true); + + doc.save(getArtifactsDir() + "WorkingWithCharts.CreateChartUsingShape.docx"); + //ExEnd:CreateChartUsingShape + } + + @Test + public void insertSimpleColumnChart() throws Exception + { + //ExStart:InsertSimpleColumnChart + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // You can specify different chart types and sizes. + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + + Chart chart = shape.getChart(); + //ExStart:ChartSeriesCollection + //GistId:23d39c0b874655d7e7354f1ecc122e39 + ChartSeriesCollection seriesColl = chart.getSeries(); + + msConsole.writeLine(seriesColl.getCount()); + //ExEnd:ChartSeriesCollection + + // Delete default generated series. + seriesColl.clear(); + + // Create category names array, in this example we have two categories. + String[] categories = new String[] { "Category 1", "Category 2" }; + + // Please note, data arrays must not be empty and arrays must be the same size. + seriesColl.add("Aspose Series 1", categories, new double[] { 1.0, 2.0 }); + seriesColl.add("Aspose Series 2", categories, new double[] { 3.0, 4.0 }); + seriesColl.add("Aspose Series 3", categories, new double[] { 5.0, 6.0 }); + seriesColl.add("Aspose Series 4", categories, new double[] { 7.0, 8.0 }); + seriesColl.add("Aspose Series 5", categories, new double[] { 9.0, 10.0 }); + + doc.save(getArtifactsDir() + "WorkingWithCharts.InsertSimpleColumnChart.docx"); + //ExEnd:InsertSimpleColumnChart + } + + @Test + public void insertColumnChart() throws Exception + { + //ExStart:InsertColumnChart + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + + Chart chart = shape.getChart(); + chart.getSeries().add("Aspose Series 1", new String[] { "Category 1", "Category 2" }, new double[] { 1.0, 2.0 }); + + doc.save(getArtifactsDir() + "WorkingWithCharts.InsertColumnChart.docx"); + //ExEnd:InsertColumnChart + } + + @Test + public void insertAreaChart() throws Exception + { + //ExStart:InsertAreaChart + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.AREA, 432.0, 252.0); + + Chart chart = shape.getChart(); + chart.getSeries().addInternal("Aspose Series 1", new DateTime[] + { + new DateTime(2002, 5, 1), + new DateTime(2002, 6, 1), + new DateTime(2002, 7, 1), + new DateTime(2002, 8, 1), + new DateTime(2002, 9, 1) + }, + new double[] { 32.0, 32.0, 28.0, 12.0, 15.0 }); + + doc.save(getArtifactsDir() + "WorkingWithCharts.InsertAreaChart.docx"); + //ExEnd:InsertAreaChart + } + + @Test + public void insertBubbleChart() throws Exception + { + //ExStart:InsertBubbleChart + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.BUBBLE, 432.0, 252.0); + + Chart chart = shape.getChart(); + chart.getSeries().add("Aspose Series 1", new double[] { 0.7, 1.8, 2.6 }, new double[] { 2.7, 3.2, 0.8 }, + new double[] { 10.0, 4.0, 8.0 }); + + doc.save(getArtifactsDir() + "WorkingWithCharts.InsertBubbleChart.docx"); + //ExEnd:InsertBubbleChart + } + + @Test + public void insertScatterChart() throws Exception + { + //ExStart:InsertScatterChart + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.SCATTER, 432.0, 252.0); + + Chart chart = shape.getChart(); + chart.getSeries().add("Aspose Series 1", new double[] { 0.7, 1.8, 2.6 }, new double[] { 2.7, 3.2, 0.8 }); + + doc.save(getArtifactsDir() + "WorkingWithCharts.InsertScatterChart.docx"); + //ExEnd:InsertScatterChart + } + + @Test + public void defineAxisProperties() throws Exception + { + //ExStart:DefineAxisProperties + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert chart + Shape shape = builder.insertChart(ChartType.AREA, 432.0, 252.0); + + Chart chart = shape.getChart(); + + chart.getSeries().clear(); + + chart.getSeries().addInternal("Aspose Series 1", + new DateTime[] + { + new DateTime(2002, 1, 1), new DateTime(2002, 6, 1), new DateTime(2002, 7, 1), + new DateTime(2002, 8, 1), new DateTime(2002, 9, 1) + }, + new double[] { 640.0, 320.0, 280.0, 120.0, 150.0 }); + + ChartAxis xAxis = chart.getAxisX(); + ChartAxis yAxis = chart.getAxisY(); + + // Change the X axis to be category instead of date, so all the points will be put with equal interval on the X axis. + xAxis.setCategoryType(AxisCategoryType.CATEGORY); + xAxis.setCrosses(AxisCrosses.CUSTOM); + xAxis.setCrossesAt(3.0); // Measured in display units of the Y axis (hundreds). + xAxis.setReverseOrder(true); + xAxis.setMajorTickMark(AxisTickMark.CROSS); + xAxis.setMinorTickMark(AxisTickMark.OUTSIDE); + xAxis.getTickLabels().setOffset(200); + + yAxis.getTickLabels().setPosition(AxisTickLabelPosition.HIGH); + yAxis.setMajorUnit(100.0); + yAxis.setMinorUnit(50.0); + yAxis.getDisplayUnit().setUnit(AxisBuiltInUnit.HUNDREDS); + yAxis.getScaling().setMinimum(new AxisBound(100.0)); + yAxis.getScaling().setMaximum(new AxisBound(700.0)); + + doc.save(getArtifactsDir() + "WorkingWithCharts.DefineAxisProperties.docx"); + //ExEnd:DefineAxisProperties + } + + @Test + public void dateTimeValuesToAxis() throws Exception + { + //ExStart:DateTimeValuesToAxis + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + Chart chart = shape.getChart(); + + chart.getSeries().clear(); + + chart.getSeries().addInternal("Aspose Series 1", + new DateTime[] + { + new DateTime(2017, 11, 6), new DateTime(2017, 11, 9), new DateTime(2017, 11, 15), + new DateTime(2017, 11, 21), new DateTime(2017, 11, 25), new DateTime(2017, 11, 29) + }, + new double[] { 1.2, 0.3, 2.1, 2.9, 4.2, 5.3 }); + + ChartAxis xAxis = chart.getAxisX(); + xAxis.getScaling().setMinimum(new AxisBound(new DateTime(2017, 11, 5).toOADate())); + xAxis.getScaling().setMaximum(new AxisBound(new DateTime(2017, 12, 3).toOADate())); + + // Set major units to a week and minor units to a day. + xAxis.setMajorUnit(7.0); + xAxis.setMinorUnit(1.0); + xAxis.setMajorTickMark(AxisTickMark.CROSS); + xAxis.setMinorTickMark(AxisTickMark.OUTSIDE); + + doc.save(getArtifactsDir() + "WorkingWithCharts.DateTimeValuesToAxis.docx"); + //ExEnd:DateTimeValuesToAxis + } + + @Test + public void numberFormatForAxis() throws Exception + { + //ExStart:NumberFormatForAxis + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + + Chart chart = shape.getChart(); + + chart.getSeries().clear(); + + chart.getSeries().add("Aspose Series 1", + new String[] { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }, + new double[] { 1900000.0, 850000.0, 2100000.0, 600000.0, 1500000.0 }); + + chart.getAxisY().getNumberFormat().setFormatCode("#,##0"); + + doc.save(getArtifactsDir() + "WorkingWithCharts.NumberFormatForAxis.docx"); + //ExEnd:NumberFormatForAxis + } + + @Test + public void boundsOfAxis() throws Exception + { + //ExStart:BoundsOfAxis + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + + Chart chart = shape.getChart(); + + chart.getSeries().clear(); + + chart.getSeries().add("Aspose Series 1", + new String[] { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }, + new double[] { 1.2, 0.3, 2.1, 2.9, 4.2 }); + + chart.getAxisY().getScaling().setMinimum(new AxisBound(0.0)); + chart.getAxisY().getScaling().setMaximum(new AxisBound(6.0)); + + doc.save(getArtifactsDir() + "WorkingWithCharts.BoundsOfAxis.docx"); + //ExEnd:BoundsOfAxis + } + + @Test + public void intervalUnitBetweenLabelsOnAxis() throws Exception + { + //ExStart:IntervalUnitBetweenLabelsOnAxis + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + + Chart chart = shape.getChart(); + + chart.getSeries().clear(); + + chart.getSeries().add("Aspose Series 1", + new String[] { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }, + new double[] { 1.2, 0.3, 2.1, 2.9, 4.2 }); + + chart.getAxisX().getTickLabels().setSpacing(2); + + doc.save(getArtifactsDir() + "WorkingWithCharts.IntervalUnitBetweenLabelsOnAxis.docx"); + //ExEnd:IntervalUnitBetweenLabelsOnAxis + } + + @Test + public void hideChartAxis() throws Exception + { + //ExStart:HideChartAxis + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + + Chart chart = shape.getChart(); + + chart.getSeries().clear(); + + chart.getSeries().add("Aspose Series 1", + new String[] { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }, + new double[] { 1.2, 0.3, 2.1, 2.9, 4.2 }); + + chart.getAxisY().setHidden(true); + + doc.save(getArtifactsDir() + "WorkingWithCharts.HideChartAxis.docx"); + //ExEnd:HideChartAxis + } + + @Test + public void tickMultiLineLabelAlignment() throws Exception + { + //ExStart:TickMultiLineLabelAlignment + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.SCATTER, 450.0, 250.0); + + ChartAxis axis = shape.getChart().getAxisX(); + // This property has effect only for multi-line labels. + axis.getTickLabels().setAlignment(ParagraphAlignment.RIGHT); + + doc.save(getArtifactsDir() + "WorkingWithCharts.TickMultiLineLabelAlignment.docx"); + //ExEnd:TickMultiLineLabelAlignment + } + + @Test + public void chartDataLabel() throws Exception + { + //ExStart:WorkWithChartDataLabel + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.BAR, 432.0, 252.0); + + Chart chart = shape.getChart(); + ChartSeries series0 = shape.getChart().getSeries().get(0); + + ChartDataLabelCollection labels = series0.getDataLabels(); + labels.setShowLegendKey(true); + // By default, when you add data labels to the data points in a pie chart, leader lines are displayed for data labels that are + // positioned far outside the end of data points. Leader lines create a visual connection between a data label and its + // corresponding data point. + labels.setShowLeaderLines(true); + labels.setShowCategoryName(false); + labels.setShowPercentage(false); + labels.setShowSeriesName(true); + labels.setShowValue(true); + labels.setSeparator("/"); + labels.setShowValue(true); + + doc.save(getArtifactsDir() + "WorkingWithCharts.ChartDataLabel.docx"); + //ExEnd:WorkWithChartDataLabel + } + + @Test + public void defaultOptionsForDataLabels() throws Exception + { + //ExStart:DefaultOptionsForDataLabels + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.PIE, 432.0, 252.0); + + Chart chart = shape.getChart(); + + chart.getSeries().clear(); + + ChartSeries series = chart.getSeries().add("Aspose Series 1", + new String[] { "Category 1", "Category 2", "Category 3" }, + new double[] { 2.7, 3.2, 0.8 }); + + ChartDataLabelCollection labels = series.getDataLabels(); + labels.setShowPercentage(true); + labels.setShowValue(true); + labels.setShowLeaderLines(false); + labels.setSeparator(" - "); + + doc.save(getArtifactsDir() + "WorkingWithCharts.DefaultOptionsForDataLabels.docx"); + //ExEnd:DefaultOptionsForDataLabels + } + + @Test + public void singleChartDataPoint() throws Exception + { + //ExStart:WorkWithSingleChartDataPoint + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.LINE, 432.0, 252.0); + + Chart chart = shape.getChart(); + ChartSeries series0 = chart.getSeries().get(0); + ChartSeries series1 = chart.getSeries().get(1); + + ChartDataPointCollection dataPointCollection = series0.getDataPoints(); + ChartDataPoint dataPoint00 = dataPointCollection.get(0); + ChartDataPoint dataPoint01 = dataPointCollection.get(1); + + dataPoint00.setExplosion(50); + dataPoint00.getMarker().setSymbol(MarkerSymbol.CIRCLE); + dataPoint00.getMarker().setSize(15); + + dataPoint01.getMarker().setSymbol(MarkerSymbol.DIAMOND); + dataPoint01.getMarker().setSize(20); + + ChartDataPoint dataPoint12 = series1.getDataPoints().get(2); + dataPoint12.setInvertIfNegative(true); + dataPoint12.getMarker().setSymbol(MarkerSymbol.STAR); + dataPoint12.getMarker().setSize(20); + + doc.save(getArtifactsDir() + "WorkingWithCharts.SingleChartDataPoint.docx"); + //ExEnd:WorkWithSingleChartDataPoint + } + + @Test + public void singleChartSeries() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.LINE, 432.0, 252.0); + + Chart chart = shape.getChart(); + + //ExStart:WorkWithSingleChartSeries + //GistId:23d39c0b874655d7e7354f1ecc122e39 + ChartSeries series0 = chart.getSeries().get(0); + ChartSeries series1 = chart.getSeries().get(1); + + series0.setName("Chart Series Name 1"); + series1.setName("Chart Series Name 2"); + + // You can also specify whether the line connecting the points on the chart shall be smoothed using Catmull-Rom splines. + series0.setSmooth(true); + series1.setSmooth(true); + //ExEnd:WorkWithSingleChartSeries + + //ExStart:ChartDataPoint + //GistId:23d39c0b874655d7e7354f1ecc122e39 + // Specifies whether by default the parent element shall inverts its colors if the value is negative. + series0.setInvertIfNegative(true); + + series0.getMarker().setSymbol(MarkerSymbol.CIRCLE); + series0.getMarker().setSize(15); + + series1.getMarker().setSymbol(MarkerSymbol.STAR); + series1.getMarker().setSize(10); + //ExEnd:ChartDataPoint + + doc.save(getArtifactsDir() + "WorkingWithCharts.SingleChartSeries.docx"); + } + + @Test + public void fillFormatting() throws Exception + { + //ExStart:FillFormatting + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.COLUMN, 432.0, 252.0); + + Chart chart = shape.getChart(); + ChartSeriesCollection seriesColl = chart.getSeries(); + + // Delete default generated series. + seriesColl.clear(); + + // Create category names array. + String[] categories = new String[] { "AW Category 1", "AW Category 2" }; + + // Adding new series. Value and category arrays must be the same size. + ChartSeries series1 = seriesColl.add("AW Series 1", categories, new double[] { 1.0, 2.0 }); + ChartSeries series2 = seriesColl.add("AW Series 2", categories, new double[] { 3.0, 4.0 }); + ChartSeries series3 = seriesColl.add("AW Series 3", categories, new double[] { 5.0, 6.0 }); + + // Set series color. + series1.getFormat().getFill().setForeColor(Color.RED); + series2.getFormat().getFill().setForeColor(Color.YELLOW); + series3.getFormat().getFill().setForeColor(Color.BLUE); + + doc.save(getArtifactsDir() + "WorkingWithCharts.FillFormatting.docx"); + //ExEnd:FillFormatting + } + + @Test + public void strokeFormatting() throws Exception + { + //ExStart:StrokeFormatting + //GistId:23d39c0b874655d7e7354f1ecc122e39 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertChart(ChartType.LINE, 432.0, 252.0); + + Chart chart = shape.getChart(); + ChartSeriesCollection seriesColl = chart.getSeries(); + + // Delete default generated series. + seriesColl.clear(); + + // Adding new series. + ChartSeries series1 = seriesColl.add("AW Series 1", new double[] { 0.7, 1.8, 2.6 }, + new double[] { 2.7, 3.2, 0.8 }); + ChartSeries series2 = seriesColl.add("AW Series 2", new double[] { 0.5, 1.5, 2.5 }, + new double[] { 3.0, 1.0, 2.0 }); + + // Set series color. + series1.getFormat().getStroke().setForeColor(Color.RED); + series1.getFormat().getStroke().setWeight(5.0); + series2.getFormat().getStroke().setForeColor(msColor.getLightGreen()); + series2.getFormat().getStroke().setWeight(5.0); + + doc.save(getArtifactsDir() + "WorkingWithCharts.StrokeFormatting.docx"); + //ExEnd:StrokeFormatting + } +} + diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_graphic_elements/WorkingWithImages.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_graphic_elements/WorkingWithImages.java new file mode 100644 index 00000000..287df5c6 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_graphic_elements/WorkingWithImages.java @@ -0,0 +1,373 @@ +package DocsExamples.Programming_with_Documents.Working_with_Graphic_Elements; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.LayoutCollector; +import java.util.Iterator; +import com.aspose.words.Paragraph; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.RelativeHorizontalPosition; +import com.aspose.words.RelativeVerticalPosition; +import com.aspose.words.WrapType; +import com.aspose.words.Shape; +import com.aspose.words.ShapeType; +import com.aspose.words.HeaderFooterType; +import com.aspose.words.Section; +import com.aspose.words.SectionStart; +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import com.aspose.words.TabStop; +import com.aspose.words.TabAlignment; +import com.aspose.words.TabLeader; +import com.aspose.words.ControlChar; +import com.aspose.ms.System.msConsole; +import com.aspose.words.NodeType; +import com.aspose.words.ConvertUtil; +import com.aspose.ms.System.Drawing.msSizeF; +import com.aspose.ms.System.Diagnostics.Debug; +import com.aspose.words.ImageSaveOptions; +import com.aspose.words.SaveFormat; +import com.aspose.words.ImageData; +import com.aspose.words.ImageType; +import com.aspose.words.ImageSize; +import java.awt.Graphics2D; +import com.aspose.ms.System.Drawing.Drawing2D.InterpolationMode; +import com.aspose.ms.System.IO.MemoryStream; +import com.aspose.ms.System.Guid; + + +public class WorkingWithImages extends DocsExamplesBase +{ + @Test + public void addImageToEachPage() throws Exception + { + Document doc = new Document(getMyDir() + "Document.docx"); + + // Create and attach collector before the document before page layout is built. + LayoutCollector layoutCollector = new LayoutCollector(doc); + + // Images in a document are added to paragraphs to add an image to every page we need + // to find at any paragraph belonging to each page. + Iterator enumerator = doc.selectNodes("// Body/Paragraph").iterator(); + + for (int page = 1; page <= doc.getPageCount(); page++) + { + while (enumerator.hasNext()) + { + // Check if the current paragraph belongs to the target page. + Paragraph paragraph = (Paragraph) enumerator.next(); + if (layoutCollector.getStartPageIndex(paragraph) == page) + { + addImageToPage(paragraph, page, getImagesDir()); + break; + } + } + } + + // If we need to save the document as a PDF or image, call UpdatePageLayout() method. + doc.updatePageLayout(); + + doc.save(getArtifactsDir() + "WorkingWithImages.AddImageToEachPage.docx"); + } + + /// + /// Adds an image to a page using the supplied paragraph. + /// + /// The paragraph to an an image to. + /// The page number the paragraph appears on. + public void addImageToPage(Paragraph para, int page, String imagesDir) throws Exception + { + Document doc = (Document) para.getDocument(); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.moveTo(para); + + // Insert a logo to the top left of the page to place it in front of all other text. + builder.insertImage(getImagesDir() + "Transparent background logo.png", RelativeHorizontalPosition.PAGE, 60.0, + RelativeVerticalPosition.PAGE, 60.0, -1, -1, WrapType.NONE); + + // Insert a textbox next to the image which contains some text consisting of the page number. + Shape textBox = new Shape(doc, ShapeType.TEXT_BOX); + + // We want a floating shape relative to the page. + textBox.setWrapType(WrapType.NONE); + textBox.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE); + textBox.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE); + + textBox.setHeight(30.0); + textBox.setWidth(200.0); + textBox.setLeft(150.0); + textBox.setTop(80.0); + + textBox.appendChild(new Paragraph(doc)); + builder.insertNode(textBox); + builder.moveTo(textBox.getFirstChild()); + builder.writeln("This is a custom note for page " + page); + } + + @Test + public void insertBarcodeImage() throws Exception + { + //ExStart:InsertBarcodeImage + //GistId:6f849e51240635a6322ab0460938c922 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // The number of pages the document should have + final int NUM_PAGES = 4; + // The document starts with one section, insert the barcode into this existing section + insertBarcodeIntoFooter(builder, doc.getFirstSection(), HeaderFooterType.FOOTER_PRIMARY); + + for (int i = 1; i < NUM_PAGES; i++) + { + // Clone the first section and add it into the end of the document + Section cloneSection = (Section) doc.getFirstSection().deepClone(false); + cloneSection.getPageSetup().setSectionStart(SectionStart.NEW_PAGE); + doc.appendChild(cloneSection); + + // Insert the barcode and other information into the footer of the section + insertBarcodeIntoFooter(builder, cloneSection, HeaderFooterType.FOOTER_PRIMARY); + } + + // Save the document as a PDF to disk + // You can also save this directly to a stream + doc.save(getArtifactsDir() + "WorkingWithImages.InsertBarcodeImage.docx"); + //ExEnd:InsertBarcodeImage + } + + //ExStart:InsertBarcodeIntoFooter + //GistId:6f849e51240635a6322ab0460938c922 + private void insertBarcodeIntoFooter(DocumentBuilder builder, Section section, + /*HeaderFooterType*/int footerType) throws Exception + { + // Move to the footer type in the specific section. + builder.moveToSection(section.getDocument().indexOf(section)); + builder.moveToHeaderFooter(footerType); + + // Insert the barcode, then move to the next line and insert the ID along with the page number. + // Use pageId if you need to insert a different barcode on each page. 0 = First page, 1 = Second page etc. + builder.insertImage(ImageIO.read(getImagesDir() + "Barcode.png")); + builder.writeln(); + builder.write("1234567890"); + builder.insertField("PAGE"); + + // Create a right-aligned tab at the right margin. + double tabPos = section.getPageSetup().getPageWidth() - section.getPageSetup().getRightMargin() - section.getPageSetup().getLeftMargin(); + builder.getCurrentParagraph().getParagraphFormat().getTabStops().add(new TabStop(tabPos, TabAlignment.RIGHT, + TabLeader.NONE)); + + // Move to the right-hand side of the page and insert the page and page total. + builder.write(ControlChar.TAB); + builder.insertField("PAGE"); + builder.write(" of "); + builder.insertField("NUMPAGES"); + } + //ExEnd:InsertBarcodeIntoFooter + + @Test + public void compressImages() throws Exception + { + Document doc = new Document(getMyDir() + "Images.docx"); + + // 220ppi Print - said to be excellent on most printers and screens. + // 150ppi Screen - said to be good for web pages and projectors. + // 96ppi Email - said to be good for minimal document size and sharing. + final int DESIRED_PPI = 150; + + // In .NET this seems to be a good compression/quality setting. + final int JPEG_QUALITY = 90; + + // Resample images to the desired PPI and save. + int count = Resampler.resample(doc, DESIRED_PPI, JPEG_QUALITY); + + System.out.println("Resampled {0} images.",count); + + if (count != 1) + System.out.println("We expected to have only 1 image resampled in this test document!"); + + doc.save(getArtifactsDir() + "WorkingWithImages.CompressImages.docx"); + + // Verify that the first image was compressed by checking the new PPI. + doc = new Document(getArtifactsDir() + "WorkingWithImages.CompressImages.docx"); + + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + double imagePpi = shape.getImageData().getImageSize().getWidthPixels() / ConvertUtil.pointToInch(msSizeF.getWidth(shape.getSizeInPointsInternal())); + + Debug.assert(imagePpi < 150, "Image was not resampled successfully."); + } + + @Test + public void cropImages() throws Exception + { + //ExStart:CropImages + //GistId:6f849e51240635a6322ab0460938c922 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + BufferedImage img = ImageIO.read(getImagesDir() + "Logo.jpg"); + + int effectiveWidth = img.getWidth() - 570; + int effectiveHeight = img.getHeight() - 571; + + Shape croppedImage = builder.insertImage(img, + ConvertUtil.pixelToPoint(img.getWidth() - effectiveWidth), + ConvertUtil.pixelToPoint(img.getHeight() - effectiveHeight)); + + double widthRatio = croppedImage.getWidth() / ConvertUtil.pixelToPoint(img.getWidth()); + double heightRatio = croppedImage.getHeight() / ConvertUtil.pixelToPoint(img.getHeight()); + + if (widthRatio < 1) + croppedImage.getImageData().setCropRight(1.0 - widthRatio); + + if (heightRatio < 1) + croppedImage.getImageData().setCropBottom(1.0 - heightRatio); + + float leftToWidth = (float)124f / img.getWidth(); + float topToHeight = (float)90f / img.getHeight(); + + croppedImage.getImageData().setCropLeft(leftToWidth); + croppedImage.getImageData().setCropRight(croppedImage.getImageData().getCropRight() - leftToWidth); + + croppedImage.getImageData().setCropTop(topToHeight); + croppedImage.getImageData().setCropBottom(croppedImage.getImageData().getCropBottom() - topToHeight); + + croppedImage.getShapeRenderer().save(getArtifactsDir() + "WorkingWithImages.CropImages.jpg", new ImageSaveOptions(SaveFormat.JPEG)); + //ExEnd:CropImages + } +} + +public class Resampler +{ + /// + /// Resamples all images in the document that are greater than the specified PPI (pixels per inch) to the specified PPI + /// and converts them to JPEG with the specified quality setting. + /// + /// The document to process. + /// Desired pixels per inch. 220 high quality. 150 screen quality. 96 email quality. + /// 0 - 100% JPEG quality. + /// + public static int resample(Document doc, int desiredPpi, int jpegQuality) throws Exception + { + int count = 0; + + for (Shape shape : (Iterable) doc.getChildNodes(NodeType.SHAPE, true)) + { + // It is important to use this method to get the picture shape size in points correctly, + // even if it is inside a group shape. + /*SizeF*/long shapeSizeInPoints = shape.getSizeInPointsInternal(); + + if (resampleCore(shape.getImageData(), shapeSizeInPoints, desiredPpi, jpegQuality)) + count++; + } + + return count; + } + + /// + /// Resamples one VML or DrawingML image. + /// + private static boolean resampleCore(ImageData imageData, /*SizeF*/long shapeSizeInPoints, int ppi, int jpegQuality) throws Exception + { + // The are several shape types that can have an image (picture, ole object, ole control), let's skip other shapes. + if (imageData == null) + return false; + + // An image can be stored in shape or linked somewhere else, let's skip images that do not store bytes in shape. + byte[] originalBytes = imageData.getImageBytes(); + if (originalBytes == null) + return false; + + // Ignore metafiles, they are vector drawings, and we don't want to resample them. + /*ImageType*/int imageType = imageData.getImageType(); + if (imageType == ImageType.WMF || imageType == ImageType.EMF) + return false; + + try + { + double shapeWidthInches = ConvertUtil.pointToInch(msSizeF.getWidth(shapeSizeInPoints)); + double shapeHeightInches = ConvertUtil.pointToInch(msSizeF.getHeight(shapeSizeInPoints)); + + // Calculate the current PPI of the image. + ImageSize imageSize = imageData.getImageSize(); + double currentPpiX = imageSize.getWidthPixels() / shapeWidthInches; + double currentPpiY = imageSize.getHeightPixels() / shapeHeightInches; + + msConsole.write("Image PpiX:{0}, PpiY:{1}. ", (int) currentPpiX, (int) currentPpiY); + + // Let's resample only if the current PPI is higher than the requested PPI (e.g., we have extra data we can get rid of). + if (currentPpiX <= ppi || currentPpiY <= ppi) + { + System.out.println("Skipping."); + return false; + } + + BufferedImage srcImage = imageData.toImage(); + try /*JAVA: was using*/ + { + // Create a new image of such size that it will hold only the pixels required by the desired PPI. + int dstWidthPixels = (int) (shapeWidthInches * ppi); + int dstHeightPixels = (int) (shapeHeightInches * ppi); + BufferedImage dstImage = new BufferedImage(dstWidthPixels, dstHeightPixels); + try /*JAVA: was using*/ + { + // Drawing the source image to the new image scales it to the new size. + Graphics2D gr = Graphics2D.FromImage(dstImage); + try /*JAVA: was using*/ + { + gr.InterpolationMode = InterpolationMode.HIGH_QUALITY_BICUBIC; + gr.DrawImage(srcImage, 0, 0, dstWidthPixels, dstHeightPixels); + } + finally { if (gr != null) gr.close(); } + + // Create JPEG encoder parameters with the quality setting. + ImageCodecInfo encoderInfo = getEncoderInfo(ImageFormat.Jpeg); + EncoderParameters encoderParams = new EncoderParameters(); + encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, jpegQuality); + + // Save the image as JPEG to a memory stream. + MemoryStream dstStream = new MemoryStream(); + dstImage.Save(dstStream, encoderInfo, encoderParams); + + // If the image saved as JPEG is smaller than the original, store it in shape. + System.out.println("Original size {0}, new size {1}.",originalBytes.length,dstStream.getLength()); + if (dstStream.getLength() < originalBytes.length) + { + dstStream.setPosition(0); + imageData.setImage(dstStream); + return true; + } + } + finally { if (dstImage != null) dstImage.close(); } + } + finally { if (srcImage != null) srcImage.flush(); } + } + catch (Exception e) + { + // Catch an exception, log an error, and continue to process one of the images for whatever reason. + System.out.println("Error processing an image, ignoring. " + e.getMessage()); + } + + return false; + } + + /// + /// Gets the codec info for the specified image format. + /// Throws if cannot find. + /// + private static ImageCodecInfo getEncoderInfo(ImageFormat format) + { + ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders(); + + for (ImageCodecInfo codecInfo : encoders) + { + if (Guid.equals(codecInfo.FormatID, format.Guid)) + return codecInfo; + } + + throw new Exception("Cannot find a codec."); + } +} + diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_graphic_elements/WorkingWithOfficeMath.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_graphic_elements/WorkingWithOfficeMath.java new file mode 100644 index 00000000..bca3d5df --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_graphic_elements/WorkingWithOfficeMath.java @@ -0,0 +1,31 @@ +package DocsExamples.Programming_with_Documents.Working_with_Graphic_Elements; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.OfficeMath; +import com.aspose.words.NodeType; +import com.aspose.words.OfficeMathDisplayType; +import com.aspose.words.OfficeMathJustification; + + +class WorkingWithOfficeMath extends DocsExamplesBase +{ + @Test + public void mathEquations() throws Exception + { + //ExStart:MathEquations + //GistId:e19d5874b376b07466fd7a397d554648 + Document doc = new Document(getMyDir() + "Office math.docx"); + OfficeMath officeMath = (OfficeMath) doc.getChild(NodeType.OFFICE_MATH, 0, true); + + // OfficeMath display type represents whether an equation is displayed inline with the text or displayed on its line. + officeMath.setDisplayType(OfficeMathDisplayType.DISPLAY); + officeMath.setJustification(OfficeMathJustification.LEFT); + + doc.save(getArtifactsDir() + "WorkingWithOfficeMath.MathEquations.docx"); + //ExEnd:MathEquations + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_graphic_elements/WorkingWithShapes.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_graphic_elements/WorkingWithShapes.java new file mode 100644 index 00000000..3576de61 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_graphic_elements/WorkingWithShapes.java @@ -0,0 +1,234 @@ +package DocsExamples.Programming_with_Documents.Working_with_Graphic_Elements; + +// ********* THIS FILE IS AUTO PORTED ********* + +import com.aspose.ms.System.ms; +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.GroupShape; +import com.aspose.words.Shape; +import com.aspose.words.ShapeType; +import com.aspose.ms.System.Drawing.msSize; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.RelativeHorizontalPosition; +import com.aspose.words.RelativeVerticalPosition; +import com.aspose.words.WrapType; +import com.aspose.words.OoxmlSaveOptions; +import com.aspose.words.SaveFormat; +import com.aspose.words.OoxmlCompliance; +import com.aspose.words.HeightRule; +import com.aspose.words.HorizontalAlignment; +import com.aspose.words.VerticalAlignment; +import com.aspose.ms.System.Drawing.msColor; +import java.awt.Color; +import com.aspose.words.Run; +import com.aspose.words.NodeType; +import com.aspose.words.MsWordVersion; +import com.aspose.ms.System.msConsole; +import com.aspose.words.TextBoxAnchor; + + +class WorkingWithShapes extends DocsExamplesBase +{ + @Test + public void addGroupShape() throws Exception + { + //ExStart:AddGroupShape + //GistId:072edc4bbb0dd0eebf1f61f610bd8d36 + Document doc = new Document(); + doc.ensureMinimum(); + + GroupShape groupShape = new GroupShape(doc); + Shape accentBorderShape = new Shape(doc, ShapeType.ACCENT_BORDER_CALLOUT_1); { accentBorderShape.setWidth(100.0); accentBorderShape.setHeight(100.0); } + groupShape.appendChild(accentBorderShape); + + Shape actionButtonShape = new Shape(doc, ShapeType.ACTION_BUTTON_BEGINNING); + { + actionButtonShape.setLeft(100.0); actionButtonShape.setWidth(100.0); actionButtonShape.setHeight(200.0); + } + groupShape.appendChild(actionButtonShape); + + groupShape.setWidth(200.0); + groupShape.setHeight(200.0); + groupShape.setCoordSizeInternal(msSize.ctor(200, 200)); + + DocumentBuilder builder = new DocumentBuilder(doc); + builder.insertNode(groupShape); + + doc.save(getArtifactsDir() + "WorkingWithShapes.AddGroupShape.docx"); + //ExEnd:AddGroupShape + } + + @Test + public void insertShape() throws Exception + { + //ExStart:InsertShape + //GistId:ad463bf5f128fe6e6c1485df3c046a4c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertShape(ShapeType.TEXT_BOX, RelativeHorizontalPosition.PAGE, 100.0, + RelativeVerticalPosition.PAGE, 100.0, 50.0, 50.0, WrapType.NONE); + shape.setRotation(30.0); + + builder.writeln(); + + shape = builder.insertShape(ShapeType.TEXT_BOX, 50.0, 50.0); + shape.setRotation(30.0); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(SaveFormat.DOCX); + { + saveOptions.setCompliance(OoxmlCompliance.ISO_29500_2008_TRANSITIONAL); + } + + doc.save(getArtifactsDir() + "WorkingWithShapes.InsertShape.docx", saveOptions); + //ExEnd:InsertShape + } + + @Test + public void aspectRatioLocked() throws Exception + { + //ExStart:AspectRatioLocked + //GistId:ad463bf5f128fe6e6c1485df3c046a4c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertImage(getImagesDir() + "Transparent background logo.png"); + shape.setAspectRatioLocked(false); + + doc.save(getArtifactsDir() + "WorkingWithShapes.AspectRatioLocked.docx"); + //ExEnd:AspectRatioLocked + } + + @Test + public void layoutInCell() throws Exception + { + //ExStart:LayoutInCell + //GistId:ad463bf5f128fe6e6c1485df3c046a4c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startTable(); + builder.getRowFormat().setHeight(100.0); + builder.getRowFormat().setHeightRule(HeightRule.EXACTLY); + + for (int i = 0; i < 31; i++) + { + if (i != 0 && i % 7 == 0) builder.endRow(); + builder.insertCell(); + builder.write("Cell contents"); + } + + builder.endTable(); + + Shape watermark = new Shape(doc, ShapeType.TEXT_PLAIN_TEXT); + { + watermark.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE); + watermark.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE); + watermark.isLayoutInCell(true); // Display the shape outside of the table cell if it will be placed into a cell. + watermark.setWidth(300.0); + watermark.setHeight(70.0); + watermark.setHorizontalAlignment(HorizontalAlignment.CENTER); + watermark.setVerticalAlignment(VerticalAlignment.CENTER); + watermark.setRotation(-40); + } + + watermark.setFillColor(msColor.getGray()); + watermark.setStrokeColor(msColor.getGray()); + + watermark.getTextPath().setText("watermarkText"); + watermark.getTextPath().setFontFamily("Arial"); + + watermark.setName("WaterMark_{Guid.NewGuid()}"); + watermark.setWrapType(WrapType.NONE); + + Run run = ms.as(doc.getChildNodes(NodeType.RUN, true).get(doc.getChildNodes(NodeType.RUN, true).getCount() - 1), Run.class); + + builder.moveTo(run); + builder.insertNode(watermark); + doc.getCompatibilityOptions().optimizeFor(MsWordVersion.WORD_2010); + + doc.save(getArtifactsDir() + "WorkingWithShapes.LayoutInCell.docx"); + //ExEnd:LayoutInCell + } + + @Test + public void addCornersSnipped() throws Exception + { + //ExStart:AddCornersSnipped + //GistId:ad463bf5f128fe6e6c1485df3c046a4c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertShape(ShapeType.TOP_CORNERS_SNIPPED, 50.0, 50.0); + + OoxmlSaveOptions saveOptions = new OoxmlSaveOptions(SaveFormat.DOCX); + { + saveOptions.setCompliance(OoxmlCompliance.ISO_29500_2008_TRANSITIONAL); + } + + doc.save(getArtifactsDir() + "WorkingWithShapes.AddCornersSnipped.docx", saveOptions); + //ExEnd:AddCornersSnipped + } + + @Test + public void getActualShapeBoundsPoints() throws Exception + { + //ExStart:GetActualShapeBoundsPoints + //GistId:ad463bf5f128fe6e6c1485df3c046a4c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape shape = builder.insertImage(getImagesDir() + "Transparent background logo.png"); + shape.setAspectRatioLocked(false); + + msConsole.write("\nGets the actual bounds of the shape in points: "); + System.out.println(shape.getShapeRenderer().getBoundsInPointsInternal()); + //ExEnd:GetActualShapeBoundsPoints + } + + @Test + public void verticalAnchor() throws Exception + { + //ExStart:VerticalAnchor + //GistId:ad463bf5f128fe6e6c1485df3c046a4c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Shape textBox = builder.insertShape(ShapeType.TEXT_BOX, 200.0, 200.0); + textBox.getTextBox().setVerticalAnchor(TextBoxAnchor.BOTTOM); + + builder.moveTo(textBox.getFirstParagraph()); + builder.write("Textbox contents"); + + doc.save(getArtifactsDir() + "WorkingWithShapes.VerticalAnchor.docx"); + //ExEnd:VerticalAnchor + } + + @Test + public void detectSmartArtShape() throws Exception + { + //ExStart:DetectSmartArtShape + //GistId:ad463bf5f128fe6e6c1485df3c046a4c + Document doc = new Document(getMyDir() + "SmartArt.docx"); + + int count = doc.getChildNodes(NodeType.SHAPE, true).Cast().Count(shape => shape.HasSmartArt); + + System.out.println("The document has {0} shapes with SmartArt.",count); + //ExEnd:DetectSmartArtShape + } + + @Test + public void updateSmartArtDrawing() throws Exception + { + Document doc = new Document(getMyDir() + "SmartArt.docx"); + + //ExStart:UpdateSmartArtDrawing + //GistId:683cdbe52b97598d9d4ee4695b4f83c9 + for (Shape shape : (Iterable) doc.getChildNodes(NodeType.SHAPE, true)) + if (shape.hasSmartArt()) + shape.updateSmartArtDrawing(); + //ExEnd:UpdateSmartArtDrawing + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_graphic_elements/WorkingWithWatermark.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_graphic_elements/WorkingWithWatermark.java new file mode 100644 index 00000000..c3b55350 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_graphic_elements/WorkingWithWatermark.java @@ -0,0 +1,199 @@ +package DocsExamples.Programming_with_Documents.Working_with_Graphic_Elements; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.TextWatermarkOptions; +import java.awt.Color; +import com.aspose.words.WatermarkLayout; +import com.aspose.words.ImageWatermarkOptions; +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import com.aspose.words.WatermarkType; +import com.aspose.words.Shape; +import com.aspose.words.ShapeType; +import com.aspose.ms.System.Drawing.msColor; +import com.aspose.words.RelativeHorizontalPosition; +import com.aspose.words.RelativeVerticalPosition; +import com.aspose.words.WrapType; +import com.aspose.words.VerticalAlignment; +import com.aspose.words.HorizontalAlignment; +import com.aspose.words.Paragraph; +import com.aspose.words.Section; +import com.aspose.words.HeaderFooterType; +import com.aspose.words.HeaderFooter; +import com.aspose.words.NodeType; + + +class WorkWithWatermark extends DocsExamplesBase +{ + @Test + public void addTextWatermark() throws Exception + { + //ExStart:AddTextWatermark + //GistId:1f690a31c188a851d80d7aed4ff7e44c + Document doc = new Document(getMyDir() + "Document.docx"); + + TextWatermarkOptions options = new TextWatermarkOptions(); + { + options.setFontFamily("Arial"); + options.setFontSize(36f); + options.setColor(Color.BLACK); + options.setLayout(WatermarkLayout.HORIZONTAL); + options.isSemitrasparent(false); + } + + doc.getWatermark().setText("Test", options); + + doc.save(getArtifactsDir() + "WorkWithWatermark.AddTextWatermark.docx"); + //ExEnd:AddTextWatermark + } + + @Test + public void addImageWatermark() throws Exception + { + //ExStart:AddImageWatermark + //GistId:1f690a31c188a851d80d7aed4ff7e44c + Document doc = new Document(getMyDir() + "Document.docx"); + + ImageWatermarkOptions options = new ImageWatermarkOptions(); + { + options.setScale(5.0); + options.isWashout(false); + } + + doc.getWatermark().setImage(ImageIO.read(getImagesDir() + "Transparent background logo.png"), options); + + doc.save(getArtifactsDir() + "WorkWithWatermark.AddImageWatermark.docx"); + //ExEnd:AddImageWatermark + } + + @Test + public void removeDocumentWatermark() throws Exception + { + //ExStart:RemoveDocumentWatermark + //GistId:1f690a31c188a851d80d7aed4ff7e44c + Document doc = new Document(); + + // Add a plain text watermark. + doc.getWatermark().setText("Aspose Watermark"); + + // If we wish to edit the text formatting using it as a watermark, + // we can do so by passing a TextWatermarkOptions object when creating the watermark. + TextWatermarkOptions textWatermarkOptions = new TextWatermarkOptions(); + textWatermarkOptions.setFontFamily("Arial"); + textWatermarkOptions.setFontSize(36f); + textWatermarkOptions.setColor(Color.BLACK); + textWatermarkOptions.setLayout(WatermarkLayout.DIAGONAL); + textWatermarkOptions.isSemitrasparent(false); + + doc.getWatermark().setText("Aspose Watermark", textWatermarkOptions); + + doc.save(getArtifactsDir() + "Document.TextWatermark.docx"); + + // We can remove a watermark from a document like this. + if (doc.getWatermark().getType() == WatermarkType.TEXT) + doc.getWatermark().remove(); + + doc.save(getArtifactsDir() + "WorkWithWatermark.RemoveDocumentWatermark.docx"); + //ExEnd:RemoveDocumentWatermark + } + + //ExStart:AddDocumentWatermark + //GistId:1f690a31c188a851d80d7aed4ff7e44c + @Test + public void addAndRemoveWatermark() throws Exception + { + Document doc = new Document(getMyDir() + "Document.docx"); + + insertWatermarkText(doc, "CONFIDENTIAL"); + doc.save(getArtifactsDir() + "WorkWithWatermark.AddWatermark.docx"); + + removeWatermarkShape(doc); + doc.save(getArtifactsDir() + "WorkWithWatermark.RemoveWatermark.docx"); + } + + /// + /// Inserts a watermark into a document. + /// + /// The input document. + /// Text of the watermark. + private void insertWatermarkText(Document doc, String watermarkText) throws Exception + { + //ExStart:SetShapeName + //GistId:1f690a31c188a851d80d7aed4ff7e44c + // Create a watermark shape, this will be a WordArt shape. + Shape watermark = new Shape(doc, ShapeType.TEXT_PLAIN_TEXT); { watermark.setName("Watermark"); } + //ExEnd:SetShapeName + + watermark.getTextPath().setText(watermarkText); + watermark.getTextPath().setFontFamily("Arial"); + watermark.setWidth(500.0); + watermark.setHeight(100.0); + + // Text will be directed from the bottom-left to the top-right corner. + watermark.setRotation(-40); + + // Remove the following two lines if you need a solid black text. + watermark.setFillColor(msColor.getGray()); + watermark.setStrokeColor(msColor.getGray()); + + // Place the watermark in the page center. + watermark.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE); + watermark.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE); + watermark.setWrapType(WrapType.NONE); + watermark.setVerticalAlignment(VerticalAlignment.CENTER); + watermark.setHorizontalAlignment(HorizontalAlignment.CENTER); + + // Create a new paragraph and append the watermark to this paragraph. + Paragraph watermarkPara = new Paragraph(doc); + watermarkPara.appendChild(watermark); + + // Insert the watermark into all headers of each document section. + for (Section sect : (Iterable
          ) doc.getSections()) + { + // There could be up to three different headers in each section. + // Since we want the watermark to appear on all pages, insert it into all headers. + insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_PRIMARY); + insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_FIRST); + insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_EVEN); + } + } + + private void insertWatermarkIntoHeader(Paragraph watermarkPara, Section sect, + /*HeaderFooterType*/int headerType) + { + HeaderFooter header = sect.getHeadersFooters().getByHeaderFooterType(headerType); + + if (header == null) + { + // There is no header of the specified type in the current section, so we need to create it. + header = new HeaderFooter(sect.getDocument(), headerType); + sect.getHeadersFooters().add(header); + } + + // Insert a clone of the watermark into the header. + header.appendChild(watermarkPara.deepClone(true)); + } + //ExEnd:AddDocumentWatermark + + //ExStart:RemoveWatermarkShape + //GistId:1f690a31c188a851d80d7aed4ff7e44c + private void removeWatermarkShape(Document doc) + { + for (HeaderFooter hf : (Iterable) doc.getChildNodes(NodeType.HEADER_FOOTER, true)) + { + for (Shape shape : (Iterable) hf.getChildNodes(NodeType.SHAPE, true)) + { + if (shape.getName().contains("Watermark")) + { + shape.remove(); + } + } + } + } + //ExEnd:RemoveWatermarkShape +} + diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_tables/WorkingWithTableStylesAndFormatting.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_tables/WorkingWithTableStylesAndFormatting.java new file mode 100644 index 00000000..b8c6f636 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_tables/WorkingWithTableStylesAndFormatting.java @@ -0,0 +1,455 @@ +package DocsExamples.Programming_with_Documents.Working_with_Tables; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.ms.System.msConsole; +import com.aspose.words.Table; +import com.aspose.words.NodeType; +import com.aspose.words.TableAlignment; +import com.aspose.words.BorderType; +import com.aspose.words.LineStyle; +import com.aspose.ms.System.Drawing.msColor; +import java.awt.Color; +import com.aspose.words.TextureIndex; +import com.aspose.words.Row; +import com.aspose.words.HeightRule; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.RowFormat; +import com.aspose.words.Cell; +import com.aspose.words.TextOrientation; +import com.aspose.words.OoxmlSaveOptions; +import com.aspose.words.OoxmlCompliance; +import com.aspose.words.StyleIdentifier; +import com.aspose.words.TableStyleOptions; +import com.aspose.words.AutoFitBehavior; +import com.aspose.words.TableStyle; +import com.aspose.words.StyleType; +import com.aspose.words.CellFormat; + + +class WorkingWithTableStylesAndFormatting extends DocsExamplesBase +{ + @Test + public void distanceBetweenTableSurroundingText() throws Exception + { + //ExStart:DistanceBetweenTableSurroundingText + //GistId:8df1ad0825619cab7c80b571c6e6ba99 + Document doc = new Document(getMyDir() + "Tables.docx"); + + System.out.println("\nGet distance between table left, right, bottom, top and the surrounding text."); + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + msConsole.writeLine(table.getDistanceTop()); + msConsole.writeLine(table.getDistanceBottom()); + msConsole.writeLine(table.getDistanceRight()); + msConsole.writeLine(table.getDistanceLeft()); + //ExEnd:DistanceBetweenTableSurroundingText + } + + @Test + public void applyOutlineBorder() throws Exception + { + //ExStart:ApplyOutlineBorder + //GistId:770bf20bd617f3cb80031a74cc6c9b73 + //ExStart:InlineTablePosition + //GistId:8df1ad0825619cab7c80b571c6e6ba99 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + // Align the table to the center of the page. + table.setAlignment(TableAlignment.CENTER); + //ExEnd:InlineTablePosition + // Clear any existing borders from the table. + table.clearBorders(); + + // Set a green border around the table but not inside. + table.setBorder(BorderType.LEFT, LineStyle.SINGLE, 1.5, msColor.getGreen(), true); + table.setBorder(BorderType.RIGHT, LineStyle.SINGLE, 1.5, msColor.getGreen(), true); + table.setBorder(BorderType.TOP, LineStyle.SINGLE, 1.5, msColor.getGreen(), true); + table.setBorder(BorderType.BOTTOM, LineStyle.SINGLE, 1.5, msColor.getGreen(), true); + + // Fill the cells with a light green solid color. + table.setShading(TextureIndex.TEXTURE_SOLID, msColor.getLightGreen(), msColor.Empty); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.ApplyOutlineBorder.docx"); + //ExEnd:ApplyOutlineBorder + } + + @Test + public void buildTableWithBorders() throws Exception + { + //ExStart:BuildTableWithBorders + //GistId:770bf20bd617f3cb80031a74cc6c9b73 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + // Clear any existing borders from the table. + table.clearBorders(); + + // Set a green border around and inside the table. + table.setBorders(LineStyle.SINGLE, 1.5, msColor.getGreen()); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.BuildTableWithBorders.docx"); + //ExEnd:BuildTableWithBorders + } + + @Test + public void modifyRowFormatting() throws Exception + { + //ExStart:ModifyRowFormatting + //GistId:770bf20bd617f3cb80031a74cc6c9b73 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + // Retrieve the first row in the table. + Row firstRow = table.getFirstRow(); + firstRow.getRowFormat().getBorders().setLineStyle(LineStyle.NONE); + firstRow.getRowFormat().setHeightRule(HeightRule.AUTO); + firstRow.getRowFormat().setAllowBreakAcrossPages(true); + //ExEnd:ModifyRowFormatting + } + + @Test + public void applyRowFormatting() throws Exception + { + //ExStart:ApplyRowFormatting + //GistId:770bf20bd617f3cb80031a74cc6c9b73 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + + RowFormat rowFormat = builder.getRowFormat(); + rowFormat.setHeight(100.0); + rowFormat.setHeightRule(HeightRule.EXACTLY); + + // These formatting properties are set on the table and are applied to all rows in the table. + table.setLeftPadding(30.0); + table.setRightPadding(30.0); + table.setTopPadding(30.0); + table.setBottomPadding(30.0); + + builder.writeln("I'm a wonderful formatted row."); + + builder.endRow(); + builder.endTable(); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.ApplyRowFormatting.docx"); + //ExEnd:ApplyRowFormatting + } + + @Test + public void cellPadding() throws Exception + { + //ExStart:CellPadding + //GistId:770bf20bd617f3cb80031a74cc6c9b73 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startTable(); + builder.insertCell(); + + // Sets the amount of space (in points) to add to the left/top/right/bottom of the cell's contents. + builder.getCellFormat().setPaddings(30.0, 50.0, 30.0, 50.0); + builder.writeln("I'm a wonderful formatted cell."); + + builder.endRow(); + builder.endTable(); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.CellPadding.docx"); + //ExEnd:CellPadding + } + + /// + /// Shows how to modify formatting of a table cell. + /// + @Test + public void modifyCellFormatting() throws Exception + { + //ExStart:ModifyCellFormatting + //GistId:770bf20bd617f3cb80031a74cc6c9b73 + Document doc = new Document(getMyDir() + "Tables.docx"); + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + Cell firstCell = table.getFirstRow().getFirstCell(); + firstCell.getCellFormat().setWidth(30.0); + firstCell.getCellFormat().setOrientation(TextOrientation.DOWNWARD); + firstCell.getCellFormat().getShading().setForegroundPatternColor(msColor.getLightGreen()); + //ExEnd:ModifyCellFormatting + } + + @Test + public void formatTableAndCellWithDifferentBorders() throws Exception + { + //ExStart:FormatTableAndCellWithDifferentBorders + //GistId:770bf20bd617f3cb80031a74cc6c9b73 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + + // Set the borders for the entire table. + table.setBorders(LineStyle.SINGLE, 2.0, Color.BLACK); + + // Set the cell shading for this cell. + builder.getCellFormat().getShading().setBackgroundPatternColor(Color.RED); + builder.writeln("Cell #1"); + + builder.insertCell(); + + // Specify a different cell shading for the second cell. + builder.getCellFormat().getShading().setBackgroundPatternColor(msColor.getGreen()); + builder.writeln("Cell #2"); + + builder.endRow(); + + // Clear the cell formatting from previous operations. + builder.getCellFormat().clearFormatting(); + + builder.insertCell(); + + // Create larger borders for the first cell of this row. This will be different + // compared to the borders set for the table. + builder.getCellFormat().getBorders().getLeft().setLineWidth(4.0); + builder.getCellFormat().getBorders().getRight().setLineWidth(4.0); + builder.getCellFormat().getBorders().getTop().setLineWidth(4.0); + builder.getCellFormat().getBorders().getBottom().setLineWidth(4.0); + builder.writeln("Cell #3"); + + builder.insertCell(); + builder.getCellFormat().clearFormatting(); + builder.writeln("Cell #4"); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.FormatTableAndCellWithDifferentBorders.docx"); + //ExEnd:FormatTableAndCellWithDifferentBorders + } + + @Test + public void tableTitleAndDescription() throws Exception + { + //ExStart:TableTitleAndDescription + //GistId:458eb4fd5bd1de8b06fab4d1ef1acdc6 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + table.setTitle("Test title"); + table.setDescription("Test description"); + + OoxmlSaveOptions options = new OoxmlSaveOptions(); { options.setCompliance(OoxmlCompliance.ISO_29500_2008_STRICT); } + + doc.getCompatibilityOptions().optimizeFor(com.aspose.words.MsWordVersion.WORD_2016); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.TableTitleAndDescription.docx", options); + //ExEnd:TableTitleAndDescription + } + + @Test + public void allowCellSpacing() throws Exception + { + //ExStart:AllowCellSpacing + //GistId:770bf20bd617f3cb80031a74cc6c9b73 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + table.setAllowCellSpacing(true); + table.setCellSpacing(2.0); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.AllowCellSpacing.docx"); + //ExEnd:AllowCellSpacing + } + + @Test + public void buildTableWithStyle() throws Exception + { + //ExStart:BuildTableWithStyle + //GistId:93b92a7e6f2f4bbfd9177dd7fcecbd8c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + + // We must insert at least one row first before setting any table formatting. + builder.insertCell(); + + // Set the table style used based on the unique style identifier. + table.setStyleIdentifier(StyleIdentifier.MEDIUM_SHADING_1_ACCENT_1); + + // Apply which features should be formatted by the style. + table.setStyleOptions(TableStyleOptions.FIRST_COLUMN | TableStyleOptions.ROW_BANDS | TableStyleOptions.FIRST_ROW); + table.autoFit(AutoFitBehavior.AUTO_FIT_TO_CONTENTS); + + builder.writeln("Item"); + builder.getCellFormat().setRightPadding(40.0); + builder.insertCell(); + builder.writeln("Quantity (kg)"); + builder.endRow(); + + builder.insertCell(); + builder.writeln("Apples"); + builder.insertCell(); + builder.writeln("20"); + builder.endRow(); + + builder.insertCell(); + builder.writeln("Bananas"); + builder.insertCell(); + builder.writeln("40"); + builder.endRow(); + + builder.insertCell(); + builder.writeln("Carrots"); + builder.insertCell(); + builder.writeln("50"); + builder.endRow(); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.BuildTableWithStyle.docx"); + //ExEnd:BuildTableWithStyle + } + + @Test + public void expandFormattingOnCellsAndRowFromStyle() throws Exception + { + //ExStart:ExpandFormattingOnCellsAndRowFromStyle + //GistId:93b92a7e6f2f4bbfd9177dd7fcecbd8c + Document doc = new Document(getMyDir() + "Tables.docx"); + + // Get the first cell of the first table in the document. + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + Cell firstCell = table.getFirstRow().getFirstCell(); + + // First print the color of the cell shading. + // This should be empty as the current shading is stored in the table style. + Color cellShadingBefore = firstCell.getCellFormat().getShading().getBackgroundPatternColor(); + System.out.println("Cell shading before style expansion: " + cellShadingBefore); + + doc.expandTableStylesToDirectFormatting(); + + // Now print the cell shading after expanding table styles. + // A blue background pattern color should have been applied from the table style. + Color cellShadingAfter = firstCell.getCellFormat().getShading().getBackgroundPatternColor(); + System.out.println("Cell shading after style expansion: " + cellShadingAfter); + //ExEnd:ExpandFormattingOnCellsAndRowFromStyle + } + + @Test + public void createTableStyle() throws Exception + { + //ExStart:CreateTableStyle + //GistId:93b92a7e6f2f4bbfd9177dd7fcecbd8c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + builder.write("Name"); + builder.insertCell(); + builder.write("Value"); + builder.endRow(); + builder.insertCell(); + builder.insertCell(); + builder.endTable(); + + TableStyle tableStyle = (TableStyle) doc.getStyles().add(StyleType.TABLE, "MyTableStyle1"); + tableStyle.getBorders().setLineStyle(LineStyle.DOUBLE); + tableStyle.getBorders().setLineWidth(1.0); + tableStyle.setLeftPadding(18.0); + tableStyle.setRightPadding(18.0); + tableStyle.setTopPadding(12.0); + tableStyle.setBottomPadding(12.0); + + table.setStyle(tableStyle); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.CreateTableStyle.docx"); + //ExEnd:CreateTableStyle + } + + @Test + public void defineConditionalFormatting() throws Exception + { + //ExStart:DefineConditionalFormatting + //GistId:93b92a7e6f2f4bbfd9177dd7fcecbd8c + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + builder.write("Name"); + builder.insertCell(); + builder.write("Value"); + builder.endRow(); + builder.insertCell(); + builder.insertCell(); + builder.endTable(); + + TableStyle tableStyle = (TableStyle) doc.getStyles().add(StyleType.TABLE, "MyTableStyle1"); + tableStyle.getConditionalStyles().getFirstRow().getShading().setBackgroundPatternColor(msColor.getGreenYellow()); + tableStyle.getConditionalStyles().getFirstRow().getShading().setTexture(TextureIndex.TEXTURE_NONE); + + table.setStyle(tableStyle); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.DefineConditionalFormatting.docx"); + //ExEnd:DefineConditionalFormatting + } + + @Test + public void setTableCellFormatting() throws Exception + { + //ExStart:DocumentBuilderSetTableCellFormatting + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startTable(); + builder.insertCell(); + + CellFormat cellFormat = builder.getCellFormat(); + cellFormat.setWidth(250.0); + cellFormat.setLeftPadding(30.0); + cellFormat.setRightPadding(30.0); + cellFormat.setTopPadding(30.0); + cellFormat.setBottomPadding(30.0); + + builder.writeln("I'm a wonderful formatted cell."); + + builder.endRow(); + builder.endTable(); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.DocumentBuilderSetTableCellFormatting.docx"); + //ExEnd:DocumentBuilderSetTableCellFormatting + } + + @Test + public void setTableRowFormatting() throws Exception + { + //ExStart:DocumentBuilderSetTableRowFormatting + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + + RowFormat rowFormat = builder.getRowFormat(); + rowFormat.setHeight(100.0); + rowFormat.setHeightRule(HeightRule.EXACTLY); + + // These formatting properties are set on the table and are applied to all rows in the table. + table.setLeftPadding(30.0); + table.setRightPadding(30.0); + table.setTopPadding(30.0); + table.setBottomPadding(30.0); + + builder.writeln("I'm a wonderful formatted row."); + + builder.endRow(); + builder.endTable(); + + doc.save(getArtifactsDir() + "WorkingWithTableStylesAndFormatting.DocumentBuilderSetTableRowFormatting.docx"); + //ExEnd:DocumentBuilderSetTableRowFormatting + } +} diff --git a/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_tables/WorkingWithTables.java b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_tables/WorkingWithTables.java new file mode 100644 index 00000000..3b8db6b4 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Programming_with_documents/Working_with_tables/WorkingWithTables.java @@ -0,0 +1,1220 @@ +package DocsExamples.Programming_with_Documents.Working_with_Tables; + +// ********* THIS FILE IS AUTO PORTED ********* + +import com.aspose.ms.java.collections.StringSwitchMap; +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.Table; +import com.aspose.words.NodeType; +import com.aspose.ms.System.msConsole; +import com.aspose.words.Cell; +import com.aspose.words.Run; +import com.aspose.ms.System.Text.msStringBuilder; +import com.aspose.words.SaveFormat; +import java.util.ArrayList; +import com.aspose.words.Row; +import com.aspose.words.AutoFitBehavior; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.Orientation; +import com.aspose.words.net.System.Data.DataSet; +import com.aspose.words.net.System.Data.DataTable; +import com.aspose.words.StyleIdentifier; +import com.aspose.words.TableStyleOptions; +import com.aspose.words.ParagraphAlignment; +import com.aspose.words.net.System.Data.DataColumn; +import com.aspose.words.net.System.Data.DataRow; +import com.aspose.ms.System.DateTime; +import com.aspose.words.Paragraph; +import com.aspose.words.NodeCollection; +import com.aspose.ms.System.Drawing.msColor; +import java.awt.Color; +import com.aspose.words.HeightRule; +import com.aspose.words.CellVerticalAlignment; +import com.aspose.words.CellMerge; +import com.aspose.ms.System.Drawing.msPoint; +import com.aspose.ms.System.Drawing.Rectangle; +import com.aspose.words.DocumentVisitor; +import com.aspose.ms.System.IO.MemoryStream; +import com.aspose.words.HtmlSaveOptions; +import com.aspose.ms.System.IO.Path; +import com.aspose.XmlUtilPal; +import java.lang.Integer; +import com.aspose.words.VisitorAction; +import com.aspose.words.PreferredWidth; +import com.aspose.words.PreferredWidthType; +import com.aspose.words.TextWrapping; +import com.aspose.words.VerticalAlignment; +import com.aspose.words.RelativeHorizontalPosition; +import com.aspose.words.RelativeVerticalPosition; + + +class WorkingWithTables extends DocsExamplesBase +{ + @Test + public void removeColumn() throws Exception + { + //ExStart:RemoveColumn + //GistId:7e7e54ead8b97457543ea46fc6bae045 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 1, true); + + Column column = Column.fromIndex(table, 2); + column.remove(); + //ExEnd:RemoveColumn + } + + @Test + public void insertBlankColumn() throws Exception + { + //ExStart:InsertBlankColumn + //GistId:7e7e54ead8b97457543ea46fc6bae045 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + //ExStart:GetPlainText + Column column = Column.fromIndex(table, 0); + // Print the plain text of the column to the screen. + System.out.println(column.toTxt()); + //ExEnd:GetPlainText + + // Create a new column to the left of this column. + // This is the same as using the "Insert Column Before" command in Microsoft Word. + Column newColumn = column.insertColumnBefore(); + + for (Cell cell : newColumn.Cells !!Autoporter error: Undefined expression type ) + cell.getFirstParagraph().appendChild(new Run(doc, "Column Text " + newColumn.indexOf(cell))); + //ExEnd:InsertBlankColumn + } + + //ExStart:ColumnClass + //GistId:7e7e54ead8b97457543ea46fc6bae045 + /// + /// Represents a facade object for a column of a table in a Microsoft Word document. + /// + static class Column + { + private Column(Table table, int columnIndex) + { + mTable = !!Autoporter warning: Not supported language construction throw new IllegalArgumentException("table"); + mColumnIndex = columnIndex; + } + + /// + /// Returns a new column facade from the table and supplied zero-based index. + /// + public static Column fromIndex(Table table, int columnIndex) + { + return new Column(table, columnIndex); + } + + /// + /// Returns the cells which make up the column. + /// + public Cell[] Cells => private GetColumnCellsgetColumnCells()private ToArraytoArray(); + + /// + /// Returns the index of the given cell in the column. + /// + public int indexOf(Cell cell) + { + return GetColumnCells().IndexOf(cell); + } + + /// + /// Inserts a brand new column before this column into the table. + /// + public Column insertColumnBefore() + { + Cell[] columnCells = Cells; + + if (columnCells.length == 0) + throw new IllegalArgumentException("Column must not be empty"); + + // Create a clone of this column. + for (Cell cell : columnCells) + cell.getParentRow().insertBefore(cell.deepClone(false), cell); + + // This is the new column. + Column column = new Column(columnCells[0].getParentRow().getParentTable(), mColumnIndex); + + // We want to make sure that the cells are all valid to work with (have at least one paragraph). + for (Cell cell : column.Cells !!Autoporter error: Undefined expression type ) + cell.ensureMinimum(); + + // Increase the index which this column represents since there is now one extra column in front. + mColumnIndex++; + + return column; + } + + /// + /// Removes the column from the table. + /// + public void remove() + { + for (Cell cell : Cells !!Autoporter error: Undefined expression type ) + cell.remove(); + } + + /// + /// Returns the text of the column. + /// + public String toTxt() throws Exception + { + StringBuilder builder = new StringBuilder(); + + for (Cell cell : Cells !!Autoporter error: Undefined expression type ) + msStringBuilder.append(builder, cell.toString(SaveFormat.TEXT)); + + return builder.toString(); + } + + /// + /// Provides an up-to-date collection of cells which make up the column represented by this facade. + /// + private ArrayList getColumnCells() + { + ArrayList columnCells = new ArrayList(); + + for (Row row : (Iterable) mTable.getRows()) + { + Cell cell = row.getCells().get(mColumnIndex); + if (cell != null) + columnCells.add(cell); + } + + return columnCells; + } + + private int mColumnIndex; + private /*final*/ Table mTable; + } + //ExEnd:ColumnClass + + @Test + public void autoFitTableToContents() throws Exception + { + //ExStart:AutoFitTableToContents + //GistId:770bf20bd617f3cb80031a74cc6c9b73 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + table.autoFit(AutoFitBehavior.AUTO_FIT_TO_CONTENTS); + + doc.save(getArtifactsDir() + "WorkingWithTables.AutoFitTableToContents.docx"); + //ExEnd:AutoFitTableToContents + } + + @Test + public void autoFitTableToFixedColumnWidths() throws Exception + { + //ExStart:AutoFitTableToFixedColumnWidths + //GistId:770bf20bd617f3cb80031a74cc6c9b73 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + // Disable autofitting on this table. + table.autoFit(AutoFitBehavior.FIXED_COLUMN_WIDTHS); + + doc.save(getArtifactsDir() + "WorkingWithTables.AutoFitTableToFixedColumnWidths.docx"); + //ExEnd:AutoFitTableToFixedColumnWidths + } + + @Test + public void autoFitTableToPageWidth() throws Exception + { + //ExStart:AutoFitTableToPageWidth + //GistId:770bf20bd617f3cb80031a74cc6c9b73 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + // Autofit the first table to the page width. + table.autoFit(AutoFitBehavior.AUTO_FIT_TO_WINDOW); + + doc.save(getArtifactsDir() + "WorkingWithTables.AutoFitTableToWindow.docx"); + //ExEnd:AutoFitTableToPageWidth + } + + @Test + public void buildTableFromDataTable() throws Exception + { + //ExStart:BuildTableFromDataTable + //GistId:affb937d8f345f60e6a506e1da3db9fa + Document doc = new Document(); + // We can position where we want the table to be inserted and specify any extra formatting to the table. + DocumentBuilder builder = new DocumentBuilder(doc); + + // We want to rotate the page landscape as we expect a wide table. + doc.getFirstSection().getPageSetup().setOrientation(Orientation.LANDSCAPE); + + DataSet ds = new DataSet(); + ds.readXml(getMyDir() + "List of people.xml"); + // Retrieve the data from our data source, which is stored as a DataTable. + DataTable dataTable = ds.getTables().get(0); + + // Build a table in the document from the data contained in the DataTable. + Table table = importTableFromDataTable(builder, dataTable, true); + + // We can apply a table style as a very quick way to apply formatting to the entire table. + table.setStyleIdentifier(StyleIdentifier.MEDIUM_LIST_2_ACCENT_1); + table.setStyleOptions(TableStyleOptions.FIRST_ROW | TableStyleOptions.ROW_BANDS | TableStyleOptions.LAST_COLUMN); + + // For our table, we want to remove the heading for the image column. + table.getFirstRow().getLastCell().removeAllChildren(); + + doc.save(getArtifactsDir() + "WorkingWithTables.BuildTableFromDataTable.docx"); + //ExEnd:BuildTableFromDataTable + } + + //ExStart:ImportTableFromDataTable + //GistId:affb937d8f345f60e6a506e1da3db9fa + /// + /// Imports the content from the specified DataTable into a new Aspose.Words Table object. + /// The table is inserted at the document builder's current position and using the current builder's formatting if any is defined. + /// + public Table importTableFromDataTable(DocumentBuilder builder, DataTable dataTable, + boolean importColumnHeadings) + { + Table table = builder.startTable(); + + // Check if the columns' names from the data source are to be included in a header row. + if (importColumnHeadings) + { + // Store the original values of these properties before changing them. + boolean boldValue = builder.getFont().getBold(); + /*ParagraphAlignment*/int paragraphAlignmentValue = builder.getParagraphFormat().getAlignment(); + + // Format the heading row with the appropriate properties. + builder.getFont().setBold(true); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + + // Create a new row and insert the name of each column into the first row of the table. + for (DataColumn column : (Iterable) dataTable.getColumns()) + { + builder.insertCell(); + builder.writeln(column.getColumnName()); + } + + builder.endRow(); + + // Restore the original formatting. + builder.getFont().setBold(boldValue); + builder.getParagraphFormat().setAlignment(paragraphAlignmentValue); + } + + for (DataRow dataRow : (Iterable) dataTable.getRows()) + { + for (Object item : dataRow.getItemArray()) + { + // Insert a new cell for each object. + builder.insertCell(); + + switch (gStringSwitchMap.of(item.getClass().getName())) + { + case /*"DateTime"*/0: + // Define a custom format for dates and times. + DateTime dateTime = (DateTime) item; + builder.write(dateTime.toString("MMMM d, yyyy")); + break; + default: + // By default any other item will be inserted as text. + builder.write(item.toString()); + break; + } + } + + // After we insert all the data from the current record, we can end the table row. + builder.endRow(); + } + + // We have finished inserting all the data from the DataTable, we can end the table. + builder.endTable(); + + return table; + } + //ExEnd:ImportTableFromDataTable + + @Test + public void cloneCompleteTable() throws Exception + { + //ExStart:CloneCompleteTable + //GistId:10307fa0baf630b07d0cbdae30119bf3 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + // Clone the table and insert it into the document after the original. + Table tableClone = (Table) table.deepClone(true); + table.getParentNode().insertAfter(tableClone, table); + + // Insert an empty paragraph between the two tables, + // or else they will be combined into one upon saving this has to do with document validation. + table.getParentNode().insertAfter(new Paragraph(doc), table); + + doc.save(getArtifactsDir() + "WorkingWithTables.CloneCompleteTable.docx"); + //ExEnd:CloneCompleteTable + } + + @Test + public void cloneLastRow() throws Exception + { + //ExStart:CloneLastRow + //GistId:10307fa0baf630b07d0cbdae30119bf3 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + Row clonedRow = (Row) table.getLastRow().deepClone(true); + // Remove all content from the cloned row's cells. This makes the row ready for new content to be inserted into. + for (Cell cell : (Iterable) clonedRow.getCells()) + cell.removeAllChildren(); + + table.appendChild(clonedRow); + + doc.save(getArtifactsDir() + "WorkingWithTables.CloneLastRow.docx"); + //ExEnd:CloneLastRow + } + + @Test + public void findingIndex() throws Exception + { + Document doc = new Document(getMyDir() + "Tables.docx"); + + //ExStart:RetrieveTableIndex + //GistId:7e7e54ead8b97457543ea46fc6bae045 + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + NodeCollection allTables = doc.getChildNodes(NodeType.TABLE, true); + int tableIndex = allTables.indexOf(table); + //ExEnd:RetrieveTableIndex + System.out.println("\nTable index is " + tableIndex); + + //ExStart:RetrieveRowIndex + //GistId:7e7e54ead8b97457543ea46fc6bae045 + int rowIndex = table.indexOf(table.getLastRow()); + //ExEnd:RetrieveRowIndex + System.out.println("\nRow index is " + rowIndex); + + Row row = table.getLastRow(); + //ExStart:RetrieveCellIndex + //GistId:7e7e54ead8b97457543ea46fc6bae045 + int cellIndex = row.indexOf(row.getCells().get(4)); + //ExEnd:RetrieveCellIndex + System.out.println("\nCell index is " + cellIndex); + } + + @Test + public void insertTableDirectly() throws Exception + { + //ExStart:InsertTableDirectly + //GistId:10307fa0baf630b07d0cbdae30119bf3 + Document doc = new Document(); + + // We start by creating the table object. Note that we must pass the document object + // to the constructor of each node. This is because every node we create must belong + // to some document. + Table table = new Table(doc); + doc.getFirstSection().getBody().appendChild(table); + + // Here we could call EnsureMinimum to create the rows and cells for us. This method is used + // to ensure that the specified node is valid. In this case, a valid table should have at least one Row and one cell. + + // Instead, we will handle creating the row and table ourselves. + // This would be the best way to do this if we were creating a table inside an algorithm. + Row row = new Row(doc); + row.getRowFormat().setAllowBreakAcrossPages(true); + table.appendChild(row); + + Cell cell = new Cell(doc); + cell.getCellFormat().getShading().setBackgroundPatternColor(msColor.getLightBlue()); + cell.getCellFormat().setWidth(80.0); + cell.appendChild(new Paragraph(doc)); + cell.getFirstParagraph().appendChild(new Run(doc, "Row 1, Cell 1 Text")); + + row.appendChild(cell); + + // We would then repeat the process for the other cells and rows in the table. + // We can also speed things up by cloning existing cells and rows. + row.appendChild(cell.deepClone(false)); + row.getLastCell().appendChild(new Paragraph(doc)); + row.getLastCell().getFirstParagraph().appendChild(new Run(doc, "Row 1, Cell 2 Text")); + + // We can now apply any auto fit settings. + table.autoFit(AutoFitBehavior.FIXED_COLUMN_WIDTHS); + + doc.save(getArtifactsDir() + "WorkingWithTables.InsertTableDirectly.docx"); + //ExEnd:InsertTableDirectly + } + + @Test + public void insertTableFromHtml() throws Exception + { + //ExStart:InsertTableFromHtml + //GistId:10307fa0baf630b07d0cbdae30119bf3 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Note that AutoFitSettings does not apply to tables inserted from HTML. + builder.insertHtml("
          " + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "
          Row 1, Cell 1Row 1, Cell 2
          Row 2, Cell 2Row 2, Cell 2
          "); + + doc.save(getArtifactsDir() + "WorkingWithTables.InsertTableFromHtml.docx"); + //ExEnd:InsertTableFromHtml + } + + @Test + public void createSimpleTable() throws Exception + { + //ExStart:CreateSimpleTable + //GistId:10307fa0baf630b07d0cbdae30119bf3 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Start building the table. + builder.startTable(); + builder.insertCell(); + builder.write("Row 1, Cell 1 Content."); + + // Build the second cell. + builder.insertCell(); + builder.write("Row 1, Cell 2 Content."); + + // Call the following method to end the row and start a new row. + builder.endRow(); + + // Build the first cell of the second row. + builder.insertCell(); + builder.write("Row 2, Cell 1 Content"); + + // Build the second cell. + builder.insertCell(); + builder.write("Row 2, Cell 2 Content."); + builder.endRow(); + + // Signal that we have finished building the table. + builder.endTable(); + + doc.save(getArtifactsDir() + "WorkingWithTables.CreateSimpleTable.docx"); + //ExEnd:CreateSimpleTable + } + + @Test + public void formattedTable() throws Exception + { + //ExStart:FormattedTable + //GistId:10307fa0baf630b07d0cbdae30119bf3 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Table table = builder.startTable(); + builder.insertCell(); + + // Table wide formatting must be applied after at least one row is present in the table. + table.setLeftIndent(20.0); + + // Set height and define the height rule for the header row. + builder.getRowFormat().setHeight(40.0); + builder.getRowFormat().setHeightRule(HeightRule.AT_LEAST); + + builder.getCellFormat().getShading().setBackgroundPatternColor(new Color((198), (217), (241))); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.getFont().setSize(16.0); + builder.getFont().setName("Arial"); + builder.getFont().setBold(true); + + builder.getCellFormat().setWidth(100.0); + builder.write("Header Row,\n Cell 1"); + + // We don't need to specify this cell's width because it's inherited from the previous cell. + builder.insertCell(); + builder.write("Header Row,\n Cell 2"); + + builder.insertCell(); + builder.getCellFormat().setWidth(200.0); + builder.write("Header Row,\n Cell 3"); + builder.endRow(); + + builder.getCellFormat().getShading().setBackgroundPatternColor(Color.WHITE); + builder.getCellFormat().setWidth(100.0); + builder.getCellFormat().setVerticalAlignment(CellVerticalAlignment.CENTER); + + // Reset height and define a different height rule for table body. + builder.getRowFormat().setHeight(30.0); + builder.getRowFormat().setHeightRule(HeightRule.AUTO); + builder.insertCell(); + + // Reset font formatting. + builder.getFont().setSize(12.0); + builder.getFont().setBold(false); + + builder.write("Row 1, Cell 1 Content"); + builder.insertCell(); + builder.write("Row 1, Cell 2 Content"); + + builder.insertCell(); + builder.getCellFormat().setWidth(200.0); + builder.write("Row 1, Cell 3 Content"); + builder.endRow(); + + builder.insertCell(); + builder.getCellFormat().setWidth(100.0); + builder.write("Row 2, Cell 1 Content"); + + builder.insertCell(); + builder.write("Row 2, Cell 2 Content"); + + builder.insertCell(); + builder.getCellFormat().setWidth(200.0); + builder.write("Row 2, Cell 3 Content."); + builder.endRow(); + builder.endTable(); + + doc.save(getArtifactsDir() + "WorkingWithTables.FormattedTable.docx"); + //ExEnd:FormattedTable + } + + @Test + public void nestedTable() throws Exception + { + //ExStart:NestedTable + //GistId:10307fa0baf630b07d0cbdae30119bf3 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + Cell cell = builder.insertCell(); + builder.writeln("Outer Table Cell 1"); + + builder.insertCell(); + builder.writeln("Outer Table Cell 2"); + + // This call is important to create a nested table within the first table. + // Without this call, the cells inserted below will be appended to the outer table. + builder.endTable(); + + // Move to the first cell of the outer table. + builder.moveTo(cell.getFirstParagraph()); + + // Build the inner table. + builder.insertCell(); + builder.writeln("Inner Table Cell 1"); + builder.insertCell(); + builder.writeln("Inner Table Cell 2"); + builder.endTable(); + + doc.save(getArtifactsDir() + "WorkingWithTables.NestedTable.docx"); + //ExEnd:NestedTable + } + + @Test + public void combineRows() throws Exception + { + //ExStart:CombineRows + //GistId:b0735c64408bcb2c063f96f7c9d5af75 + Document doc = new Document(getMyDir() + "Tables.docx"); + + // The rows from the second table will be appended to the end of the first table. + Table firstTable = (Table) doc.getChild(NodeType.TABLE, 0, true); + Table secondTable = (Table) doc.getChild(NodeType.TABLE, 1, true); + + // Append all rows from the current table to the next tables + // with different cell count and widths can be joined into one table. + while (secondTable.hasChildNodes()) + firstTable.getRows().add(secondTable.getFirstRow()); + + secondTable.remove(); + + doc.save(getArtifactsDir() + "WorkingWithTables.CombineRows.docx"); + //ExEnd:CombineRows + } + + @Test + public void splitTable() throws Exception + { + //ExStart:SplitTable + //GistId:4ab56c5443822fa44f4cac1f45af32b7 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table firstTable = (Table) doc.getChild(NodeType.TABLE, 0, true); + + // We will split the table at the third row (inclusive). + Row row = firstTable.getRows().get(2); + + // Create a new container for the split table. + Table table = (Table) firstTable.deepClone(false); + + // Insert the container after the original. + firstTable.getParentNode().insertAfter(table, firstTable); + + // Add a buffer paragraph to ensure the tables stay apart. + firstTable.getParentNode().insertAfter(new Paragraph(doc), firstTable); + + Row currentRow; + do + { + currentRow = firstTable.getLastRow(); + table.prependChild(currentRow); + } while (currentRow != row); + + doc.save(getArtifactsDir() + "WorkingWithTables.SplitTable.docx"); + //ExEnd:SplitTable + } + + @Test + public void rowFormatDisableBreakAcrossPages() throws Exception + { + //ExStart:RowFormatDisableBreakAcrossPages + //GistId:7e7e54ead8b97457543ea46fc6bae045 + Document doc = new Document(getMyDir() + "Table spanning two pages.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + // Disable breaking across pages for all rows in the table. + for (Row row : (Iterable) table.getRows()) + row.getRowFormat().setAllowBreakAcrossPages(false); + + doc.save(getArtifactsDir() + "WorkingWithTables.RowFormatDisableBreakAcrossPages.docx"); + //ExEnd:RowFormatDisableBreakAcrossPages + } + + @Test + public void keepTableTogether() throws Exception + { + //ExStart:KeepTableTogether + //GistId:7e7e54ead8b97457543ea46fc6bae045 + Document doc = new Document(getMyDir() + "Table spanning two pages.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + // We need to enable KeepWithNext for every paragraph in the table to keep it from breaking across a page, + // except for the last paragraphs in the last row of the table. + for (Cell cell : (Iterable) table.getChildNodes(NodeType.CELL, true)) + { + cell.ensureMinimum(); + + for (Paragraph para : (Iterable) cell.getParagraphs()) + if (!(cell.getParentRow().isLastRow() && para.isEndOfCell())) + para.getParagraphFormat().setKeepWithNext(true); + } + + doc.save(getArtifactsDir() + "WorkingWithTables.KeepTableTogether.docx"); + //ExEnd:KeepTableTogether + } + + @Test + public void checkCellsMerged() throws Exception + { + //ExStart:CheckCellsMerged + //GistId:93de23a2f74a7f2e4971ed203874c983 + Document doc = new Document(getMyDir() + "Table with merged cells.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + for (Row row : (Iterable) table.getRows()) + { + for (Cell cell : (Iterable) row.getCells()) + { + System.out.println(printCellMergeType(cell)); + } + } + //ExEnd:CheckCellsMerged + } + + //ExStart:PrintCellMergeType + public String printCellMergeType(Cell cell) + { + boolean isHorizontallyMerged = cell.getCellFormat().getHorizontalMerge() != CellMerge.NONE; + boolean isVerticallyMerged = cell.getCellFormat().getVerticalMerge() != CellMerge.NONE; + + String cellLocation = + $"R{cell.ParentRow.ParentTable.IndexOf(cell.ParentRow) + 1}, C{cell.ParentRow.IndexOf(cell) + 1}"; + + if (isHorizontallyMerged && isVerticallyMerged) + return $"The cell at {cellLocation} is both horizontally and vertically merged"; + + if (isHorizontallyMerged) + return $"The cell at {cellLocation} is horizontally merged."; + + if (isVerticallyMerged) + return $"The cell at {cellLocation} is vertically merged"; + + return $"The cell at {cellLocation} is not merged"; + } + //ExEnd:PrintCellMergeType + + @Test + public void verticalMerge() throws Exception + { + //ExStart:VerticalMerge + //GistId:93de23a2f74a7f2e4971ed203874c983 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertCell(); + builder.getCellFormat().setVerticalMerge(CellMerge.FIRST); + builder.write("Text in merged cells."); + + builder.insertCell(); + builder.getCellFormat().setVerticalMerge(CellMerge.NONE); + builder.write("Text in one cell"); + builder.endRow(); + + builder.insertCell(); + // This cell is vertically merged to the cell above and should be empty. + builder.getCellFormat().setVerticalMerge(CellMerge.PREVIOUS); + + builder.insertCell(); + builder.getCellFormat().setVerticalMerge(CellMerge.NONE); + builder.write("Text in another cell"); + builder.endRow(); + builder.endTable(); + + doc.save(getArtifactsDir() + "WorkingWithTables.VerticalMerge.docx"); + //ExEnd:VerticalMerge + } + + @Test + public void horizontalMerge() throws Exception + { + //ExStart:HorizontalMerge + //GistId:93de23a2f74a7f2e4971ed203874c983 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.insertCell(); + builder.getCellFormat().setHorizontalMerge(CellMerge.FIRST); + builder.write("Text in merged cells."); + + builder.insertCell(); + // This cell is merged to the previous and should be empty. + builder.getCellFormat().setHorizontalMerge(CellMerge.PREVIOUS); + builder.endRow(); + + builder.insertCell(); + builder.getCellFormat().setHorizontalMerge(CellMerge.NONE); + builder.write("Text in one cell."); + + builder.insertCell(); + builder.write("Text in another cell."); + builder.endRow(); + builder.endTable(); + + doc.save(getArtifactsDir() + "WorkingWithTables.HorizontalMerge.docx"); + //ExEnd:HorizontalMerge + } + + @Test + public void mergeCellRange() throws Exception + { + //ExStart:MergeCellRange + //GistId:93de23a2f74a7f2e4971ed203874c983 + Document doc = new Document(getMyDir() + "Table with merged cells.docx"); + + Table table = doc.getFirstSection().getBody().getTables().get(0); + + // We want to merge the range of cells found inbetween these two cells. + Cell cellStartRange = table.getRows().get(0).getCells().get(0); + Cell cellEndRange = table.getRows().get(1).getCells().get(1); + + // Merge all the cells between the two specified cells into one. + mergeCells(cellStartRange, cellEndRange); + + doc.save(getArtifactsDir() + "WorkingWithTables.MergeCellRange.docx"); + //ExEnd:MergeCellRange + } + + @Test + public void printHorizontalAndVerticalMerged() throws Exception + { + //ExStart:PrintHorizontalAndVerticalMerged + //GistId:93de23a2f74a7f2e4971ed203874c983 + Document doc = new Document(getMyDir() + "Table with merged cells.docx"); + + SpanVisitor visitor = new SpanVisitor(doc); + doc.accept(visitor); + //ExEnd:PrintHorizontalAndVerticalMerged + } + + @Test + public void convertToHorizontallyMergedCells() throws Exception + { + //ExStart:ConvertToHorizontallyMergedCells + //GistId:93de23a2f74a7f2e4971ed203874c983 + Document doc = new Document(getMyDir() + "Table with merged cells.docx"); + + Table table = doc.getFirstSection().getBody().getTables().get(0); + // Now merged cells have appropriate merge flags. + table.convertToHorizontallyMergedCells(); + //ExEnd:ConvertToHorizontallyMergedCells + } + + //ExStart:MergeCells + //GistId:93de23a2f74a7f2e4971ed203874c983 + void mergeCells(Cell startCell, Cell endCell) + { + Table parentTable = startCell.getParentRow().getParentTable(); + + // Find the row and cell indices for the start and end cell. + /*Point*/long startCellPos = msPoint.ctor(startCell.getParentRow().indexOf(startCell), + parentTable.indexOf(startCell.getParentRow())); + /*Point*/long endCellPos = msPoint.ctor(endCell.getParentRow().indexOf(endCell), parentTable.indexOf(endCell.getParentRow())); + + // Create a range of cells to be merged based on these indices. + // Inverse each index if the end cell is before the start cell. + Rectangle mergeRange = new Rectangle(Math.min(msPoint.getX(startCellPos), msPoint.getX(endCellPos)), + Math.min(msPoint.getY(startCellPos), msPoint.getY(endCellPos)), + Math.abs(msPoint.getX(endCellPos) - msPoint.getX(startCellPos)) + 1, Math.abs(msPoint.getY(endCellPos) - msPoint.getY(startCellPos)) + 1); + + for (Row row : (Iterable) parentTable.getRows()) + { + for (Cell cell : (Iterable) row.getCells()) + { + /*Point*/long currentPos = msPoint.ctor(row.indexOf(cell), parentTable.indexOf(row)); + + // Check if the current cell is inside our merge range, then merge it. + if (mergeRange.contains(currentPos)) + { + cell.getCellFormat().setHorizontalMerge(msPoint.getX(currentPos) == mergeRange.getX() ? CellMerge.FIRST : CellMerge.PREVIOUS); + + cell.getCellFormat().setVerticalMerge(msPoint.getY(currentPos) == mergeRange.getY() ? CellMerge.FIRST : CellMerge.PREVIOUS); + } + } + } + } + //ExEnd:MergeCells + + //ExStart:HorizontalAndVerticalMergeHelperClasses + //GistId:93de23a2f74a7f2e4971ed203874c983 + /// + /// Helper class that contains collection of rowinfo for each row. + /// + public static class TableInfo + { + public ArrayList getRows() { return mRows; }; + + private ArrayList mRows !!!Autoporter warning: AutoProperty initialization can't be autoported! = /*new*/ ArrayListlist(); + } + + /// + /// Helper class that contains collection of cellinfo for each cell. + /// + public static class RowInfo + { + public ArrayList getCells() { return mCells; }; + + private ArrayList mCells !!!Autoporter warning: AutoProperty initialization can't be autoported! = /*new*/ArrayListlist(); + } + + /// + /// Helper class that contains info about cell. currently here is only colspan and rowspan. + /// + public static class CellInfo + { + public CellInfo(int colSpan, int rowSpan) + { + mColSpan = colSpan; + mRowSpan = rowSpan; + } + + public int getColSpan() { return mColSpan; }; + + private int mColSpan; + public int getRowSpan() { return mRowSpan; }; + + private int mRowSpan; + } + + public static class SpanVisitor extends DocumentVisitor + { + /// + /// Creates new SpanVisitor instance. + /// + /// + /// Is document which we should parse. + /// + public SpanVisitor(Document doc) throws Exception + { + mWordTables = doc.getChildNodes(NodeType.TABLE, true); + + // We will parse HTML to determine the rowspan and colspan of each cell. + MemoryStream htmlStream = new MemoryStream(); + + HtmlSaveOptions options = new HtmlSaveOptions(); + { + options.setImagesFolder(Path.getTempPath()); + } + + doc.save(htmlStream, options); + + // Load HTML into the XML document. + org.w3c.dom.Document xmlDoc = XmlUtilPal.newXmlDocument(); + htmlStream.setPosition(0); + xmlDoc.Load(htmlStream); + + // Get collection of tables in the HTML document. + org.w3c.dom.NodeList tables = xmlDoc.getDocumentElement().getElementsByTagName("table"); + + for (org.w3c.dom.Node table : (Iterable) tables) + { + TableInfo tableInf = new TableInfo(); + // Get collection of rows in the table. + org.w3c.dom.NodeList rows = table.SelectNodes("tr"); + + for (org.w3c.dom.Node row : (Iterable) rows) + { + RowInfo rowInf = new RowInfo(); + // Get collection of cells. + org.w3c.dom.NodeList cells = row.SelectNodes("td"); + + for (org.w3c.dom.Node cell : (Iterable) cells) + { + // Determine row span and colspan of the current cell. + org.w3c.dom.Attr colSpanAttr = cell.getAttributes().getNamedItem("colspan"); + org.w3c.dom.Attr rowSpanAttr = cell.getAttributes().getNamedItem("rowspan"); + + int colSpan = colSpanAttr == null ? 0 : Integer.parseInt(colSpanAttr.getNodeValue()); + int rowSpan = rowSpanAttr == null ? 0 : Integer.parseInt(rowSpanAttr.getNodeValue()); + + CellInfo cellInf = new CellInfo(colSpan, rowSpan); + rowInf.getCells().add(cellInf); + } + + tableInf.getRows().add(rowInf); + } + + mTables.add(tableInf); + } + } + + public /*override*/ /*VisitorAction*/int visitCellStart(Cell cell) + { + int tabIdx = mWordTables.indexOf(cell.getParentRow().getParentTable()); + int rowIdx = cell.getParentRow().getParentTable().indexOf(cell.getParentRow()); + int cellIdx = cell.getParentRow().indexOf(cell); + + int colSpan = 0; + int rowSpan = 0; + if (tabIdx < mTables.size() && + rowIdx < mTables.get(tabIdx).getRows().size() && + cellIdx < mTables.get(tabIdx).getRows().get(rowIdx).getCells().size()) + { + colSpan = mTables.get(tabIdx).getRows().get(rowIdx).getCells().get(cellIdx).getColSpan(); + rowSpan = mTables.get(tabIdx).getRows().get(rowIdx).getCells().get(cellIdx).getRowSpan(); + } + + msConsole.writeLine("{0}.{1}.{2} colspan={3}\t rowspan={4}", tabIdx, rowIdx, cellIdx, colSpan, rowSpan); + + return VisitorAction.CONTINUE; + } + + private /*final*/ ArrayList mTables = new ArrayList(); + private /*final*/ NodeCollection mWordTables; + } + //ExEnd:HorizontalAndVerticalMergeHelperClasses + + @Test + public void repeatRowsOnSubsequentPages() throws Exception + { + //ExStart:RepeatRowsOnSubsequentPages + //GistId:7e7e54ead8b97457543ea46fc6bae045 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + builder.startTable(); + builder.getRowFormat().setHeadingFormat(true); + builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); + builder.getCellFormat().setWidth(100.0); + builder.insertCell(); + builder.writeln("Heading row 1"); + builder.endRow(); + builder.insertCell(); + builder.writeln("Heading row 2"); + builder.endRow(); + + builder.getCellFormat().setWidth(50.0); + builder.getParagraphFormat().clearFormatting(); + + for (int i = 0; i < 50; i++) + { + builder.insertCell(); + builder.getRowFormat().setHeadingFormat(false); + builder.write("Column 1 Text"); + builder.insertCell(); + builder.write("Column 2 Text"); + builder.endRow(); + } + + doc.save(getArtifactsDir() + "WorkingWithTables.RepeatRowsOnSubsequentPages.docx"); + //ExEnd:RepeatRowsOnSubsequentPages + } + + @Test + public void autoFitPageWidth() throws Exception + { + //ExStart:AutoFitPageWidth + //GistId:770bf20bd617f3cb80031a74cc6c9b73 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a table with a width that takes up half the page width. + Table table = builder.startTable(); + + builder.insertCell(); + table.setPreferredWidth(PreferredWidth.fromPercent(50.0)); + builder.writeln("Cell #1"); + + builder.insertCell(); + builder.writeln("Cell #2"); + + builder.insertCell(); + builder.writeln("Cell #3"); + + doc.save(getArtifactsDir() + "WorkingWithTables.AutoFitPageWidth.docx"); + //ExEnd:AutoFitPageWidth + } + + @Test + public void preferredWidthSettings() throws Exception + { + //ExStart:PreferredWidthSettings + //GistId:770bf20bd617f3cb80031a74cc6c9b73 + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert a table row made up of three cells which have different preferred widths. + // Insert an absolute sized cell. + builder.insertCell(); + builder.getCellFormat().setPreferredWidth(PreferredWidth.fromPoints(40.0)); + builder.getCellFormat().getShading().setBackgroundPatternColor(Color.LightYellow); + builder.writeln("Cell at 40 points width"); + + // Insert a relative (percent) sized cell. + builder.insertCell(); + builder.getCellFormat().setPreferredWidth(PreferredWidth.fromPercent(20.0)); + builder.getCellFormat().getShading().setBackgroundPatternColor(msColor.getLightBlue()); + builder.writeln("Cell at 20% width"); + + // Insert a auto sized cell. + builder.insertCell(); + builder.getCellFormat().setPreferredWidth(PreferredWidth.AUTO); + builder.getCellFormat().getShading().setBackgroundPatternColor(msColor.getLightGreen()); + builder.writeln( + "Cell automatically sized. The size of this cell is calculated from the table preferred width."); + builder.writeln("In this case the cell will fill up the rest of the available space."); + + doc.save(getArtifactsDir() + "WorkingWithTables.PreferredWidthSettings.docx"); + //ExEnd:PreferredWidthSettings + } + + @Test + public void retrievePreferredWidthType() throws Exception + { + //ExStart:RetrievePreferredWidthType + //GistId:770bf20bd617f3cb80031a74cc6c9b73 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + //ExStart:AllowAutoFit + //GistId:770bf20bd617f3cb80031a74cc6c9b73 + table.setAllowAutoFit(true); + //ExEnd:AllowAutoFit + + Cell firstCell = table.getFirstRow().getFirstCell(); + /*PreferredWidthType*/int type = firstCell.getCellFormat().getPreferredWidth().getType(); + double value = firstCell.getCellFormat().getPreferredWidth().getValue(); + //ExEnd:RetrievePreferredWidthType + } + + @Test + public void getTablePosition() throws Exception + { + //ExStart:GetTablePosition + //GistId:8df1ad0825619cab7c80b571c6e6ba99 + Document doc = new Document(getMyDir() + "Tables.docx"); + + Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); + + if (table.getTextWrapping() == TextWrapping.AROUND) + { + System.out.println(table.getRelativeHorizontalAlignment()); + System.out.println(table.getRelativeVerticalAlignment()); + } + else + { + System.out.println(table.getAlignment()); + } + //ExEnd:GetTablePosition + } + + @Test + public void getFloatingTablePosition() throws Exception + { + //ExStart:GetFloatingTablePosition + //GistId:8df1ad0825619cab7c80b571c6e6ba99 + Document doc = new Document(getMyDir() + "Table wrapped by text.docx"); + + for (Table table : (Iterable) doc.getFirstSection().getBody().getTables()) + { + // If the table is floating type, then print its positioning properties. + if (table.getTextWrapping() == TextWrapping.AROUND) + { + System.out.println(table.getHorizontalAnchor()); + System.out.println(table.getVerticalAnchor()); + msConsole.writeLine(table.getAbsoluteHorizontalDistance()); + msConsole.writeLine(table.getAbsoluteVerticalDistance()); + msConsole.writeLine(table.getAllowOverlap()); + msConsole.writeLine(table.getAbsoluteHorizontalDistance()); + System.out.println(table.getRelativeVerticalAlignment()); + System.out.println(".............................."); + } + } + //ExEnd:GetFloatingTablePosition + } + + @Test + public void floatingTablePosition() throws Exception + { + //ExStart:FloatingTablePosition + //GistId:8df1ad0825619cab7c80b571c6e6ba99 + Document doc = new Document(getMyDir() + "Table wrapped by text.docx"); + + Table table = doc.getFirstSection().getBody().getTables().get(0); + table.setAbsoluteHorizontalDistance(10.0); + table.setRelativeVerticalAlignment(VerticalAlignment.CENTER); + + doc.save(getArtifactsDir() + "WorkingWithTables.FloatingTablePosition.docx"); + //ExEnd:FloatingTablePosition + } + + @Test + public void relativeHorizontalOrVerticalPosition() throws Exception + { + //ExStart:RelativeHorizontalOrVerticalPosition + Document doc = new Document(getMyDir() + "Table wrapped by text.docx"); + + Table table = doc.getFirstSection().getBody().getTables().get(0); + table.setHorizontalAnchor(RelativeHorizontalPosition.COLUMN); + table.setVerticalAnchor(RelativeVerticalPosition.PAGE); + + doc.save(getArtifactsDir() + "WorkingWithTables.RelativeHorizontalOrVerticalPosition.docx"); + //ExEnd:RelativeHorizontalOrVerticalPosition + } + + //JAVA-added for string switch emulation + private static final StringSwitchMap gStringSwitchMap = new StringSwitchMap + ( + "DateTime" + ); + +} diff --git a/Examples/DocsExamples/JavaPorting/Rendering_and_printing/Complex_examples_and_helpers/EnumerateLayoutElements.java b/Examples/DocsExamples/JavaPorting/Rendering_and_printing/Complex_examples_and_helpers/EnumerateLayoutElements.java new file mode 100644 index 00000000..8d1f0b73 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Rendering_and_printing/Complex_examples_and_helpers/EnumerateLayoutElements.java @@ -0,0 +1,203 @@ +package DocsExamples.Complex_examples_and_helpers; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.LayoutEnumerator; +import com.aspose.ms.System.msConsole; +import com.aspose.words.LayoutEntityType; +import com.aspose.ms.System.msString; +import com.aspose.words.PageInfo; +import java.awt.image.BufferedImage; +import com.aspose.ms.System.Drawing.msSize; +import java.awt.Graphics2D; +import java.awt.Color; +import com.aspose.ms.System.Drawing.RectangleF; +import com.aspose.ms.System.Drawing.Rectangle; +import com.aspose.ms.System.Convert; +import com.aspose.words.ConvertUtil; + + +public class EnumerateLayoutElements extends DocsExamplesBase +{ + @Test + public void getLayoutElements() throws Exception + { + Document doc = new Document(getMyDir() + "Document layout.docx"); + + // Enumerator which is used to "walk" the elements of a rendered document. + LayoutEnumerator layoutEnumerator = new LayoutEnumerator(doc); + + // Use the enumerator to write information about each layout element to the console. + LayoutInfoWriter.run(layoutEnumerator); + + // Adds a border around each layout element and saves each page as a JPEG image to the data directory. + OutlineLayoutEntitiesRenderer.run(doc, layoutEnumerator, getArtifactsDir()); + } +} +class LayoutInfoWriter +{ + public static void run(LayoutEnumerator layoutEnumerator) throws Exception + { + displayLayoutElements(layoutEnumerator, ""); + } + + /// + /// Enumerates forward through each layout element in the document and prints out details of each element. + /// + private static void displayLayoutElements(LayoutEnumerator layoutEnumerator, String padding) throws Exception + { + do + { + displayEntityInfo(layoutEnumerator, padding); + + if (layoutEnumerator.moveFirstChild()) + { + // Recurse into this child element. + displayLayoutElements(layoutEnumerator, addPadding(padding)); + layoutEnumerator.moveParent(); + } + } while (layoutEnumerator.moveNext()); + } + + /// + /// Displays information about the current layout entity to the console. + /// + private static void displayEntityInfo(LayoutEnumerator layoutEnumerator, String padding) throws Exception + { + msConsole.write(padding + layoutEnumerator.getType() + " - " + layoutEnumerator.getKind()); + + if (layoutEnumerator.getType() == LayoutEntityType.SPAN) + msConsole.write(" - " + layoutEnumerator.getText()); + + msConsole.writeLine(); + } + + /// + /// Returns a string of spaces for padding purposes. + /// + private static String addPadding(String padding) + { + return padding + msString.newString(' ', 4); + } +} + +class OutlineLayoutEntitiesRenderer +{ + public static void run(Document doc, LayoutEnumerator layoutEnumerator, String folderPath) throws Exception + { + // Make sure the enumerator is at the beginning of the document. + layoutEnumerator.reset(); + + for (int pageIndex = 0; pageIndex < doc.getPageCount(); pageIndex++) + { + // Use the document class to find information about the current page. + PageInfo pageInfo = doc.getPageInfo(pageIndex); + + final float RESOLUTION = 150.0f; + /*Size*/long pageSize = pageInfo.getSizeInPixelsInternal(1.0f, RESOLUTION); + + BufferedImage img = new BufferedImage(msSize.getWidth(pageSize), msSize.getHeight(pageSize)); + try /*JAVA: was using*/ + { + img.SetResolution(RESOLUTION, RESOLUTION); + + Graphics2D g = Graphics2D.FromImage(img); + try /*JAVA: was using*/ + { + // Make the background white. + g.Clear(Color.WHITE); + + // Render the page to the graphics. + doc.renderToScaleInternal(pageIndex, g, 0.0f, 0.0f, 1.0f); + + // Add an outline around each element on the page using the graphics object. + addBoundingBoxToElementsOnPage(layoutEnumerator, g); + + // Move the enumerator to the next page if there is one. + layoutEnumerator.moveNext(); + + img.Save(folderPath + $"EnumerateLayoutElements.Page_{pageIndex + 1}.png"); + } + finally { if (g != null) g.close(); } + } + finally { if (img != null) img.close(); } + } + } + + /// + /// Adds a colored border around each layout element on the page. + /// + private static void addBoundingBoxToElementsOnPage(LayoutEnumerator layoutEnumerator, Graphics2D g) throws Exception + { + do + { + // Use MoveLastChild and MovePrevious to enumerate from last to the first enumeration is done backward, + // so the lines of child entities are drawn first and don't overlap the parent's lines. + if (layoutEnumerator.moveLastChild()) + { + addBoundingBoxToElementsOnPage(layoutEnumerator, g); + layoutEnumerator.moveParent(); + } + + // Convert the rectangle representing the position of the layout entity on the page from points to pixels. + RectangleF rectF = layoutEnumerator.getRectangleInternal(); + Rectangle rect = new Rectangle(pointToPixel(rectF.getLeft(), g.DpiX), pointToPixel(rectF.getTop(), g.DpiY), + pointToPixel(rectF.getWidth(), g.DpiX), pointToPixel(rectF.getHeight(), g.DpiY)); + + // Draw a line around the layout entity on the page. + g.DrawRectangle(getColoredPenFromType(layoutEnumerator.getType()), rect); + + // Stop after all elements on the page have been processed. + if (layoutEnumerator.getType() == LayoutEntityType.PAGE) + return; + } while (layoutEnumerator.movePrevious()); + } + + /// + /// Returns a different colored pen for each entity type. + /// + private static Pen getColoredPenFromType(/*LayoutEntityType*/int type) + { + switch (type) + { + case LayoutEntityType.CELL: + return Pens.Purple; + case LayoutEntityType.COLUMN: + return Pens.Green; + case LayoutEntityType.COMMENT: + return Pens.LightBlue; + case LayoutEntityType.ENDNOTE: + return Pens.DarkRed; + case LayoutEntityType.FOOTNOTE: + return Pens.DarkBlue; + case LayoutEntityType.HEADER_FOOTER: + return Pens.DarkGreen; + case LayoutEntityType.LINE: + return Pens.Blue; + case LayoutEntityType.NOTE_SEPARATOR: + return Pens.LightGreen; + case LayoutEntityType.PAGE: + return Pens.Red; + case LayoutEntityType.ROW: + return Pens.Orange; + case LayoutEntityType.SPAN: + return Pens.Red; + case LayoutEntityType.TEXT_BOX: + return Pens.Yellow; + default: + return Pens.Red; + } + } + + /// + /// Converts a value in points to pixels. + /// + private static int pointToPixel(float value, double resolution) + { + return Convert.toInt32(ConvertUtil.pointToPixel(value, resolution)); + } +} + diff --git a/Examples/DocsExamples/JavaPorting/Rendering_and_printing/Complex_examples_and_helpers/PageLayoutHelper.java b/Examples/DocsExamples/JavaPorting/Rendering_and_printing/Complex_examples_and_helpers/PageLayoutHelper.java new file mode 100644 index 00000000..663353b1 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Rendering_and_printing/Complex_examples_and_helpers/PageLayoutHelper.java @@ -0,0 +1,613 @@ +package DocsExamples.Complex_examples_and_helpers; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.ms.System.msConsole; +import com.aspose.words.Paragraph; +import com.aspose.words.LayoutEntityType; +import com.aspose.words.LayoutCollector; +import com.aspose.words.LayoutEnumerator; +import com.aspose.words.Node; +import com.aspose.words.NodeType; +import java.util.ArrayList; +import com.aspose.words.Row; +import com.aspose.ms.System.Collections.msDictionary; +import java.util.HashMap; +import com.aspose.ms.System.Text.msStringBuilder; +import com.aspose.ms.System.Collections.msArrayList; +import com.aspose.ms.System.Drawing.RectangleF; +import java.util.Iterator; + + +class DocumentLayoutHelper extends DocsExamplesBase +{ + @Test + public void wrapperToAccessLayoutEntities() throws Exception + { + // This sample introduces the RenderedDocument class and other related classes which provide an API wrapper for + // the LayoutEnumerator. This allows you to access the layout entities of a document using a DOM style API. + Document doc = new Document(getMyDir() + "Document layout.docx"); + + RenderedDocument layoutDoc = new RenderedDocument(doc); + + // Get access to the line of the first page and print to the console. + RenderedLine line = layoutDoc.Pages[0].Columns[0].Lines[2]; + System.out.println("Line: " + line.getText()); + + // With a rendered line, the original paragraph in the document object model can be returned. + Paragraph para = line.Paragraph; + System.out.println("Paragraph text: " + para.getRange().getText()); + + // Retrieve all the text that appears on the first page in plain text format (including headers and footers). + String pageText = layoutDoc.Pages[0].Text; + msConsole.writeLine(); + + // Loop through each page in the document and print how many lines appear on each page. + for (RenderedPage page : layoutDoc.Pages !!Autoporter error: Undefined expression type ) + { + LayoutCollection lines = page.getChildEntities(LayoutEntityType.LINE, true); + msConsole.WriteLine("Page {0} has {1} lines.", page.PageIndex, lines.Count); + } + + // This method provides a reverse lookup of layout entities for any given node + // (except runs and nodes in the header and footer). + msConsole.writeLine(); + System.out.println("The lines of the second paragraph:"); + for (RenderedLine paragraphLine : (Iterable) layoutDoc.getLayoutEntitiesOfNode( + doc.getFirstSection().getBody().getParagraphs().get(1))) + { + System.out.println("\"{paragraphLine.Text.Trim()}\""); + msConsole.WriteLine(paragraphLine.Rectangle.ToString()); + msConsole.writeLine(); + } + } +} + +/// +/// Provides an API wrapper for the LayoutEnumerator class to access the page layout +/// of a document presented in an object model like the design. +/// +public class RenderedDocument extends LayoutEntity +{ + /// + /// Creates a new instance from the supplied Document class. + /// + /// A document whose page layout model to enumerate. + /// If page layout model of the document hasn't been built the enumerator calls + /// to build it. + /// Whenever document is updated and new page layout model is created, + /// a new RenderedDocument instance must be used to access the changes. + public RenderedDocument(Document doc) throws Exception + { + mLayoutCollector = new LayoutCollector(doc); + mEnumerator = new LayoutEnumerator(doc); + + processLayoutElements(this); + linkLayoutMarkersToNodes(doc); + collectLinesAndAddToMarkers(); + } + + /// + /// Provides access to the pages of a document. + /// + public LayoutCollection Pages => private GetChildNodesgetChildNodes(); + + /// + /// Returns all the layout entities of the specified node. + /// + /// Note that this method does not work with Run nodes or nodes in the header or footer. + public LayoutCollection getLayoutEntitiesOfNode(Node node) + { + if (!mLayoutCollector.getDocument().equals(node.getDocument())) + throw new IllegalArgumentException("Node does not belong to the same document which was rendered."); + + if (node.getNodeType() == NodeType.DOCUMENT) + return new LayoutCollection(mChildEntities); + + ArrayList entities = new ArrayList(); + + // Retrieve all entities from the layout document (inversion of LayoutEntityType.None). + for (LayoutEntity entity : getChildEntities(~LayoutEntityType.NONE, true)) + { + if (entity.ParentNode == node) + entities.add(entity); + + // There is no table entity in rendered output, so manually check if rows belong to a table node. + if (entity.Type == LayoutEntityType.ROW) + { + RenderedRow row = (RenderedRow) entity; + if (row.Table == node) + entities.add(entity); + } + } + + return new LayoutCollection(entities); + } + + private void processLayoutElements(LayoutEntity current) throws Exception + { + do + { + LayoutEntity child = current.addChildEntity(mEnumerator); + + if (mEnumerator.moveFirstChild()) + { + current = child; + + processLayoutElements(current); + mEnumerator.moveParent(); + + current = current.Parent; + } + } while (mEnumerator.moveNext()); + } + + private void collectLinesAndAddToMarkers() + { + collectLinesOfMarkersCore(LayoutEntityType.COLUMN); + collectLinesOfMarkersCore(LayoutEntityType.COMMENT); + } + + private void collectLinesOfMarkersCore(/*LayoutEntityType*/int type) + { + ArrayList collectedLines = new ArrayList(); + + for (RenderedPage page : Pages !!Autoporter error: Undefined expression type ) + { + for (LayoutEntity story : page.getChildEntities(type, false)) + { + for (RenderedLine line : (Iterable) story.getChildEntities(LayoutEntityType.LINE, true)) + { + collectedLines.add(line); + for (RenderedSpan span : line.Spans !!Autoporter error: Undefined expression type ) + { + if (mLayoutToNodeLookup.containsKey(span.getLayoutObject())) + { + if ("PARAGRAPH".equals(span.Kind) || "ROW".equals(span.Kind) || "CELL".equals(span.Kind) || + "SECTION".equals(span.Kind)) + { + Node node = mLayoutToNodeLookup.get(span.getLayoutObject()); + + if (node.getNodeType() == NodeType.ROW) + node = ((Row) node).getLastCell().getLastParagraph(); + + for (RenderedLine collectedLine : collectedLines) + collectedLine.setParentNode(node); + + collectedLines = new ArrayList(); + } + else + { + span.setParentNode(mLayoutToNodeLookup.get(span.getLayoutObject())); + } + } + } + } + } + } + } + + private void linkLayoutMarkersToNodes(Document doc) throws Exception + { + for (Node node : (Iterable) doc.getChildNodes(NodeType.ANY, true)) + { + Object entity = mLayoutCollector.getEntity(node); + + if (entity != null) + msDictionary.add(mLayoutToNodeLookup, entity, node); + } + } + + private /*final*/ LayoutCollector mLayoutCollector; + private /*final*/ LayoutEnumerator mEnumerator; + + private /*final*/ HashMap mLayoutToNodeLookup = + new HashMap(); +} + +/// +/// Provides the base class for rendered elements of a document. +/// +public abstract class LayoutEntity +{private mPageIndexmPageIndex; + + /// + /// Returns bounding rectangle of the entity relative to the page top left corner (in points). + /// + public RectangleF Rectangle => private mRectanglemRectangle;private mTypemType; + + /// + /// Exports the contents of the entity into a string in plain text format. + /// + public /*virtual*/ String getText() + { + StringBuilder builder = new StringBuilder(); + for (LayoutEntity entity : mChildEntities) + { + msStringBuilder.append(builder, entity.getText()); + } + + return builder.toString(); + }private mParentmParent; + + /// + /// Returns the node that corresponds to this layout entity. + /// + /// This property may return null for spans that originate + /// from Run nodes or nodes inside the header or footer. + public /*virtual*/ Node ParentNode => private mParentNodemParentNode; + + /// + /// Internal method separate from ParentNode property to make code autoportable to VB.NET. + /// + /*virtual*/ void setParentNode(Node value) + { + mParentNode = value; + } + + /// + /// Reserved for internal use. + /// + Object getLayoutObject() { return mLayoutObject; }; void setLayoutObject(Object value) { mLayoutObject = value; }; + + private Object mLayoutObject; + + /// + /// Reserved for internal use. + /// + LayoutEntity addChildEntity(LayoutEnumerator it) throws Exception + { + LayoutEntity child = createLayoutEntityFromType(it); + mChildEntities.add(child); + + return child; + } + + private LayoutEntity createLayoutEntityFromType(LayoutEnumerator it) throws Exception + { + LayoutEntity childEntity; + switch (it.getType()) + { + case LayoutEntityType.CELL: + childEntity = new RenderedCell(); + break; + case LayoutEntityType.COLUMN: + childEntity = new RenderedColumn(); + break; + case LayoutEntityType.COMMENT: + childEntity = new RenderedComment(); + break; + case LayoutEntityType.ENDNOTE: + childEntity = new RenderedEndnote(); + break; + case LayoutEntityType.FOOTNOTE: + childEntity = new RenderedFootnote(); + break; + case LayoutEntityType.HEADER_FOOTER: + childEntity = new RenderedHeaderFooter(); + break; + case LayoutEntityType.LINE: + childEntity = new RenderedLine(); + break; + case LayoutEntityType.NOTE_SEPARATOR: + childEntity = new RenderedNoteSeparator(); + break; + case LayoutEntityType.PAGE: + childEntity = new RenderedPage(); + break; + case LayoutEntityType.ROW: + childEntity = new RenderedRow(); + break; + case LayoutEntityType.SPAN: + childEntity = new RenderedSpan(it.getText()); + break; + case LayoutEntityType.TEXT_BOX: + childEntity = new RenderedTextBox(); + break; + default: + throw new IllegalStateException("Unknown layout type"); + } + + childEntity.mKind = it.getKind(); + childEntity.mPageIndex = it.getPageIndex(); + childEntity.mRectangle = it.getRectangleInternal(); + childEntity.mType = it.getType(); + childEntity.setLayoutObject(it.getCurrent()); + childEntity.mParent = this; + + return childEntity; + } + + /// + /// Returns a collection of child entities which match the specified type. + /// + /// Specifies the type of entities to select. + /// True to select from all child entities recursively. + /// False to select only among immediate children + public LayoutCollection getChildEntities(/*LayoutEntityType*/int type, boolean isDeep) + { + ArrayList childList = new ArrayList(); + + for (LayoutEntity entity : mChildEntities) + { + if ((entity.Type & type) == entity.Type) + childList.add(entity); + + if (isDeep) + msArrayList.addRange(childList, entity.getChildEntities(type, true)); + } + + return new LayoutCollection(childList); + } + + protected LayoutCollection getChildNodes() + { + T obj = new T(); + ArrayList childList = mChildEntities.Where(entity => entity.GetType() == obj.GetType()).Cast().ToList(); + + return new LayoutCollection(childList); + } + + protected String mKind; + protected int mPageIndex; + protected Node mParentNode; + protected RectangleF mRectangle; + protected /*LayoutEntityType*/int mType; + protected LayoutEntity mParent; + protected ArrayList mChildEntities = new ArrayList(); +} + +/// +/// Represents a generic collection of layout entity types. +/// +public final class LayoutCollection implements Iterable +{ + /// + /// Reserved for internal use. + /// + LayoutCollection(ArrayList baseList) + { + mBaseList = baseList; + } + + /// + /// Provides a simple "foreach" style iteration over the collection of nodes. + /// + //JAVA-deleted non-generic namesake: + //Iterator iterator() + + /// + /// Provides a simple "foreach" style iteration over the collection of nodes. + /// + public Iterator /*IEnumerable.*/iterator() + { + return mBaseList.GetEnumerator(); + } + + /// + /// Returns the first entity in the collection. + /// + public T First => mBaseList.Count > 0 ? mBaseList[0] : default; + + /// + /// Returns the last entity in the collection. + /// + public T Last => mBaseList.Count > 0 ? mBaseList[mBaseList.Count - 1] : default; + + /// + /// Retrieves the entity at the given index. + /// + /// The index is zero-based. + /// If index is greater than or equal to the number of items in the list, + /// this returns a null reference. + !!Autoporter error: Indexer DocsExamples.Complex_examples_and_helpers.LayoutCollection.Item(int) hasn't both getter and setter! => index < mBaseList.Count ? mBaseList[index] : default; + + /// + /// Gets the number of entities in the collection. + /// + public int Count => mBaseList.Count; + + private /*final*/ List mBaseList; +} + +/// +/// Represents an entity that contains lines and rows. +/// +public abstract class StoryLayoutEntity extends LayoutEntity +{private GetChildNodesgetChildNodes();private GetChildNodesgetChildNodes(); +} + +/// +/// Represents line of characters of text and inline objects. +/// +public class RenderedLine extends LayoutEntity +{private Environment.NewLineEnvironment;private ParentNodeParentNode; + + /// + /// Provides access to the spans of the line. + /// + public LayoutCollection Spans => private GetChildNodesgetChildNodes(); +} + +/// +/// Represents one or more characters in a line. +/// This include special characters like field start/end markers, bookmarks, shapes and comments. +/// +public class RenderedSpan extends LayoutEntity +{ + public RenderedSpan() + { + } + + RenderedSpan(String text) + { + // Assign empty text if the span text is null (this can happen with shape spans). + mText = (text != null ? text : ""); + }private mKindmKind; + + /// + /// Exports the contents of the entity into a string in plain text format. + /// + public /*override*/ String getText() { return mText; }; + + private String mText;private mParentNodemParentNode; +} + +/// +/// Represents the header/footer content on a page. +/// +public class RenderedHeaderFooter extends StoryLayoutEntity +{ + /// + /// Returns the type of the header or footer. + /// + public String Kind => private mKindmKind; +} + +/// +/// Represents page of a document. +/// +public class RenderedPage extends LayoutEntity +{ + /// + /// Provides access to the columns of the page. + /// + public LayoutCollection Columns => private GetChildNodesgetChildNodes();private GetChildNodesgetChildNodes(); + + /// + /// Provides access to the comments of the page. + /// + public LayoutCollection Comments => private GetChildNodesgetChildNodes(); + + /// + /// Returns the section that corresponds to the layout entity. + /// + public Section Section => (Section) private ParentNodeParentNode;private Columns.First.GetChildEntitiescolumns(LayoutEntityType.Line, true)private First.ParentNode.GetAncestorfirst(NodeType.Section); +} + +/// +/// Represents a table row. +/// +public class RenderedRow extends LayoutEntity +{private GetChildNodesgetChildNodes(); + + /// + /// Returns the row that corresponds to the layout entity. + /// + /// This property may return null for some rows such as those inside the header or footer. + public Row Row => (Row) private ParentNodeParentNode;private ParentTableParentTable; + + /// + /// Returns the node that corresponds to this layout entity. + /// + /// This property may return null for nodes that are inside the header or footer. + public /*override*/ Node getParentNode() + { + Paragraph para = Cells.First.Lines.First?.Paragraph; + return para?.GetAncestor(NodeType.Row); + } +} + +/// +/// Represents a column of text on a page. +/// +public class RenderedColumn extends StoryLayoutEntity +{private GetChildNodesgetChildNodes(); + + /// + /// Provides access to the endnotes of the page. + /// + public LayoutCollection Endnotes => private GetChildNodesgetChildNodes(); + + /// + /// Provides access to the note separators of the page. + /// + public LayoutCollection NoteSeparators => private GetChildNodesgetChildNodes();private ParentNodeParentNode; + + /// + /// Returns the node that corresponds to this layout entity. + /// + public /*override*/ Node ParentNode => + private GetChildEntitiesgetChildEntities(LayoutEntityType.Line, true).private First.ParentNode.GetAncestorfirst(NodeType.Body); +} + +/// +/// Represents a table cell. +/// +public class RenderedCell extends StoryLayoutEntity +{ + /// + /// Returns the cell that corresponds to the layout entity. + /// + /// This property may return null for some cells such as those inside the header or footer. + public Cell Cell => (Cell) private ParentNodeParentNode;private GetAncestorgetAncestor(NodeType.Cell); +} + +/// +/// Represents placeholder for footnote content. +/// +public class RenderedFootnote extends StoryLayoutEntity +{private ParentNodeParentNode; + + /// + /// Returns the node that corresponds to this layout entity. + /// + public /*override*/ Node ParentNode => + private GetChildEntitiesgetChildEntities(LayoutEntityType.Line, true).private First.ParentNode.GetAncestorfirst(NodeType.Footnote); +} + +/// +/// Represents placeholder for endnote content. +/// +public class RenderedEndnote extends StoryLayoutEntity +{ + /// + /// Returns the endnote that corresponds to the layout entity. + /// + public Footnote Endnote => (Footnote) private ParentNodeParentNode;private GetChildEntitiesgetChildEntities(LayoutEntityType.Line, true).private First.ParentNode.GetAncestorfirst(NodeType.Footnote); +} + +/// +/// Represents text area inside of a shape. +/// +public class RenderedTextBox extends StoryLayoutEntity +{ + /// + /// Returns the Shape or DrawingML that corresponds to the layout entity. + /// + /// This property may return null for some Shapes or DrawingML such as those inside the header or footer. + public /*override*/ Node getParentNode() + { + LayoutCollection lines = getChildEntities(LayoutEntityType.LINE, true); + Node shape = lines.First.ParentNode.GetAncestor(NodeType.SHAPE); + + return (shape != null ? shape : lines.First.ParentNode.GetAncestor(NodeType.SHAPE)); + } +} + +/// +/// Represents placeholder for comment content. +/// +public class RenderedComment extends StoryLayoutEntity +{private ParentNodeParentNode; + + /// + /// Returns the node that corresponds to this layout entity. + /// + public /*override*/ Node ParentNode => + private GetChildEntitiesgetChildEntities(LayoutEntityType.Line, true).private First.ParentNode.GetAncestorfirst(NodeType.Comment); +} + +/// +/// Represents footnote/endnote separator. +/// +public class RenderedNoteSeparator extends StoryLayoutEntity +{ + /// + /// Returns the footnote/endnote that corresponds to the layout entity. + /// + public Footnote Footnote => (Footnote) private ParentNodeParentNode;private GetChildEntitiesgetChildEntities(LayoutEntityType.Line, true).private First.ParentNode.GetAncestorfirst(NodeType.Footnote); +} diff --git a/Examples/DocsExamples/JavaPorting/Rendering_and_printing/PrintDocuments.java b/Examples/DocsExamples/JavaPorting/Rendering_and_printing/PrintDocuments.java new file mode 100644 index 00000000..5b3b7ed3 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Rendering_and_printing/PrintDocuments.java @@ -0,0 +1,678 @@ +package DocsExamples.Rendering_and_Printing; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.ms.System.Drawing.Printing.PrinterSettings; +import com.aspose.words.AsposeWordsPrintDocument; +import com.aspose.ms.System.Drawing.msSize; +import com.aspose.ms.System.ms; +import com.aspose.ms.System.Drawing.Text.TextRenderingHint; +import com.aspose.ms.System.Drawing.msSizeF; +import com.aspose.words.ConvertUtil; +import com.aspose.ms.System.msConsole; +import com.aspose.ms.System.IO.MemoryStream; +import com.aspose.words.SaveFormat; +import com.aspose.ms.System.IO.Stream; +import com.aspose.ms.System.EventArgs; +import com.aspose.words.ref.Ref; +import com.aspose.words.ref.RefInt; + + +class PrintDocuments extends DocsExamplesBase +{ + @Test (enabled = false, description = "Run only when the printer driver is installed") + public void cachePrinterSettings() throws Exception + { + //ExStart:CachePrinterSettings + Document doc = new Document(getMyDir() + "Rendering.docx"); + + doc.updatePageLayout(); + + PrinterSettings settings = new PrinterSettings(); { settings.setPrinterName("Microsoft XPS Document Writer"); } + + // The standard print controller comes with no UI. + PrintController standardPrintController = new StandardPrintController(); + + AsposeWordsPrintDocument printDocument = new AsposeWordsPrintDocument(doc); + { + printDocument.setPrinterSettings(settings); + printDocument.setPrintController(standardPrintController); + } + printDocument.cachePrinterSettings(); + + printDocument.print(); + //ExEnd:CachePrinterSettings + } + + @Test (enabled = false, description = "Run only when the printer driver is installed") + public void print() throws Exception + { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + //ExStart:PrintDialog + // Initialize the print dialog with the number of pages in the document. + PrintDialog printDlg = new PrintDialog(); + { + printDlg.setAllowSomePages(true); + printDlg.setPrinterSettings({ + printDlg.getPrinterSettings().setMinimumPage(1); printDlg.getPrinterSettings().setMaximumPage(doc.getPageCount()); printDlg.getPrinterSettings().setFromPage(1); printDlg.getPrinterSettings().setToPage(doc.getPageCount()); + }); + } + //ExEnd:PrintDialog + + //ExStart:ShowDialog + if (printDlg.ShowDialog() != DialogResult.OK) + return; + //ExEnd:ShowDialog + + //ExStart:AsposeWordsPrintDocument + // Pass the printer settings from the dialog to the print document. + AsposeWordsPrintDocument awPrintDoc = new AsposeWordsPrintDocument(doc); + { + awPrintDoc.setPrinterSettings(printDlg.PrinterSettings); + } + //ExEnd:AsposeWordsPrintDocument + + //ExStart:ActivePrintPreviewDialog + // Pass the Aspose.Words print document to the Print Preview dialog. + ActivePrintPreviewDialog previewDlg = new ActivePrintPreviewDialog(); + { + previewDlg.setDocument(awPrintDoc); previewDlg.setShowInTaskbar(true); previewDlg.setMinimizeBox(true); + } + + // Specify additional parameters of the Print Preview dialog. + previewDlg.PrintPreviewControl.Zoom = 1.0; + previewDlg.Document.setDocumentName("PrintDocuments.Print.docx"); + previewDlg.WindowState = FormWindowState.Maximized; + previewDlg.ShowDialog(); // Show the appropriately configured Print Preview dialog. + //ExEnd:ActivePrintPreviewDialog + } + + @Test (enabled = false, description = "Run only when the printer driver is installed") + public void printMultiplePages() throws Exception + { + //ExStart:PrintMultiplePagesOnOneSheet + Document doc = new Document(getMyDir() + "Rendering.docx"); + + //ExStart:PrintDialogSettings + // Initialize the Print Dialog with the number of pages in the document. + PrintDialog printDlg = new PrintDialog(); + { + printDlg.setAllowSomePages(true); + printDlg.setPrinterSettings({ + printDlg.getPrinterSettings().setMinimumPage(1); printDlg.getPrinterSettings().setMaximumPage(doc.getPageCount()); printDlg.getPrinterSettings().setFromPage(1); printDlg.getPrinterSettings().setToPage(doc.getPageCount()); + }); + } + //ExEnd:PrintDialogSettings + + // Check if the user accepted the print settings and proceed to preview. + //ExStart:CheckPrintSettings + if (printDlg.ShowDialog() != DialogResult.OK) + return; + //ExEnd:CheckPrintSettings + + // Pass the printer settings from the dialog to the print document. + MultipagePrintDocument awPrintDoc = new MultipagePrintDocument(doc, 4, true); + { + awPrintDoc.setPrinterSettings(printDlg.PrinterSettings); + } + + //ExStart:ActivePrintPreviewDialog + // Create and configure the the ActivePrintPreviewDialog class. + ActivePrintPreviewDialog previewDlg = new ActivePrintPreviewDialog(); + { + previewDlg.setDocument(awPrintDoc); previewDlg.setShowInTaskbar(true); previewDlg.setMinimizeBox(true); + } + + // Specify additional parameters of the Print Preview dialog. + previewDlg.Document.setDocumentName("PrintDocuments.PrintMultiplePages.docx"); + previewDlg.WindowState = FormWindowState.Maximized; + previewDlg.ShowDialog(); // Show appropriately configured Print Preview dialog. + //ExEnd:ActivePrintPreviewDialog + //ExEnd:PrintMultiplePagesOnOneSheet + } + + @Test (enabled = false, description = "Run only when a printer driver installed") + public void useXpsPrintHelper() throws Exception + { + //ExStart:PrintDocViaXpsPrint + Document document = new Document(getMyDir() + "Rendering.docx"); + + // Specify the name of the printer you want to print to. + final String PRINTER_NAME = "\\\\COMPANY\\Brother MFC-885CW Printer"; + + XpsPrintHelper.print(document, PRINTER_NAME, "My Test Job", true); + //ExEnd:PrintDocViaXpsPrint + } +} + +//ExStart:MultipagePrintDocument +class MultipagePrintDocument extends PrintDocument +//ExEnd:MultipagePrintDocument +{ + //ExStart:DataAndStaticFields + private /*final*/ Document mDocument; + private /*final*/ int mPagesPerSheet; + private /*final*/ boolean mPrintPageBorders; + private /*Size*/long mPaperSize = msSize.Empty; + private int mCurrentPage; + + private int mPageTo; + //ExEnd:DataAndStaticFields + + /// + /// The constructor of the custom PrintDocument class. + /// + //ExStart:MultipagePrintDocumentConstructor + public MultipagePrintDocument(Document document, int pagesPerSheet, boolean printPageBorders) + { + mDocument = !!Autoporter warning: Not supported language construction throw new NullPointerException(ms.nameof("document")); + mPagesPerSheet = pagesPerSheet; + mPrintPageBorders = printPageBorders; + } + //ExEnd:MultipagePrintDocumentConstructor + + /// + /// The overridden method OnBeginPrint, which is called before the first page of the document prints. + /// + //ExStart:OnBeginPrint + protected /*override*/ void onBeginPrint(PrintEventArgs e) throws Exception + { + super.onBeginPrint(e); + + switch (getPrinterSettings().getPrintRange()) + { + case PrintRange.AllPages: + mCurrentPage = 0; + mPageTo = mDocument.getPageCount() - 1; + break; + case PrintRange.SomePages: + mCurrentPage = getPrinterSettings().getFromPage() - 1; + mPageTo = getPrinterSettings().getToPage() - 1; + break; + default: + throw new IllegalStateException("Unsupported print range."); + } + + // Store the size of the paper selected by the user, taking into account the paper orientation. + if (getPrinterSettings().getDefaultPageSettings().Landscape) + mPaperSize = msSize.ctor(getPrinterSettings().getDefaultPageSettings().PaperSize.Height, + getPrinterSettings().getDefaultPageSettings().PaperSize.Width); + else + mPaperSize = msSize.ctor(getPrinterSettings().getDefaultPageSettings().PaperSize.Width, + getPrinterSettings().getDefaultPageSettings().PaperSize.Height); + } + //ExEnd:OnBeginPrint + + /// + /// Generates the printed page from the specified number of the document pages. + /// + //ExStart:OnPrintPage + protected /*override*/ void onPrintPage(PrintPageEventArgs e) throws Exception + { + super.onPrintPage(e); + + // Transfer to the point units. + e.Graphics.PageUnit = GraphicsUnit.Point; + e.Graphics.TextRenderingHint = com.aspose.ms.System.Drawing.Text.TextRenderingHint.ANTI_ALIAS_GRID_FIT; + + // Get the number of the thumbnail placeholders across and down the paper sheet. + /*Size*/long thumbCount = getThumbCount(mPagesPerSheet); + + // Calculate the size of each thumbnail placeholder in points. + // Papersize in .NET is represented in hundreds of an inch. We need to convert this value to points first. + /*SizeF*/long thumbSize = msSizeF.ctor( + hundredthsInchToPoint(msSize.getWidth(mPaperSize)) / msSize.getWidth(thumbCount), + hundredthsInchToPoint(msSize.getHeight(mPaperSize)) / msSize.getHeight(thumbCount)); + + // Select the number of the last page to be printed on this sheet of paper. + int pageTo = Math.min(mCurrentPage + mPagesPerSheet - 1, mPageTo); + + // Loop through the selected pages from the stored current page to the calculated last page. + for (int pageIndex = mCurrentPage; pageIndex <= pageTo; pageIndex++) + { + // Calculate the column and row indices. + int rowIdx = Math.DivRem(pageIndex - mCurrentPage, msSize.getWidth(thumbCount), /*out*/ int columnIdx); + + // Define the thumbnail location in world coordinates (points in this case). + float thumbLeft = columnIdx * msSizeF.getWidth(thumbSize); + float thumbTop = rowIdx * msSizeF.getHeight(thumbSize); + // Render the document page to the Graphics object using calculated coordinates and thumbnail placeholder size. + // The useful return value is the scale at which the page was rendered. + float scale = mDocument.renderToSize(pageIndex, e.Graphics, thumbLeft, thumbTop, msSizeF.getWidth(thumbSize), + msSizeF.getHeight(thumbSize)); + + // Draw the page borders (the page thumbnail could be smaller than the thumbnail placeholder size). + if (mPrintPageBorders) + { + // Get the real 100% size of the page in points. + /*SizeF*/long pageSize = mDocument.getPageInfo(pageIndex).getSizeInPointsInternal(); + // Draw the border around the scaled page using the known scale factor. + e.Graphics.DrawRectangle(Pens.Black, thumbLeft, thumbTop, msSizeF.getWidth(pageSize) * scale, + msSizeF.getHeight(pageSize) * scale); + + // Draws the border around the thumbnail placeholder. + e.Graphics.DrawRectangle(Pens.Red, thumbLeft, thumbTop, msSizeF.getWidth(thumbSize), msSizeF.getHeight(thumbSize)); + } + } + + // Re-calculate the next current page and continue with printing if such a page resides within the print range. + mCurrentPage += mPagesPerSheet; + e.HasMorePages = mCurrentPage <= mPageTo; + } + //ExEnd:OnPrintPage + + /// + /// Converts hundredths of inches to points. + /// + //ExStart:HundredthsInchToPoint + private float hundredthsInchToPoint(float value) + { + return (float)ConvertUtil.inchToPoint(value / 100f); + } + //ExEnd:HundredthsInchToPoint + + /// + /// Defines the number of columns and rows depending on the pagesPerSheet number and the page orientation. + /// + //ExStart:GetThumbCount + private /*Size*/long getThumbCount(int pagesPerSheet) + { + /*Size*/long size = msSize.Empty; + // Define the number of columns and rows on the sheet for the Landscape-oriented paper. + switch (pagesPerSheet) + { + case 16: + size = msSize.ctor(4, 4); + break; + case 9: + size = msSize.ctor(3, 3); + break; + case 8: + size = msSize.ctor(4, 2); + break; + case 6: + size = msSize.ctor(3, 2); + break; + case 4: + size = msSize.ctor(2, 2); + break; + case 2: + size = msSize.ctor(2, 1); + break; + default: + size = msSize.ctor(1, 1); + break; + } + + // Switch the width and height of the paper is in the Portrait orientation. + return msSize.getWidth(mPaperSize) < msSize.getHeight(mPaperSize) ? msSize.ctor(msSize.getHeight(size), msSize.getWidth(size)) : size; + } + //ExEnd:GetThumbCount +} + +/// +/// A utility class that converts a document to XPS using Aspose.Words and then sends to the XpsPrint API. +/// +public class XpsPrintHelper +{ + /// + /// No ctor. + /// + private XpsPrintHelper() + { + } + + //ExStart:XpsPrint_PrintDocument + /// + /// Sends an Aspose.Words document to a printer using the XpsPrint API. + /// + /// + /// + /// Job name. Can be null. + /// True to wait for the job to complete. False to return immediately after submitting the job. + /// Thrown if any error occurs. + public static void print(Document document, String printerName, String jobName, boolean isWait) throws Exception + { + System.out.println("Print"); + if (document == null) + throw new NullPointerException(ms.nameof("document")); + + // Use Aspose.Words to convert the document to XPS and store it in a memory stream. + MemoryStream stream = new MemoryStream(); + document.save(stream, SaveFormat.XPS); + + stream.setPosition(0); + System.out.println("Saved as Xps"); + print(stream, printerName, jobName, isWait); + System.out.println("After Print"); + } + //ExEnd:XpsPrint_PrintDocument + + //ExStart:XpsPrint_PrintStream + /// + /// Sends a stream that contains a document in the XPS format to a printer using the XpsPrint API. + /// Has no dependency on Aspose.Words, can be used in any project. + /// + /// + /// + /// Job name. Can be null. + /// True to wait for the job to complete. False to return immediately after submitting the job. + /// Thrown if any error occurs. + public static void print(Stream stream, String printerName, String jobName, boolean isWait) throws Exception + { + if (stream == null) + throw new NullPointerException(ms.nameof("stream")); + if (printerName == null) + throw new NullPointerException(ms.nameof("printerName")); + + // Create an event that we will wait on until the job is complete. + IntPtr completionEvent = createEvent(IntPtr.Zero, true, false, null); + if (completionEvent == IntPtr.Zero) + throw new Win32Exception(); + + System.out.println("StartJob"); + Ref referenceToIXpsPrintJob = new Ref(IXpsPrintJob); + StartJob(printerName, jobName, completionEvent, /*out*/ referenceToIXpsPrintJob + IXpsPrintJob = referenceToIXpsPrintJob.get(); job, /*out*/ IXpsPrintJobStream jobStream); + System.out.println("Done StartJob"); + + System.out.println("Start CopyJob"); + copyJob(stream, jobStream); + System.out.println("End CopyJob"); + + System.out.println("Start Wait"); + if (isWait) + { + waitForJob(completionEvent); + CheckJobStatus(job); + } + System.out.println("End Wait"); + + if (completionEvent != IntPtr.Zero) + closeHandle(completionEvent); + System.out.println("Close Handle"); + } + //ExEnd:XpsPrint_PrintStream + + private static void startJob(String printerName, String jobName, IntPtr completionEvent, /*out*/Ref job, + /*out*/Ref jobStream) + { + int result = startXpsPrintJob(printerName, jobName, null, IntPtr.Zero, completionEvent, + null, 0, /*out*/ job, /*out*/ jobStream, IntPtr.Zero); + if (result != 0) + throw new Win32Exception(result); + } + + private static void copyJob(Stream stream, IXpsPrintJobStream jobStream) throws Exception + { + byte[] buff = new byte[4096]; + while (true) + { + /*uint*/int read = (/*uint*/int)stream.read(buff, 0, buff.length); + if (read == 0) + break; + + jobStream.Write(buff, read, /*out*/ /*uint*/int written); + + if ((read & 0xFFFFFFFFL) != written) + throw new Exception("Failed to copy data to the print job stream."); + } + + // Indicate that the entire document has been copied. + jobStream.close(); + } + + private static void waitForJob(IntPtr completionEvent) + { + final int INFINITE = -1; + switch (waitForSingleObject(completionEvent, INFINITE)) + { + case WAIT_RESULT.WAIT_OBJECT_0: + // Expected result, do nothing. + break; + case WAIT_RESULT.WAIT_FAILED: + throw new Win32Exception(); + default: + throw new Exception("Unexpected result when waiting for the print job."); + } + } + + private static void checkJobStatus(IXpsPrintJob job) + { + Ref referenceToXPS_JOB_STATUS = new Ref(XPS_JOB_STATUS); + job.GetJobStatus(/*out*/ referenceToXPS_JOB_STATUS jobStatus); + XPS_JOB_STATUS = referenceToXPS_JOB_STATUS.get(); + switch (jobStatus.completion) + { + case XPS_JOB_COMPLETION.XPS_JOB_COMPLETED: + // Expected result, do nothing. + break; + case XPS_JOB_COMPLETION.XPS_JOB_FAILED: + throw new Win32Exception(jobStatus.jobStatus); + default: + throw new Exception("Unexpected print job status."); + } + } + + @DllImport ("XpsPrint.dll"EntryPoint = "StartXpsPrintJob") + private static extern int startXpsPrintJob( + @MarshalAs (UnmanagedType.LPWStr) String printerName, + @MarshalAs (UnmanagedType.LPWStr) String jobName, + @MarshalAs (UnmanagedType.LPWStr) String outputFileName, + IntPtr progressEvent, + IntPtr completionEvent, + @MarshalAs (UnmanagedType.LPArray) byte[] printablePagesOn, + /*uint*/int printablePagesOnCount, + /*out*/Ref xpsPrintJob, + /*out*/Ref documentStream, + IntPtr printTicketStream); // "out IXpsPrintJobStream", we don't use it and just want to pass null, hence IntPtr. + + @DllImport ("Kernel32.dll"SetLastError = true) + private static extern IntPtr createEvent(IntPtr lpEventAttributes, boolean bManualReset, boolean bInitialState, + String lpName); + + @DllImport ("Kernel32.dll"SetLastError = true, ExactSpelling = true) + private static extern /*WAIT_RESULT*/int waitForSingleObject(IntPtr handle, int milliseconds); + + @DllImport ("Kernel32.dll"SetLastError = true) + return:/*Attribute target specifier not applicable to java*/ @MarshalAs (UnmanagedType.Bool) + private static extern boolean closeHandle(IntPtr hObject); +} + +/// +/// This interface definition is HACKED. +/// +/// It appears that the IID for IXpsPrintJobStream specified in XpsPrint.h as +/// MIDL_INTERFACE("7a77dc5f-45d6-4dff-9307-d8cb846347ca") is not correct and the RCW cannot return it. +/// But the returned object returns the parent ISequentialStream inteface successfully. +/// +/// So the hack is that we obtain the ISequentialStream interface but work with it as +/// with the IXpsPrintJobStream interface. +/// +@Guid ("0C733A30-2A1C-11CE-ADE5-00AA0044773D") // This is IID of ISequenatialSteam. +@InterfaceType (ComInterfaceType.InterfaceIsIUnknown) +interface IXpsPrintJobStream +{ + // ISequentualStream methods. + public void read( @MarshalAs (UnmanagedType.LPArray) byte[] pv, /*uint*/int cb, /*out*/RefInt pcbRead); + + public void write( @MarshalAs (UnmanagedType.LPArray) byte[] pv, /*uint*/int cb, /*out*/RefInt pcbWritten); + + // IXpsPrintJobStream methods. + public void close(); +} + +@Guid ("5ab89b06-8194-425f-ab3b-d7a96e350161") +@InterfaceType (ComInterfaceType.InterfaceIsIUnknown) +interface IXpsPrintJob +{ + public void cancel(); + public void getJobStatus(/*out*/Ref jobStatus); +} + +/*struct*/ final class XPS_JOB_STATUS +{ + public XPS_JOB_STATUS(){} + + public /*uint*/int jobId; + public int currentDocument; + public int currentPage; + public int currentPageTotal; + public /*XPS_JOB_COMPLETION*/int completion; + public int jobStatus; +} + +/*enum*/ final class XPS_JOB_COMPLETION +{ + private XPS_JOB_COMPLETION(){} + + public static final int XPS_JOB_IN_PROGRESS = 0; + public static final int XPS_JOB_COMPLETED = 1; + public static final int XPS_JOB_CANCELLED = 2; + public static final int XPS_JOB_FAILED = 3; + + /// + /// Returns JAVA_STYLE string representation of integer XPS_JOB_COMPLETION value. + /// + public static String getName(/*XPS_JOB_COMPLETION*/int xPS_JOB_COMPLETION) + { + switch (xPS_JOB_COMPLETION) + { + case XPS_JOB_IN_PROGRESS: return "XPS_JOB_IN_PROGRESS"; + case XPS_JOB_COMPLETED: return "XPS_JOB_COMPLETED"; + case XPS_JOB_CANCELLED: return "XPS_JOB_CANCELLED"; + case XPS_JOB_FAILED: return "XPS_JOB_FAILED"; + default: return "Unknown XPS_JOB_COMPLETION value."; + } + } + + /// + /// Returns DotNetStyle string representation of integer XPS_JOB_COMPLETION value. + /// + public static String toString(/*XPS_JOB_COMPLETION*/int xPS_JOB_COMPLETION) + { + switch (xPS_JOB_COMPLETION) + { + case XPS_JOB_IN_PROGRESS: return "XPS_JOB_IN_PROGRESS"; + case XPS_JOB_COMPLETED: return "XPS_JOB_COMPLETED"; + case XPS_JOB_CANCELLED: return "XPS_JOB_CANCELLED"; + case XPS_JOB_FAILED: return "XPS_JOB_FAILED"; + default: return "Unknown XPS_JOB_COMPLETION value."; + } + } + + /// + /// Returns integer representation by XPS_JOB_COMPLETION name. + /// + public static /*XPS_JOB_COMPLETION*/int fromName(String xPS_JOB_COMPLETIONName) + { + if ("XPS_JOB_IN_PROGRESS".equals(xPS_JOB_COMPLETIONName)) return XPS_JOB_IN_PROGRESS; + if ("XPS_JOB_COMPLETED".equals(xPS_JOB_COMPLETIONName)) return XPS_JOB_COMPLETED; + if ("XPS_JOB_CANCELLED".equals(xPS_JOB_COMPLETIONName)) return XPS_JOB_CANCELLED; + if ("XPS_JOB_FAILED".equals(xPS_JOB_COMPLETIONName)) return XPS_JOB_FAILED; + throw new IllegalArgumentException("Unknown XPS_JOB_COMPLETION name."); + } + + /// + /// Returns array of XPS_JOB_COMPLETION values. + /// + public static int[] getValues() + { + return new int[] + { + XPS_JOB_IN_PROGRESS, + XPS_JOB_COMPLETED, + XPS_JOB_CANCELLED, + XPS_JOB_FAILED, + }; + } + + public static final int length = 4; +} + +/*enum*/ final class WAIT_RESULT +{ + private WAIT_RESULT(){} + + public static final int WAIT_OBJECT_0 = 0; + public static final int WAIT_ABANDONED = 0x80; + public static final int WAIT_TIMEOUT = 0x102; + public static final int WAIT_FAILED = -1; + + /// + /// Returns JAVA_STYLE string representation of integer WAIT_RESULT value. + /// + public static String getName(/*WAIT_RESULT*/int wAIT_RESULT) + { + switch (wAIT_RESULT) + { + case WAIT_OBJECT_0: return "WAIT_OBJECT_0"; + case WAIT_ABANDONED: return "WAIT_ABANDONED"; + case WAIT_TIMEOUT: return "WAIT_TIMEOUT"; + case WAIT_FAILED: return "WAIT_FAILED"; + default: return "Unknown WAIT_RESULT value."; + } + } + + /// + /// Returns DotNetStyle string representation of integer WAIT_RESULT value. + /// + public static String toString(/*WAIT_RESULT*/int wAIT_RESULT) + { + switch (wAIT_RESULT) + { + case WAIT_OBJECT_0: return "WAIT_OBJECT_0"; + case WAIT_ABANDONED: return "WAIT_ABANDONED"; + case WAIT_TIMEOUT: return "WAIT_TIMEOUT"; + case WAIT_FAILED: return "WAIT_FAILED"; + default: return "Unknown WAIT_RESULT value."; + } + } + + /// + /// Returns integer representation by WAIT_RESULT name. + /// + public static /*WAIT_RESULT*/int fromName(String wAIT_RESULTName) + { + if ("WAIT_OBJECT_0".equals(wAIT_RESULTName)) return WAIT_OBJECT_0; + if ("WAIT_ABANDONED".equals(wAIT_RESULTName)) return WAIT_ABANDONED; + if ("WAIT_TIMEOUT".equals(wAIT_RESULTName)) return WAIT_TIMEOUT; + if ("WAIT_FAILED".equals(wAIT_RESULTName)) return WAIT_FAILED; + throw new IllegalArgumentException("Unknown WAIT_RESULT name."); + } + + /// + /// Returns array of WAIT_RESULT values. + /// + public static int[] getValues() + { + return new int[] + { + WAIT_OBJECT_0, + WAIT_ABANDONED, + WAIT_TIMEOUT, + WAIT_FAILED, + }; + } + + public static final int length = 4; +} + +//ExStart:ActivePrintPreviewDialogClass +class ActivePrintPreviewDialog extends PrintPreviewDialog +{ + /// + /// Brings the Print Preview dialog on top when it is initially displayed. + /// + protected /*override*/ void onShown(EventArgs e) + { + Activate(); + super.OnShown(e); + } +} +//ExEnd:ActivePrintPreviewDialogClass + diff --git a/Examples/DocsExamples/JavaPorting/Rendering_and_printing/RenderingShapes.java b/Examples/DocsExamples/JavaPorting/Rendering_and_printing/RenderingShapes.java new file mode 100644 index 00000000..4c4e2e46 --- /dev/null +++ b/Examples/DocsExamples/JavaPorting/Rendering_and_printing/RenderingShapes.java @@ -0,0 +1,299 @@ +package DocsExamples.Rendering_and_Printing; + +// ********* THIS FILE IS AUTO PORTED ********* + +import DocsExamples.DocsExamplesBase; +import org.testng.annotations.Test; +import com.aspose.words.Document; +import com.aspose.words.Shape; +import com.aspose.words.NodeType; +import com.aspose.words.ShapeRenderer; +import com.aspose.words.ImageSaveOptions; +import com.aspose.words.SaveFormat; +import com.aspose.words.ImageColorMode; +import com.aspose.ms.System.IO.FileStream; +import com.aspose.ms.System.IO.FileMode; +import com.aspose.ms.System.Drawing.msSize; +import java.awt.image.BufferedImage; +import java.awt.Graphics2D; +import com.aspose.words.Cell; +import com.aspose.words.Row; +import com.aspose.words.DocumentBuilder; +import com.aspose.words.ShapeType; +import com.aspose.ms.System.Drawing.msColor; +import java.awt.Color; +import com.aspose.words.CompositeNode; +import com.aspose.words.ImportFormatMode; +import com.aspose.words.Body; +import com.aspose.words.HeaderFooter; +import com.aspose.words.Node; +import com.aspose.words.InlineStory; +import com.aspose.words.Story; +import com.aspose.words.ShapeBase; +import com.aspose.words.LayoutEnumerator; +import com.aspose.ms.System.Drawing.RectangleF; +import com.aspose.words.LayoutEntityType; + + +class RenderingShapes extends DocsExamplesBase +{ + @Test + public void renderShapeAsEmf() throws Exception + { + Document doc = new Document(getMyDir() + "Rendering.docx"); + // Retrieve the target shape from the document. + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + //ExStart:RenderShapeAsEmf + //GistId:7fc867ac8ef1b729b6f70580fbc5b3f9 + ShapeRenderer render = shape.getShapeRenderer(); + ImageSaveOptions imageOptions = new ImageSaveOptions(SaveFormat.EMF); + { + imageOptions.setScale(1.5f); + } + + render.save(getArtifactsDir() + "RenderShape.RenderShapeAsEmf.emf", imageOptions); + //ExEnd:RenderShapeAsEmf + } + + @Test + public void renderShapeAsJpeg() throws Exception + { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + + //ExStart:RenderShapeAsJpeg + //GistId:7fc867ac8ef1b729b6f70580fbc5b3f9 + ShapeRenderer render = new ShapeRenderer(shape); + ImageSaveOptions imageOptions = new ImageSaveOptions(SaveFormat.JPEG); + { + // Output the image in gray scale + imageOptions.setImageColorMode(ImageColorMode.GRAYSCALE); + // Reduce the brightness a bit (default is 0.5f) + imageOptions.setImageBrightness(0.45f); + } + + FileStream stream = new FileStream(getArtifactsDir() + "RenderShape.RenderShapeAsJpeg.jpg", FileMode.CREATE); + try /*JAVA: was using*/ + { + render.save(stream, imageOptions); + } + finally { if (stream != null) stream.close(); } + //ExEnd:RenderShapeAsJpeg + } + @Test + //ExStart:RenderShapeToGraphics + //GistId:7fc867ac8ef1b729b6f70580fbc5b3f9 + public void renderShapeToGraphics() throws Exception + { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + ShapeRenderer render = shape.getShapeRenderer(); + + // Find the size that the shape will be rendered to at the specified scale and resolution. + /*Size*/long shapeSizeInPixels = render.getSizeInPixelsInternal(1.0f, 96.0f); + // Rotating the shape may result in clipping as the image canvas is too small. Find the longest side + // and make sure that the graphics canvas is large enough to compensate for this. + int maxSide = Math.max(msSize.getWidth(shapeSizeInPixels), msSize.getHeight(shapeSizeInPixels)); + + BufferedImage image = new BufferedImage((int) (maxSide * 1.25), (int) (maxSide * 1.25)); + try /*JAVA: was using*/ + { + // Rendering to a graphics object means we can specify settings and transformations to be applied to the rendered shape. + // In our case we will rotate the rendered shape. + Graphics2D graphics = Graphics2D.FromImage(image); + try /*JAVA: was using*/ + { + // Clear the shape with the background color of the document. + graphics.Clear(shape.getDocument().getPageColor()); + // Center the rotation using the translation method below. + graphics.TranslateTransform((float) image.getWidth() / 8f, (float) image.getHeight() / 2f); + // Rotate the image by 45 degrees. + graphics.RotateTransform(45f); + // Undo the translation. + graphics.TranslateTransform(-(float) image.getWidth() / 8f, -(float) image.getHeight() / 2f); + + // Render the shape onto the graphics object. + render.renderToSize(graphics, 0f, 0f, msSize.getWidth(shapeSizeInPixels), msSize.getHeight(shapeSizeInPixels)); + } + finally { if (graphics != null) graphics.close(); } + + image.Save(getArtifactsDir() + "RenderShape.RenderShapeToGraphics.png", ImageFormat.Png); + } + finally { if (image != null) image.close(); } + } + //ExEnd:RenderShapeToGraphics + + @Test + public void findShapeSizes() throws Exception + { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); + + //ExStart:FindShapeSizes + //GistId:7fc867ac8ef1b729b6f70580fbc5b3f9 + /*Size*/long shapeRenderedSize = shape.getShapeRenderer().getSizeInPixelsInternal(1.0f, 96.0f); + + BufferedImage image = new BufferedImage(msSize.getWidth(shapeRenderedSize), msSize.getHeight(shapeRenderedSize)); + try /*JAVA: was using*/ + { + Graphics2D graphics = Graphics2D.FromImage(image); + try /*JAVA: was using*/ + { + // Render shape onto the graphics object using the RenderToScale + // or RenderToSize methods of ShapeRenderer class. + } + finally { if (graphics != null) graphics.close(); } + } + finally { if (image != null) image.close(); } + //ExEnd:FindShapeSizes + } + + @Test + public void renderCellToImage() throws Exception + { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + //ExStart:RenderCellToImage + Cell cell = (Cell)doc.getChild(NodeType.CELL, 2, true); + Document tmp = convertToImage(doc, cell); + tmp.save(getArtifactsDir() + "RenderShape.RenderCellToImage.png"); + //ExEnd:RenderCellToImage + } + + @Test + public void renderRowToImage() throws Exception + { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + //ExStart:RenderRowToImage + Row row = (Row) doc.getChild(NodeType.ROW, 0, true); + Document tmp = convertToImage(doc, row); + tmp.save(getArtifactsDir() + "RenderShape.RenderRowToImage.png"); + //ExEnd:RenderRowToImage + } + + @Test + public void renderParagraphToImage() throws Exception + { + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + //ExStart:RenderParagraphToImage + Shape textBoxShape = builder.insertShape(ShapeType.TEXT_BOX, 150.0, 100.0); + + builder.moveTo(textBoxShape.getLastParagraph()); + builder.write("Vertical text"); + + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.PNG); + { + options.setPaperColor(msColor.getLightPink()); + } + + Document tmp = convertToImage(doc, textBoxShape.getLastParagraph()); + tmp.save(getArtifactsDir() + "RenderShape.RenderParagraphToImage.png"); + //ExEnd:RenderParagraphToImage + } + + @Test + public void renderShapeImage() throws Exception + { + Document doc = new Document(getMyDir() + "Rendering.docx"); + + Shape shape = (Shape) doc.getChild(NodeType.SHAPE, 0, true); + //ExStart:RenderShapeImage + //GistId:7fc867ac8ef1b729b6f70580fbc5b3f9 + shape.getShapeRenderer().save(getArtifactsDir() + "RenderShape.RenderShapeImage.jpg", new ImageSaveOptions(SaveFormat.JPEG)); + //ExEnd:RenderShapeImage + } + + /// + /// Renders any node in a document into an image. + /// + /// The current document. + /// The node to render. + private static Document convertToImage(Document doc, CompositeNode node) throws Exception + { + Document tmp = createTemporaryDocument(doc, node); + appendNodeContent(tmp, node); + adjustDocumentLayout(tmp); + return tmp; + } + + /// + /// Creates a temporary document for further rendering. + /// + private static Document createTemporaryDocument(Document doc, CompositeNode node) + { + Document tmp = (Document)doc.deepClone(false); + tmp.getSections().add(tmp.importNode(node.getAncestor(NodeType.SECTION), false, ImportFormatMode.USE_DESTINATION_STYLES)); + tmp.getFirstSection().appendChild(new Body(tmp)); + tmp.getFirstSection().getPageSetup().setTopMargin(0.0); + tmp.getFirstSection().getPageSetup().setBottomMargin(0.0); + + return tmp; + } + + /// + /// Adds a node to a temporary document. + /// + private static void appendNodeContent(Document tmp, CompositeNode node) + { + if (node instanceof HeaderFooter headerFooter) + for (Node hfNode : headerFooter.GetChildNodes(NodeType.ANY, false) !!Autoporter error: Undefined expression type ) + tmp.getFirstSection().getBody().appendChild(tmp.importNode(hfNode, true, ImportFormatMode.USE_DESTINATION_STYLES)); + else + appendNonHeaderFooterContent(tmp, node); + } + + private static void appendNonHeaderFooterContent(Document tmp, CompositeNode node) + { + Node parentNode = node.getParentNode(); + while (!(parentNode instanceof InlineStory || parentNode instanceof Story || parentNode instanceof ShapeBase)) + { + CompositeNode parent = (CompositeNode)parentNode.deepClone(false); + parent.appendChild(node.deepClone(true)); + node = parent; + + parentNode = parentNode.getParentNode(); + } + + tmp.getFirstSection().getBody().appendChild(tmp.importNode(node, true, ImportFormatMode.USE_DESTINATION_STYLES)); + } + + /// + /// Adjusts the layout of the document to fit the content area. + /// + private static void adjustDocumentLayout(Document tmp) throws Exception + { + LayoutEnumerator enumerator = new LayoutEnumerator(tmp); + RectangleF rect = RectangleF.Empty; + rect = calculateVisibleRect(enumerator, rect); + + tmp.getFirstSection().getPageSetup().setPageHeight(rect.getHeight()); + tmp.updatePageLayout(); + } + + /// + /// Calculates the visible area of the content. + /// + private static RectangleF calculateVisibleRect(LayoutEnumerator enumerator, RectangleF rect) throws Exception + { + RectangleF result = rect; + do + { + if (enumerator.moveFirstChild()) + { + if (enumerator.getType() == LayoutEntityType.LINE || enumerator.getType() == LayoutEntityType.SPAN) + result = result.isEmpty() ? enumerator.getRectangleInternal() : RectangleF.union(result, enumerator.getRectangleInternal()); + result = calculateVisibleRect(enumerator, result); + enumerator.moveParent(); + } + } while (enumerator.moveNext()); + + return result; + } +} diff --git a/Examples/README.md b/Examples/README.md deleted file mode 100644 index 1e448744..00000000 --- a/Examples/README.md +++ /dev/null @@ -1,7 +0,0 @@ -##Aspose.Words for Java Examples - -This directory contains Java examples for [Aspose.Words for Java](http://www.aspose.com/java/word-component.aspx). - -##How to use the Examples? - -Clone or Download the ZIP and extract the contents to your local hard drive. This project uses Maven build system and can be opened in any modern IDE like IntelliJ IDEA, Eclipse or NetBeans. For more details, visit our [Documentation website](http://www.aspose.com/docs/display/wordsjava/How+to+Run+the+Examples). diff --git a/Examples/pom.xml b/Examples/pom.xml deleted file mode 100644 index 0466b683..00000000 --- a/Examples/pom.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - 4.0.0 - com.aspose - words-java-examples - 1.0-SNAPSHOT - jar - - 1.7 - 1.7 - - - - com.aspose - aspose-words - 16.11.0 - jdk16 - - - com.aspose - aspose-email - 6.8.0 - jdk16 - - - com.aspose - aspose-barcode - 8.0.0 - - - javax.media.jai - com.springsource.javax.media.jai.core - 1.1.3 - - - net.sf.ucanaccess - ucanaccess - 3.0.6 - - - - - aspose-maven-repository - http://maven.aspose.com/repository/repo/ - - - com.springsource.repository.bundles.external - SpringSource Enterprise Bundle Repository - External Bundle Releases - http://repository.springsource.com/maven/bundles/external - - - diff --git a/Examples/src/main/java/com/aspose/words/examples/Utils.java b/Examples/src/main/java/com/aspose/words/examples/Utils.java deleted file mode 100644 index ee0f4d84..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/Utils.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.aspose.words.examples; -import java.io.File; - -public class Utils { - - public static String getSharedDataDir(Class c) { - File dir = new File(System.getProperty("user.dir")); - dir = new File(dir, "src"); - dir = new File(dir, "main"); - dir = new File(dir, "resources"); - - return dir.toString() + File.separator; - } - - public static String getDataDir(Class c) { - File dir = new File(System.getProperty("user.dir")); - dir = new File(dir, "src"); - dir = new File(dir, "main"); - dir = new File(dir, "resources"); - - for (String s : c.getName().split("\\.")) { - dir = new File(dir, s); - if (dir.isDirectory() == false) - dir.mkdir(); - } - System.out.println("Using data directory: " + dir.toString()); - return dir.toString() + File.separator; - } - - public static void applyALicense() throws Exception { - String dataDir = getSharedDataDir(Utils.class) + "License/"; - com.aspose.words.License license = new com.aspose.words.License(); - license.setLicense(dataDir + "Aspose.Words.Java.lic"); - } - - public static String GetOutputFilePath(String inputFilePath) - { - String extension = ""; - int i = inputFilePath.lastIndexOf('.'); - if (i > 0) { - extension = inputFilePath.substring(i+1); - } - if (inputFilePath.contains(".")) - { - inputFilePath = inputFilePath.substring(0, inputFilePath.lastIndexOf("."));} - - return inputFilePath + "_out_." + extension; - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/document_object_model/AccessParentNode.java b/Examples/src/main/java/com/aspose/words/examples/document_object_model/AccessParentNode.java deleted file mode 100644 index 1feebb6f..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/document_object_model/AccessParentNode.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.aspose.words.examples.document_object_model; - -import com.aspose.words.Document; -import com.aspose.words.Node; - -public class AccessParentNode { - - public static void main(String[] args) throws Exception { - // Create a new empty document. It has one section. - Document doc = new Document(); - // The section is the first child node of the document. - Node section = doc.getFirstChild(); - // The section's parent node is the document. - System.out.println("Section parent is the document: " + (doc == section.getParentNode())); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/document_object_model/ChildNodes.java b/Examples/src/main/java/com/aspose/words/examples/document_object_model/ChildNodes.java deleted file mode 100644 index cdf75b0d..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/document_object_model/ChildNodes.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.aspose.words.examples.document_object_model; - -import com.aspose.words.Document; -import com.aspose.words.Node; -import com.aspose.words.NodeCollection; -import com.aspose.words.NodeType; -import com.aspose.words.Paragraph; -import com.aspose.words.Run; -import com.aspose.words.examples.Utils; - -public class ChildNodes { - - public static void main(String[] args) throws Exception { - String dataDir = Utils.getSharedDataDir(ChildNodes.class) + "DocumentObjectModel/"; - - enumerateChildrenOfACompositeNodeUsingEnumeratorProvidedByChildNodesCollection(dataDir); - enumerateChildrenOfACompositeNodeUsingIndexedAccess(dataDir); - } - - public static void enumerateChildrenOfACompositeNodeUsingEnumeratorProvidedByChildNodesCollection(String dataDir) throws Exception { - - Document doc = new Document(dataDir + "Document.doc"); - Paragraph paragraph = (Paragraph)doc.getChild(NodeType.PARAGRAPH, 0, true); - - NodeCollection children = paragraph.getChildNodes(); - for (Node child : (Iterable) children) { - // Paragraph may contain children of various types such as runs, shapes and so on. - if (child.getNodeType() == NodeType.RUN) { - // Say we found the node that we want, do something useful. - Run run = (Run)child; - System.out.println(run.getText()); - } - } - } - - public static void enumerateChildrenOfACompositeNodeUsingIndexedAccess(String dataDir) throws Exception { - - Document doc = new Document(dataDir + "Document.doc"); - Paragraph paragraph = (Paragraph)doc.getChild(NodeType.PARAGRAPH, 0, true); - - NodeCollection children = paragraph.getChildNodes(); - for (int i = 0; i < children.getCount(); i++) { - Node child = children.get(i); - - // Paragraph may contain children of various types such as runs, shapes and so on. - if (child.getNodeType() == NodeType.RUN) { - // Say we found the node that we want, do something useful. - Run run = (Run)child; - System.out.println(run.getText()); - } - } - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/document_object_model/CreateAndAddParagraphNode.java b/Examples/src/main/java/com/aspose/words/examples/document_object_model/CreateAndAddParagraphNode.java deleted file mode 100644 index 311658c5..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/document_object_model/CreateAndAddParagraphNode.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.aspose.words.examples.document_object_model; - -import com.aspose.words.Document; -import com.aspose.words.Paragraph; -import com.aspose.words.Section; - -public class CreateAndAddParagraphNode { - - public static void main(String[] args) throws Exception { - Document doc = new Document(); - Paragraph para = new Paragraph(doc); - Section section = doc.getLastSection(); - section.getBody().appendChild(para); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/document_object_model/GetNodeType.java b/Examples/src/main/java/com/aspose/words/examples/document_object_model/GetNodeType.java deleted file mode 100644 index a37851f3..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/document_object_model/GetNodeType.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.aspose.words.examples.document_object_model; - -import com.aspose.words.Document; - -public class GetNodeType { - - public static void main(String[] args) throws Exception { - Document doc = new Document(); - // Returns NodeType.Document - int type = doc.getNodeType(); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/document_object_model/OwnerDocument.java b/Examples/src/main/java/com/aspose/words/examples/document_object_model/OwnerDocument.java deleted file mode 100644 index f67885bc..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/document_object_model/OwnerDocument.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.aspose.words.examples.document_object_model; - -import com.aspose.words.Document; -import com.aspose.words.Paragraph; - -public class OwnerDocument { - - public static void main(String[] args) throws Exception { - // Open a file from disk. - Document doc = new Document(); - - // Creating a new node of any type requires a document passed into the constructor. - Paragraph para = new Paragraph(doc); - - // The new paragraph node does not yet have a parent. - System.out.println("Paragraph has no parent node: " + (para.getParentNode() == null)); - - // But the paragraph node knows its document. - System.out.println("Both nodes' documents are the same: " + (para.getDocument() == doc)); - - // The fact that a node always belongs to a document allows us to access and modify - // properties that reference the document-wide data such as styles or lists. - para.getParagraphFormat().setStyleName("Heading 1"); - - // Now add the paragraph to the main text of the first section. - doc.getFirstSection().getBody().appendChild(para); - - // The paragraph node is now a child of the Body node. - System.out.println("Paragraph has a parent node: " + (para.getParentNode() != null)); - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/document_object_model/SiblingNodes.java b/Examples/src/main/java/com/aspose/words/examples/document_object_model/SiblingNodes.java deleted file mode 100644 index 712428a8..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/document_object_model/SiblingNodes.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.aspose.words.examples.document_object_model; - -import com.aspose.words.CompositeNode; -import com.aspose.words.Document; -import com.aspose.words.Node; -import com.aspose.words.examples.Utils; - -public class SiblingNodes { - - public static void main(String[] args) throws Exception { - String dataDir = Utils.getSharedDataDir(ChildNodes.class) + "DocumentObjectModel/"; - recurseAllNodes(dataDir); - } - - public static void recurseAllNodes(String dataDir) throws Exception { - // Open a document - Document doc = new Document(dataDir + "Node.RecurseAllNodes.doc"); - // Invoke the recursive function that will walk the tree. - traverseAllNodes(doc); - } - - /** - * A simple function that will walk through all children of a specified node - * recursively and print the type of each node to the screen. - */ - public static void traverseAllNodes(CompositeNode parentNode) throws Exception { - // This is the most efficient way to loop through immediate children of a node. - for (Node childNode = parentNode.getFirstChild(); childNode != null; childNode = childNode.getNextSibling()) { - // Do some useful work. - System.out.println(Node.nodeTypeToString(childNode.getNodeType())); - - // Recurse into the node if it is a composite node. - if (childNode.isComposite()) - traverseAllNodes((CompositeNode) childNode); - } - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/document_object_model/TypedAccessToChildrenAndParent.java b/Examples/src/main/java/com/aspose/words/examples/document_object_model/TypedAccessToChildrenAndParent.java deleted file mode 100644 index a97f8e56..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/document_object_model/TypedAccessToChildrenAndParent.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.aspose.words.examples.document_object_model; - -import com.aspose.words.Body; -import com.aspose.words.Document; -import com.aspose.words.Section; -import com.aspose.words.Table; -import com.aspose.words.TableCollection; - -public class TypedAccessToChildrenAndParent { - - public static void main(String[] args) throws Exception { - Document doc = new Document(); - - // Quick typed access to the first child Section node of the Document. - Section section = doc.getFirstSection(); - - // Quick typed access to the Body child node of the Section. - Body body = section.getBody(); - - // Quick typed access to all Table child nodes contained in the Body. - TableCollection tables = body.getTables(); - - for (Table table : tables) { - // Quick typed access to the first row of the table. - if (table.getFirstRow() != null) - table.getFirstRow().remove(); - - // Quick typed access to the last row of the table. - if (table.getLastRow() != null) - table.getLastRow().remove(); - } - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/linq/BubbleChart.java b/Examples/src/main/java/com/aspose/words/examples/linq/BubbleChart.java deleted file mode 100644 index 17eb77ad..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/linq/BubbleChart.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.aspose.words.examples.linq; - -import com.aspose.words.Document; -import com.aspose.words.ReportingEngine; -import com.aspose.words.examples.Utils; - -public class BubbleChart { - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - - String dataDir = Utils.getDataDir(BubbleChart.class); - - String fileName = "BubbleChart.docx"; - // Load the template document. - Document doc = new Document(dataDir + fileName); - - // Create a Reporting Engine. - ReportingEngine engine = new ReportingEngine(); - - // Execute the build report. - engine.buildReport(doc, Common.GetContracts(), "contracts"); - - dataDir = dataDir + Utils.GetOutputFilePath(fileName); - - // Save the finished document to disk. - doc.save(dataDir); - - System.out.println("\nBubble chart template document is populated with the data about managers.\nFile saved at " + dataDir); - - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/linq/BulletedList.java b/Examples/src/main/java/com/aspose/words/examples/linq/BulletedList.java deleted file mode 100644 index 395d5996..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/linq/BulletedList.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.aspose.words.examples.linq; -import com.aspose.words.*; -import com.aspose.words.examples.Utils; -import java.util.*; -public class BulletedList { - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(BulletedList.class); - - String fileName = "BulletedList.doc"; - // Load the template document. - Document doc = new Document(dataDir + fileName); - - // Create a Reporting Engine. - ReportingEngine engine = new ReportingEngine(); - - // Execute the build report. - // engine.getKnownTypes().add(DateUtil.class); - engine.buildReport(doc, Common.GetClients()); - - dataDir = dataDir + Utils.GetOutputFilePath(fileName); - - // Save the finished document to disk. - doc.save(dataDir); - - - System.out.println("\nBulleted list template document is populated with the data about clients.\nFile saved at " + dataDir); - - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/linq/ChartWithFilteringGroupingOrdering.java b/Examples/src/main/java/com/aspose/words/examples/linq/ChartWithFilteringGroupingOrdering.java deleted file mode 100644 index dc88f9e5..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/linq/ChartWithFilteringGroupingOrdering.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.aspose.words.examples.linq; - -import com.aspose.words.Document; -import com.aspose.words.ReportingEngine; -import com.aspose.words.examples.Utils; - -public class ChartWithFilteringGroupingOrdering { - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - - String dataDir = Utils.getDataDir(ChartWithFilteringGroupingOrdering.class); - - String fileName = "ChartWithFilteringGroupingOrdering.docx"; - // Load the template document. - Document doc = new Document(dataDir + fileName); - - // Create a Reporting Engine. - ReportingEngine engine = new ReportingEngine(); - - // Execute the build report. - engine.buildReport(doc, Common.GetContracts(), "contracts"); - - dataDir = dataDir + Utils.GetOutputFilePath(fileName); - - // Save the finished document to disk. - doc.save(dataDir); - - // System.out.println("\nBubble chart template document is populated with the data about managers.\nFile saved at " + dataDir); - - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/linq/Client.java b/Examples/src/main/java/com/aspose/words/examples/linq/Client.java deleted file mode 100644 index 7cf76afd..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/linq/Client.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.aspose.words.examples.linq; -public class Client -{ - private String Name; - public final String getName() - { - return Name; - } - public final void setName(String value) - { - Name = value; - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/linq/Common.java b/Examples/src/main/java/com/aspose/words/examples/linq/Common.java deleted file mode 100644 index e758cdb1..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/linq/Common.java +++ /dev/null @@ -1,276 +0,0 @@ -package com.aspose.words.examples.linq; -import java.io.File; -import java.io.FileInputStream; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; -import com.aspose.words.net.System.Data.DataRow; -import com.aspose.words.net.System.Data.DataSet; -import com.aspose.words.net.System.Data.DataTable; - -import java.sql.*; -import java.util.*; -import java.util.Date; - -public class Common { - public static List managers = new ArrayList(); - - /// - /// Return first manager from Managers which is an enumeration of instances of the Manager class. - /// - public static Manager GetManager(){ - for (Manager manager : GetManagers()) { - return manager; - } - return null; - } - - /// - /// Return an dataset of the Client class. - /// - public static DataSet GetClients() throws Exception - { - // Create a new data set - DataSet dataSet = new DataSet("DS"); - - // Add a new table to store clients - DataTable dt = new DataTable("clients"); - - // Add columns - dt.getColumns().add("Name"); - dataSet.getTables().add(dt); - - // Populate the data in table - for (Manager manager : GetManagers()) { - List listOfContracts = manager.getContracts(); - for (Contract contract : listOfContracts) { - DataRow row = dt.newRow(); - row.set("Name", contract.getClient().getName()); - dt.getRows().add(row); - } - } - return dataSet; - } - - /// - /// Return an enumeration of instances of the Manager class. - /// - private static List GetManagers() { - - Manager manager = new Manager(); - manager.setName("John Smith"); - manager.setAge(36); - manager.setPhoto(Photo()); - - Contract contract1 = new Contract(); - Client client1 = new Client(); - client1.setName("A Company"); - contract1.setClient(client1); - contract1.setManager(manager); - contract1.setPrice(1200000); - contract1.setDate(new Date(2015, 1, 1)); - - Contract contract2 = new Contract(); - Client client2 = new Client(); - client2.setName("B Ltd."); - contract2.setClient(client2); - contract2.setManager(manager); - contract2.setPrice(750000); - contract2.setDate(new Date(2015, 4, 1)); - - Contract contract3 = new Contract(); - Client client3 = new Client(); - client3.setName("C & D"); - contract3.setClient(client3); - contract3.setManager(manager); - contract3.setPrice(350000); - contract3.setDate(new Date(2015, 7, 1)); - - ArrayList contracts = new ArrayList(); - contracts.add(contract1); - contracts.add(contract2); - contracts.add(contract3); - - manager.setContracts(contracts); - managers.add(manager); - - manager = new Manager(); - manager.setName("Tony Anderson"); - manager.setAge(37); - manager.setPhoto(Photo()); - Contract contract4 = new Contract(); - Client client4 = new Client(); - client4.setName("E Corp."); - contract4.setClient(client4); - contract4.setManager(manager); - contract4.setPrice(650000); - Date date = new Date(2015, 2, 1); - contract4.setDate(date); - Contract contract5 = new Contract(); - Client client5 = new Client(); - client5.setName("F & Partners"); - contract5.setClient(client5); - contract5.setManager(manager); - contract5.setPrice(550000); - contract5.setDate(new Date(2015, 8, 1)); - - ArrayList contracts2 = new ArrayList(); - contracts2.add(contract4); - contracts2.add(contract5); - manager.setContracts(contracts2); - managers.add(manager); - - manager = new Manager(); - manager.setName("July James"); - manager.setAge(38); - manager.setPhoto(Photo()); - Contract contract6 = new Contract(); - Client client6 = new Client(); - client6.setName("G & Co."); - contract6.setClient(client6); - contract6.setManager(manager); - contract6.setPrice(350000); - contract6.setDate(new Date(2015, 2, 1)); - Contract contract7 = new Contract(); - Client client7 = new Client(); - client7.setName("H Group"); - contract7.setClient(client7); - contract7.setManager(manager); - contract7.setPrice(250000); - contract7.setDate(new Date(2015, 5, 1)); - Contract contract8 = new Contract(); - Client client8 = new Client(); - client8.setName("I & Sons"); - contract8.setClient(client8); - contract8.setManager(manager); - contract8.setPrice(100000); - contract8.setDate(new Date(2015, 7, 1)); - Contract contract9 = new Contract(); - Client client9 = new Client(); - client9.setName("J Ent."); - contract9.setClient(client9); - contract9.setManager(manager); - contract9.setPrice(100000); - contract9.setDate(new Date(2015, 8, 1)); - - ArrayList contracts3 = new ArrayList(); - contracts3.add(contract6); - contracts3.add(contract7); - - contracts3.add(contract8); - contracts3.add(contract9); - - manager.setContracts(contracts3); - managers.add(manager); - return managers; - } - /// - /// Return an array of photo bytes. - /// - private static byte[] Photo() - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(Common.class); - File file = new File(dataDir + "photo.png"); - return readContentIntoByteArray(file); - } - private static byte[] readContentIntoByteArray(File file) - { - FileInputStream fileInputStream = null; - byte[] bFile = new byte[(int) file.length()]; - try - { - //convert file into array of bytes - fileInputStream = new FileInputStream(file); - fileInputStream.read(bFile); - fileInputStream.close(); - for (int i = 0; i < bFile.length; i++) - { - //System.out.print((char) bFile[i]); - } - } - catch (Exception e) - { - e.printStackTrace(); - } - return bFile; - } - /// - /// Return an dataset of the Contract class. - /// - public static DataSet GetContracts() throws Exception - { - // Create a new data set - DataSet ds = new DataSet("ds"); - - // Add a new table to store contracts - DataTable dtContracts = new DataTable("Contracts"); - - // Add a new table to store managers - DataTable dtManagers = new DataTable("Managers"); - - // Add a new table to store clients - DataTable dtClients = new DataTable("Clients"); - - // Add columns to Managers table - dtManagers.getColumns().add("Id", int.class); - dtManagers.getColumns().add("Name"); - dtManagers.getColumns().add("Age", int.class); - dtManagers.getColumns().add("Photo", byte[].class); - ds.getTables().add(dtManagers); - - // Add columns to Contracts table - dtContracts.getColumns().add("Id", int.class); - dtContracts.getColumns().add("ClientId", int.class); - dtContracts.getColumns().add("ManagerId", int.class); - dtContracts.getColumns().add("Price", float.class); - dtContracts.getColumns().add("Date", Date.class); - ds.getTables().add(dtContracts); - - // Add columns to Clients table - dtClients.getColumns().add("Id", int.class); - dtClients.getColumns().add("Name"); - ds.getTables().add(dtClients); - ds.getRelations().add(dtClients,dtContracts, "Id","ClientId"); - ds.getRelations().add(dtManagers,dtContracts, "Id","ManagerId"); - - - int managerCounter = 1; - int contractCounter =1; - int clientCounter = 1; - for (Manager manager : GetManagers()) { - // Add data row to managers table. - DataRow managerRow = dtManagers.newRow(); - managerRow.set("Id", managerCounter); - managerRow.set("Name", manager.getName()); - managerRow.set("Age", manager.getAge()); - managerRow.set("Photo", manager.getPhoto()); - dtManagers.getRows().add(managerRow); - - for (Contract contract : manager.getContracts()) { - DataRow contractRow = dtContracts.newRow(); - DataRow clientRow = dtClients.newRow(); - - clientRow.set("Id", clientCounter); - clientRow.set("Name", contract.getClient().getName()); - dtClients.getRows().add(clientRow); - - contractRow.set("Id", contractCounter); - contractRow.set("ClientId", clientCounter); - contractRow.set("ManagerId", managerCounter); - contractRow.set("Price", contract.getPrice()); - contractRow.set("Date", contract.getDate()); - dtContracts.getRows().add(contractRow); - clientCounter += 1; - contractCounter += 1; - - - } - managerCounter += 1; - } - return ds; - } - - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/linq/CommonList.java b/Examples/src/main/java/com/aspose/words/examples/linq/CommonList.java deleted file mode 100644 index dd6c0e1f..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/linq/CommonList.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.aspose.words.examples.linq; -import com.aspose.words.*; -import com.aspose.words.examples.Utils; -import java.util.*; -public class CommonList { - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(CommonList.class); - - String fileName = "CommonList.doc"; - // Load the template document. - Document doc = new Document(dataDir + fileName); - - // Create a Reporting Engine. - ReportingEngine engine = new ReportingEngine(); - - // Execute the build report. - // engine.getKnownTypes().add(DateUtil.class); - engine.buildReport(doc, Common.GetContracts()); - - dataDir = dataDir + Utils.GetOutputFilePath(fileName); - - // Save the finished document to disk. - doc.save(dataDir); - - - System.out.println("\nCommon list template document is populated with the data about managers.\nFile saved at " + dataDir); - - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/linq/CommonMasterDetail.java b/Examples/src/main/java/com/aspose/words/examples/linq/CommonMasterDetail.java deleted file mode 100644 index b2786ba7..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/linq/CommonMasterDetail.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.aspose.words.examples.linq; -import com.aspose.words.*; -import com.aspose.words.examples.Utils; -public class CommonMasterDetail { - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - - String dataDir = Utils.getDataDir(CommonMasterDetail.class); - - String fileName = "CommonMasterDetail.doc"; - // Load the template document. - Document doc = new Document(dataDir + fileName); - - // Create a Reporting Engine. - ReportingEngine engine = new ReportingEngine(); - - // Execute the build report. -// engine.getKnownTypes().add(DateUtil.class); - engine.buildReport(doc, Common.GetContracts(), "ds"); - - dataDir = dataDir + Utils.GetOutputFilePath(fileName); - - // Save the finished document to disk. - doc.save(dataDir); - - System.out.println("\nCommon master detail template document is populated with the data about managers and it's contracts.\nFile saved at " + dataDir); - - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/linq/Contract.java b/Examples/src/main/java/com/aspose/words/examples/linq/Contract.java deleted file mode 100644 index 9fab6f3d..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/linq/Contract.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.aspose.words.examples.linq; -import java.util.Date; -public class Contract -{ - private Manager Manager; - public final Manager getManager() - { - return Manager; - } - public final void setManager(Manager value) - { - Manager = value; - } - private Client Client; - public final Client getClient() - { - return Client; - } - public final void setClient(Client value) - { - Client = value; - } - private float Price; - public final float getPrice() - { - return Price; - } - public final void setPrice(float value) - { - Price = value; - } - private Date Date = new Date(); - public final Date getDate() - { - return Date; - } - public final void setDate(Date value) - { - Date = value; - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/linq/HelloWorld.java b/Examples/src/main/java/com/aspose/words/examples/linq/HelloWorld.java deleted file mode 100644 index 2547a5b1..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/linq/HelloWorld.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.aspose.words.examples.linq; -import com.aspose.words.*; -import com.aspose.words.examples.Utils; -import java.util.*; -public class HelloWorld { - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception - { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(HelloWorld.class); - - String fileName = "HelloWorld.doc"; - // Load the template document. - Document doc = new Document(dataDir + fileName); - - // Create an instance of sender class to set it's properties. - Sender sender = new Sender(); - sender.setName("LINQ Reporting Engine"); - sender.setMessage("Hello World"); - - // Create a Reporting Engine. - ReportingEngine engine = new ReportingEngine(); - - // Execute the build report. - engine.buildReport(doc, sender, "sender"); - - dataDir = dataDir + Utils.GetOutputFilePath(fileName); - - // Save the finished document to disk. - doc.save(dataDir); - - System.out.println("\nTemplate document is populated with the data about the sender.\nFile saved at " + dataDir); - - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/linq/InParagraphList.java b/Examples/src/main/java/com/aspose/words/examples/linq/InParagraphList.java deleted file mode 100644 index bed36c74..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/linq/InParagraphList.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.aspose.words.examples.linq; -import com.aspose.words.*; -import com.aspose.words.examples.Utils; -public class InParagraphList { - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - - String dataDir = Utils.getDataDir(InParagraphList.class); - - String fileName = "InParagraphList.doc"; - // Load the template document. - Document doc = new Document(dataDir + fileName); - - // Create a Reporting Engine. - ReportingEngine engine = new ReportingEngine(); - - // Execute the build report. -// engine.getKnownTypes().add(DateUtil.class); - engine.buildReport(doc, Common.GetClients()); - - dataDir = dataDir + Utils.GetOutputFilePath(fileName); - - // Save the finished document to disk. - doc.save(dataDir); - - System.out.println("\nIn-Paragraph list template document is populated with the data about clients.\nFile saved at " + dataDir); - - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/linq/InTableAlternateContent.java b/Examples/src/main/java/com/aspose/words/examples/linq/InTableAlternateContent.java deleted file mode 100644 index 055c58f1..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/linq/InTableAlternateContent.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.aspose.words.examples.linq; - -import com.aspose.words.Document; -import com.aspose.words.ReportingEngine; -import com.aspose.words.examples.Utils; - -public class InTableAlternateContent { - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - - String dataDir = Utils.getDataDir(InTableAlternateContent.class); - - String fileName = "InTableAlternateContent.doc"; - // Load the template document. - Document doc = new Document(dataDir + fileName); - - // Create a Reporting Engine. - ReportingEngine engine = new ReportingEngine(); - - // Execute the build report. - engine.buildReport(doc, Common.GetContracts(), "ds"); - - dataDir = dataDir + Utils.GetOutputFilePath(fileName); - - // Save the finished document to disk. - doc.save(dataDir); -// System.out.println("\nIn-Table list template document is populated with the data about managers.\nFile saved at " + dataDir); - - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/linq/InTableList.java b/Examples/src/main/java/com/aspose/words/examples/linq/InTableList.java deleted file mode 100644 index c1d485d1..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/linq/InTableList.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.aspose.words.examples.linq; -import com.aspose.words.*; -import com.aspose.words.examples.Utils; -public class InTableList { - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - - String dataDir = Utils.getDataDir(InTableList.class); - - String fileName = "InTableList.doc"; - // Load the template document. - Document doc = new Document(dataDir + fileName); - - // Create a Reporting Engine. - ReportingEngine engine = new ReportingEngine(); - - // Execute the build report. - engine.buildReport(doc, Common.GetContracts(), "ds"); - - dataDir = dataDir + Utils.GetOutputFilePath(fileName); - - // Save the finished document to disk. - doc.save(dataDir); - - System.out.println("\nIn-Table list template document is populated with the data about managers.\nFile saved at " + dataDir); - - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/linq/InTableMasterDetail.java b/Examples/src/main/java/com/aspose/words/examples/linq/InTableMasterDetail.java deleted file mode 100644 index 152fdf68..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/linq/InTableMasterDetail.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.aspose.words.examples.linq; -import com.aspose.words.*; -import com.aspose.words.examples.Utils; -public class InTableMasterDetail { - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - - String dataDir = Utils.getDataDir(InTableMasterDetail.class); - - String fileName = "InTableMasterDetail.doc"; - // Load the template document. - Document doc = new Document(dataDir + fileName); - - // Create a Reporting Engine. - ReportingEngine engine = new ReportingEngine(); - - // Execute the build report. -// engine.getKnownTypes().add(DateUtil.class); - engine.buildReport(doc, Common.GetContracts(), "ds"); - - dataDir = dataDir + Utils.GetOutputFilePath(fileName); - - // Save the finished document to disk. - doc.save(dataDir); - - System.out.println("\nIn-Table master detail template document is populated with the data about managers and it's contracts.\nFile saved at " + dataDir); - - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/linq/InTableRow.java b/Examples/src/main/java/com/aspose/words/examples/linq/InTableRow.java deleted file mode 100644 index 307d0868..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/linq/InTableRow.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.aspose.words.examples.linq; -import com.aspose.words.*; -import com.aspose.words.examples.Utils; -public class InTableRow { - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - - String dataDir = Utils.getDataDir(InTableRow.class); - - String fileName = "InTableList.doc"; - // Load the template document. - Document doc = new Document(dataDir + fileName); - - // Create a Reporting Engine. - ReportingEngine engine = new ReportingEngine(); - - // Execute the build report. -// engine.getKnownTypes().add(DateUtil.class); - engine.buildReport(doc, Common.GetContracts(), "ds"); - - dataDir = dataDir + Utils.GetOutputFilePath(fileName); - - // Save the finished document to disk. - doc.save(dataDir); - - System.out.println("\nIn-Table row template document is populated with the data about managers.\nFile saved at " + dataDir); - - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/linq/InTableWithFilteringGroupingSorting.java b/Examples/src/main/java/com/aspose/words/examples/linq/InTableWithFilteringGroupingSorting.java deleted file mode 100644 index c9e90a0c..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/linq/InTableWithFilteringGroupingSorting.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.aspose.words.examples.linq; - -import com.aspose.words.Document; -import com.aspose.words.ReportingEngine; -import com.aspose.words.examples.Utils; - -public class InTableWithFilteringGroupingSorting { - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - - String dataDir = Utils.getDataDir(InTableWithFilteringGroupingSorting.class); - - String fileName = "InTableWithFilteringGroupingSorting.doc"; - // Load the template document. - Document doc = new Document(dataDir + fileName); - - // Create a Reporting Engine. - ReportingEngine engine = new ReportingEngine(); - - // Execute the build report. - engine.buildReport(doc, Common.GetContracts(), "contracts"); - - dataDir = dataDir + Utils.GetOutputFilePath(fileName); - - // Save the finished document to disk. - doc.save(dataDir); - - // System.out.println("\nBubble chart template document is populated with the data about managers.\nFile saved at " + dataDir); - - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/linq/Manager.java b/Examples/src/main/java/com/aspose/words/examples/linq/Manager.java deleted file mode 100644 index 29bb0c8c..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/linq/Manager.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.aspose.words.examples.linq; -import java.util.List; -public class Manager -{ - private String Name; - public final String getName() - { - return Name; - } - public final void setName(String value) - { - Name = value; - } - private int Age; - public final int getAge() - { - return Age; - } - public final void setAge(int value) - { - Age = value; - } - private byte[] Photo; - public final byte[] getPhoto() - { - return Photo; - } - public final void setPhoto(byte[] value) - { - Photo = value; - } - private List Contracts; - public final List getContracts() - { - return Contracts; - } - public final void setContracts(List value) - { - Contracts = value; - } - - -} - diff --git a/Examples/src/main/java/com/aspose/words/examples/linq/MulticoloredNumberedList.java b/Examples/src/main/java/com/aspose/words/examples/linq/MulticoloredNumberedList.java deleted file mode 100644 index 10fcc151..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/linq/MulticoloredNumberedList.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.aspose.words.examples.linq; -import com.aspose.words.*; -import com.aspose.words.examples.Utils; -import java.util.*; -public class MulticoloredNumberedList { - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(MulticoloredNumberedList.class); - String fileName = "MulticoloredNumberedList.doc"; - // Load the template document. - Document doc = new Document(dataDir + fileName); - - // Create a Reporting Engine. - ReportingEngine engine = new ReportingEngine(); - - // Execute the build report. - engine.buildReport(doc, Common.GetClients()); - - dataDir = dataDir + Utils.GetOutputFilePath(fileName); - - // Save the finished document to disk. - doc.save(dataDir); - - System.out.println("\nMulticolored numbered list template document is populated with the data about clients.\nFile saved at " + dataDir); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/linq/NumberedList.java b/Examples/src/main/java/com/aspose/words/examples/linq/NumberedList.java deleted file mode 100644 index 922858fb..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/linq/NumberedList.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.aspose.words.examples.linq; -import com.aspose.words.*; -import com.aspose.words.examples.Utils; -import java.util.*; -public class NumberedList { - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(NumberedList.class); - String fileName = "NumberedList.doc"; - // Load the template document. - Document doc = new Document(dataDir + fileName); - - // Create a Reporting Engine. - ReportingEngine engine = new ReportingEngine(); - - // Execute the build report. - engine.buildReport(doc, Common.GetClients()); - - dataDir = dataDir + Utils.GetOutputFilePath(fileName); - - // Save the finished document to disk. - doc.save(dataDir); - - System.out.println("\nNumbered list template document is populated with the data about clients.\nFile saved at " + dataDir); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/linq/PieChart.java b/Examples/src/main/java/com/aspose/words/examples/linq/PieChart.java deleted file mode 100644 index 4a8a5e97..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/linq/PieChart.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.aspose.words.examples.linq; -import com.aspose.words.*; -import com.aspose.words.examples.Utils; -public class PieChart { - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - - String dataDir = Utils.getDataDir(PieChart.class); - - String fileName = "PieChart.docx"; - // Load the template document. - Document doc = new Document(dataDir + fileName); - - // Create a Reporting Engine. - ReportingEngine engine = new ReportingEngine(); - - // Execute the build report. - engine.buildReport(doc, Common.GetContracts(), "ds"); - - dataDir = dataDir + Utils.GetOutputFilePath(fileName); - - // Save the finished document to disk. - doc.save(dataDir); - - System.out.println("\nPie chart template document is populated with the data about managers.\nFile saved at " + dataDir); - - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/linq/ScatterChart.java b/Examples/src/main/java/com/aspose/words/examples/linq/ScatterChart.java deleted file mode 100644 index 6d3bbec1..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/linq/ScatterChart.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.aspose.words.examples.linq; -import com.aspose.words.*; -import com.aspose.words.examples.Utils; -public class ScatterChart { - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - - String dataDir = Utils.getDataDir(ScatterChart.class); - - String fileName = "ScatterChart.docx"; - // Load the template document. - Document doc = new Document(dataDir + fileName); - - // Create a Reporting Engine. - ReportingEngine engine = new ReportingEngine(); - - // Execute the build report. - engine.buildReport(doc, Common.GetContracts(), "ds"); - - dataDir = dataDir + Utils.GetOutputFilePath(fileName); - - // Save the finished document to disk. - doc.save(dataDir); - - System.out.println("\nScatter chart template document is populated with the data about contracts.\nFile saved at " + dataDir); - - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/linq/Sender.java b/Examples/src/main/java/com/aspose/words/examples/linq/Sender.java deleted file mode 100644 index 70c5981f..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/linq/Sender.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.aspose.words.examples.linq; -public class Sender { - private String Name; - public final String getName() - { - return Name; - } - public final void setName(String value) - { - Name = value; - } - private String Message; - public final String getMessage() - { - return Message; - } - public final void setMessage(String value) - { - Message = value; - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/linq/SingleRow.java b/Examples/src/main/java/com/aspose/words/examples/linq/SingleRow.java deleted file mode 100644 index 3691e34d..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/linq/SingleRow.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.aspose.words.examples.linq; -import com.aspose.words.*; -import com.aspose.words.examples.Utils; -public class SingleRow { - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(SingleRow.class); - - String fileName = "SingleRow.doc"; - // Load the template document. - Document doc = new Document(dataDir + fileName); - - // Create a Reporting Engine. - ReportingEngine engine = new ReportingEngine(); - - // Execute the build report. - engine.buildReport(doc, Common.GetManager(), "manager"); - - dataDir = dataDir + Utils.GetOutputFilePath(fileName); - - // Save the finished document to disk. - doc.save(dataDir); - - System.out.println("\nSingle row template document is populated with the data about manager.\nFile saved at " + dataDir); - - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/AccessAndVerifySignature.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/AccessAndVerifySignature.java deleted file mode 100644 index d223dbdf..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/AccessAndVerifySignature.java +++ /dev/null @@ -1,33 +0,0 @@ -/* -* Copyright 2001-2014 Aspose Pty Ltd. All Rights Reserved. -* -* This file is part of Aspose.Words. The source code in this file -* is only intended as a supplement to the documentation, and is provided -* "as is", without warranty of any kind, either expressed or implied. -*/ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.DigitalSignature; -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; -//FIXME: no input file - -public class AccessAndVerifySignature { - - // The path to the documents directory. - private static final String dataDir = Utils.getSharedDataDir(AccessAndVerifySignature.class) + "LoadingSavingAndConverting/"; - - public static void main(String[] args) throws Exception { - - // The path to the document which is to be processed. - String filePath = dataDir + "Document.Signed.docx"; - Document doc = new Document(filePath); - - for (DigitalSignature signature : doc.getDigitalSignatures()) { - System.out.println("*** Signature Found ***"); - System.out.println("Is valid: " + signature.isValid()); - System.out.println("Reason for signing: " + signature.getComments()); // This property is available in MS Word documents only. - System.out.println("Time of signing: " + signature.getSignTime()); - } - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/CheckFormat.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/CheckFormat.java deleted file mode 100644 index 16339f65..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/CheckFormat.java +++ /dev/null @@ -1,141 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.Document; -import com.aspose.words.FileFormatInfo; -import com.aspose.words.FileFormatUtil; -import com.aspose.words.LoadFormat; -import com.aspose.words.examples.Utils; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; - -public class CheckFormat { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(CheckFormat.class); - - String supportedDir = dataDir + "OutSupported" + File.separator; - String unknownDir = dataDir + "OutUnknown" + File.separator; - String encryptedDir = dataDir + "OutEncrypted" + File.separator; - String pre97Dir = dataDir + "OutPre97" + File.separator; - - File[] fileList = new java.io.File(dataDir).listFiles(); - - // Loop through all found files. - for (File file : fileList) { - if (file.isDirectory()) - continue; - - // Extract and display the file name without the path. - String nameOnly = file.getName(); - System.out.print(nameOnly); - - // Check the file format and move the file to the appropriate folder. - String fileName = file.getPath(); - FileFormatInfo info = FileFormatUtil.detectFileFormat(fileName); - - // Display the document type. - switch (info.getLoadFormat()) { - case LoadFormat.DOC: - System.out.println("\tMicrosoft Word 97-2003 document."); - break; - case LoadFormat.DOT: - System.out.println("\tMicrosoft Word 97-2003 template."); - break; - case LoadFormat.DOCX: - System.out.println("\tOffice Open XML WordprocessingML Macro-Free Document."); - break; - case LoadFormat.DOCM: - System.out.println("\tOffice Open XML WordprocessingML Macro-Enabled Document."); - break; - case LoadFormat.DOTX: - System.out.println("\tOffice Open XML WordprocessingML Macro-Free Template."); - break; - case LoadFormat.DOTM: - System.out.println("\tOffice Open XML WordprocessingML Macro-Enabled Template."); - break; - case LoadFormat.FLAT_OPC: - System.out.println("\tFlat OPC document."); - break; - case LoadFormat.RTF: - System.out.println("\tRTF format."); - break; - case LoadFormat.WORD_ML: - System.out.println("\tMicrosoft Word 2003 WordprocessingML format."); - break; - case LoadFormat.HTML: - System.out.println("\tHTML format."); - break; - case LoadFormat.MHTML: - System.out.println("\tMHTML (Web archive) format."); - break; - case LoadFormat.ODT: - System.out.println("\tOpenDocument Text."); - break; - case LoadFormat.OTT: - System.out.println("\tOpenDocument Text Template."); - break; - case LoadFormat.DOC_PRE_WORD_60: - System.out.println("\tMS Word 6 or Word 95 format."); - break; - case LoadFormat.UNKNOWN: - default: - System.out.println("\tUnknown format."); - break; - } - - // Now copy the document into the appropriate folder. - if (info.isEncrypted()) { - System.out.println("\tAn encrypted document."); - fileCopy(fileName, new File(encryptedDir, nameOnly).getPath()); - } else { - switch (info.getLoadFormat()) { - case LoadFormat.DOC_PRE_WORD_60: - fileCopy(fileName, new File(pre97Dir + nameOnly).getPath()); - break; - case LoadFormat.UNKNOWN: - fileCopy(fileName, new File(unknownDir + nameOnly).getPath()); - break; - default: - fileCopy(fileName, new File(supportedDir + nameOnly).getPath()); - break; - } - } - } - } - - private static void fileCopy(String sourceFileName, String destinationFileName) throws Exception - { - File sourceFile = new File(sourceFileName); - File destinationFile = new File(destinationFileName); - - File directoryFile = new File(destinationFile.getParent()); - if (!directoryFile.exists()) - directoryFile.mkdir(); - - FileInputStream fis = null; - FileOutputStream fos = null; - - try - { - fis = new FileInputStream(sourceFile); - fos = new FileOutputStream(destinationFile); - - byte[] buffer = new byte[8192]; - int bytesRead; - while ((bytesRead = fis.read(buffer)) != -1) - fos.write(buffer, 0, bytesRead); - } - finally - { - if (fis != null) - fis.close(); - if (fos != null) - fos.close(); - } - - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/CheckFormatCompatibility.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/CheckFormatCompatibility.java deleted file mode 100644 index 0a61870c..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/CheckFormatCompatibility.java +++ /dev/null @@ -1,139 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.FileFormatInfo; -import com.aspose.words.FileFormatUtil; -import com.aspose.words.LoadFormat; -import com.aspose.words.examples.Utils; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; - -public class CheckFormatCompatibility { - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(CheckFormatCompatibility.class); - - String supportedDir = dataDir + "OutSupported" + File.separator; - String unknownDir = dataDir + "OutUnknown" + File.separator; - String encryptedDir = dataDir + "OutEncrypted" + File.separator; - String pre97Dir = dataDir + "OutPre97" + File.separator; - - File[] fileList = new File(dataDir).listFiles(); - - // Loop through all found files. - for (File file : fileList) { - if (file.isDirectory()) - continue; - - // Extract and display the file name without the path. - String nameOnly = file.getName(); - System.out.print(nameOnly); - - // Check the file format and move the file to the appropriate folder. - String fileName = file.getPath(); - FileFormatInfo info = FileFormatUtil.detectFileFormat(fileName); - - // Display the document type. - switch (info.getLoadFormat()) { - case LoadFormat.DOC: - System.out.println("\tMicrosoft Word 97-2003 document."); - break; - case LoadFormat.DOT: - System.out.println("\tMicrosoft Word 97-2003 template."); - break; - case LoadFormat.DOCX: - System.out.println("\tOffice Open XML WordprocessingML Macro-Free Document."); - break; - case LoadFormat.DOCM: - System.out.println("\tOffice Open XML WordprocessingML Macro-Enabled Document."); - break; - case LoadFormat.DOTX: - System.out.println("\tOffice Open XML WordprocessingML Macro-Free Template."); - break; - case LoadFormat.DOTM: - System.out.println("\tOffice Open XML WordprocessingML Macro-Enabled Template."); - break; - case LoadFormat.FLAT_OPC: - System.out.println("\tFlat OPC document."); - break; - case LoadFormat.RTF: - System.out.println("\tRTF format."); - break; - case LoadFormat.WORD_ML: - System.out.println("\tMicrosoft Word 2003 WordprocessingML format."); - break; - case LoadFormat.HTML: - System.out.println("\tHTML format."); - break; - case LoadFormat.MHTML: - System.out.println("\tMHTML (Web archive) format."); - break; - case LoadFormat.ODT: - System.out.println("\tOpenDocument Text."); - break; - case LoadFormat.OTT: - System.out.println("\tOpenDocument Text Template."); - break; - case LoadFormat.DOC_PRE_WORD_60: - System.out.println("\tMS Word 6 or Word 95 format."); - break; - case LoadFormat.UNKNOWN: - default: - System.out.println("\tUnknown format."); - break; - } - - // Now copy the document into the appropriate folder. - if (info.isEncrypted()) { - System.out.println("\tAn encrypted document."); - fileCopy(fileName, new File(encryptedDir, nameOnly).getPath()); - } else { - switch (info.getLoadFormat()) { - case LoadFormat.DOC_PRE_WORD_60: - fileCopy(fileName, new File(pre97Dir + nameOnly).getPath()); - break; - case LoadFormat.UNKNOWN: - fileCopy(fileName, new File(unknownDir + nameOnly).getPath()); - break; - default: - fileCopy(fileName, new File(supportedDir + nameOnly).getPath()); - break; - } - } - } - } - - private static void fileCopy(String sourceFileName, String destinationFileName) throws Exception - { - File sourceFile = new File(sourceFileName); - File destinationFile = new File(destinationFileName); - - File directoryFile = new File(destinationFile.getParent()); - if (!directoryFile.exists()) - directoryFile.mkdir(); - - FileInputStream fis = null; - FileOutputStream fos = null; - - try - { - fis = new FileInputStream(sourceFile); - fos = new FileOutputStream(destinationFile); - - byte[] buffer = new byte[8192]; - int bytesRead; - while ((bytesRead = fis.read(buffer)) != -1) - fos.write(buffer, 0, bytesRead); - } - finally - { - if (fis != null) - fis.close(); - if (fos != null) - fos.close(); - } - - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/ConvertADocumentToMHTMLAndEmail.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/ConvertADocumentToMHTMLAndEmail.java deleted file mode 100644 index ab354357..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/ConvertADocumentToMHTMLAndEmail.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; - -import com.aspose.email.MailAddress; -import com.aspose.email.MailMessage; -import com.aspose.email.SaveOptions; -import com.aspose.words.Document; -import com.aspose.words.SaveFormat; -import com.aspose.words.examples.Utils; - -public class ConvertADocumentToMHTMLAndEmail { - - public static void main(String[] args) throws Exception { - String dataDir = Utils.getSharedDataDir(ConvertADocumentToMHTMLAndEmail.class) + "LoadingSavingAndConverting/"; - - // Load the document into Aspose.Words. - String srcFileName = dataDir + "Document.doc"; - Document doc = new Document(srcFileName); - - // Save to an output stream in MHTML format. - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - doc.save(outputStream, SaveFormat.MHTML); - - // Load the MHTML stream back into an input stream for use with Aspose.Email. - ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); - - // Create an Aspose.Email MIME email message from the stream. - MailMessage message = MailMessage.load(inputStream); - message.setFrom(new MailAddress("your_from@email.com")); - message.getTo().add("your_to@email.com"); - message.setSubject("Aspose.Words + Aspose.Email MHTML Test Message"); - - // Save the message in Outlook MSG format. - message.save(dataDir + "Message Out.msg", SaveOptions.getDefaultMsg()); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/ConvertDocumentToByte.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/ConvertDocumentToByte.java deleted file mode 100644 index 2c3fcd39..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/ConvertDocumentToByte.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; -import com.aspose.words.*; -import java.io.*; - -public class ConvertDocumentToByte -{ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(ConvertDocumentToByte.class); - - // Load the document. - Document doc = new Document(dataDir + "Test File (doc).doc"); - - // Create a new memory stream. - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - // Save the document to stream. - doc.save(outStream, SaveFormat.DOCX); - - // Convert the document to byte form. - byte[] docBytes = outStream.toByteArray(); - - // The bytes are now ready to be stored/transmitted. - - // Now reverse the steps to load the bytes back into a document object. - ByteArrayInputStream inStream = new ByteArrayInputStream(docBytes); - - // Load the stream into a new document object. - Document loadDoc = new Document(inStream); - System.out.println("Document converted to byte array successfully."); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/ConvertDocumentToEPUB.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/ConvertDocumentToEPUB.java deleted file mode 100644 index e8a3e7f5..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/ConvertDocumentToEPUB.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; -import com.aspose.words.*; -import java.nio.charset.Charset; - -public class ConvertDocumentToEPUB -{ - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ConvertDocumentToEPUB.class); - - // Open an existing document from disk. - Document doc = new Document(dataDir + "Document.EpubConversion.doc"); - - // Save the document in EPUB format. - doc.save(dataDir + "Document.EpubConversion_out_.epub"); - - System.out.println("Document converted to EPUB successfully."); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/ConvertDocumentToEPUBUysingDefaultSaveOptions.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/ConvertDocumentToEPUBUysingDefaultSaveOptions.java deleted file mode 100644 index b075738c..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/ConvertDocumentToEPUBUysingDefaultSaveOptions.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.Document; -import com.aspose.words.DocumentSplitCriteria; -import com.aspose.words.HtmlSaveOptions; -import com.aspose.words.SaveFormat; -import com.aspose.words.examples.Utils; - -import java.nio.charset.Charset; - -public class ConvertDocumentToEPUBUysingDefaultSaveOptions { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ConvertDocumentToEPUBUysingDefaultSaveOptions.class); - // Open an existing document from disk. - Document doc = new Document(dataDir + "Document.EpubConversion.doc"); - - // Create a new instance of HtmlSaveOptions. This object allows us to set options that control - // how the output document is saved. - HtmlSaveOptions saveOptions = new HtmlSaveOptions(); - - // Specify the desired encoding. - saveOptions.setEncoding(Charset.forName("UTF-8")); - - // Specify at what elements to split the internal HTML at. This creates a new HTML within the EPUB - // which allows you to limit the size of each HTML part. This is useful for readers which cannot read - // HTML files greater than a certain size e.g 300kb. - saveOptions.setDocumentSplitCriteria(DocumentSplitCriteria.HEADING_PARAGRAPH); - - // Specify that we want to export document properties. - saveOptions.setExportDocumentProperties(true); - - // Specify that we want to save in EPUB format. - saveOptions.setSaveFormat(SaveFormat.EPUB); - - // Export the document as an EPUB file. - doc.save(dataDir + "Document.EpubConversion_out_.epub", saveOptions); - System.out.println("Document using save options converted to EPUB successfully."); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/ConvertDocumentToHtmlWithRoundtrip.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/ConvertDocumentToHtmlWithRoundtrip.java deleted file mode 100644 index 036c496d..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/ConvertDocumentToHtmlWithRoundtrip.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.Document; -import com.aspose.words.SaveFormat; -import com.aspose.words.examples.Utils; -import com.aspose.words.*; -public class ConvertDocumentToHtmlWithRoundtrip -{ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(ConvertDocumentToHtmlWithRoundtrip.class); - - // Load the document. - Document doc = new Document(dataDir + "Test File (doc).doc"); - - HtmlSaveOptions options = new HtmlSaveOptions(); - - //HtmlSaveOptions.ExportRoundtripInformation property specifies - //whether to write the roundtrip information when saving to HTML, MHTML or EPUB. - //Default value is true for HTML and false for MHTML and EPUB. - options.setExportRoundtripInformation(true); - doc.save(dataDir + "ExportRoundtripInformation_out_.html", options); - - doc = new Document(dataDir + "ExportRoundtripInformation_out_.html"); - - //Save the document Docx file format - doc.save(dataDir + "TestFile_out_.docx", SaveFormat.DOCX); - System.out.println("Document converted to html with roundtrip informations successfully."); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/ConvertImageToPdf.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/ConvertImageToPdf.java deleted file mode 100644 index 1f6f7612..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/ConvertImageToPdf.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import javax.imageio.ImageIO; -import javax.imageio.ImageReader; -import javax.imageio.stream.ImageInputStream; -import java.awt.image.BufferedImage; -import java.io.File; - - -public class ConvertImageToPdf { - public static void main(String[] args) throws Exception { - /** - * Converts an image to PDF using Aspose.Words for Java. - * - * @param inputFileName File name of input image file. - * @param outputFileName Output PDF file name. - */ - - String dataDir = Utils.getDataDir(ConvertImageToPdf.class); - String inputFileName = dataDir + "Test.bmp"; - String outputFileName = dataDir + "output.pdf"; - - // Create Aspose.Words.Document and DocumentBuilder. - // The builder makes it simple to add content to the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - // Load images from the disk using the approriate reader. - // The file formats that can be loaded depends on the image readers available on the machine. - ImageInputStream iis = ImageIO.createImageInputStream(new File(inputFileName)); - ImageReader reader = ImageIO.getImageReaders(iis).next(); - reader.setInput(iis, false); - // Get the number of frames in the image. - int framesCount = reader.getNumImages(true); - - // Loop through all frames. - for (int frameIdx = 0; frameIdx < framesCount; frameIdx++) { - // Insert a section break before each new page, in case of a multi-frame image. - if (frameIdx != 0) - builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); - - // Select active frame. - BufferedImage image = reader.read(frameIdx); - - // We want the size of the page to be the same as the size of the image. - // Convert pixels to points to size the page to the actual image size. - PageSetup ps = builder.getPageSetup(); - - ps.setPageWidth(ConvertUtil.pixelToPoint(image.getWidth())); - ps.setPageHeight(ConvertUtil.pixelToPoint(image.getHeight())); - - // Insert the image into the document and position it at the top left corner of the page. - builder.insertImage( - image, - RelativeHorizontalPosition.PAGE, - 0, - RelativeVerticalPosition.PAGE, - 0, - ps.getPageWidth(), - ps.getPageHeight(), - WrapType.NONE); - - doc.save(outputFileName); - } - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/CreateDocument.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/CreateDocument.java deleted file mode 100644 index b965df36..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/CreateDocument.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.SaveFormat; -import com.aspose.words.examples.Utils; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; - -public class CreateDocument -{ - public static void main(String[] args) throws Exception - { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(CreateDocument.class); - - // Load the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - builder.write("hello world"); - doc.save(dataDir + "output.docx"); - - System.out.println("Document created successfully."); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/DetectDocumentSignatures.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/DetectDocumentSignatures.java deleted file mode 100644 index 48da358e..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/DetectDocumentSignatures.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import javax.imageio.ImageIO; -import javax.imageio.ImageReader; -import javax.imageio.stream.ImageInputStream; -import java.awt.image.BufferedImage; -import java.io.File; - - -public class DetectDocumentSignatures -{ - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DetectDocumentSignatures.class); - - // The path to the document which is to be processed. - String filePath = dataDir + "Document.Signed.docx"; - - FileFormatInfo info = FileFormatUtil.detectFileFormat(filePath); - if (info.hasDigitalSignature()) - { - System.out.println(java.text.MessageFormat.format( - "Document {0} has digital signatures, they will be lost if you open/save this document with Aspose.Words.", - new File(filePath).getName())); - } - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/DetectFileFormat.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/DetectFileFormat.java deleted file mode 100644 index 781f8ec2..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/DetectFileFormat.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.FileFormatInfo; -import com.aspose.words.FileFormatUtil; -import com.aspose.words.examples.Utils; - -import java.io.File; - - -public class DetectFileFormat -{ - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(DetectDocumentSignatures.class); - - // The path to the document which is to be processed. - String filePath = dataDir + "Document.Signed.docx"; - - FileFormatInfo info = FileFormatUtil.detectFileFormat(filePath); - System.out.println("The document format is: " + FileFormatUtil.loadFormatToExtension(info.getLoadFormat())); - System.out.println("Document is encrypted: " + info.isEncrypted()); - System.out.println("Document has a digital signature: " + info.hasDigitalSignature()); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/DigitallySignedPdf.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/DigitallySignedPdf.java deleted file mode 100644 index 86b327e1..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/DigitallySignedPdf.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.Document; -import com.aspose.words.FileFormatInfo; -import com.aspose.words.FileFormatUtil; -import com.aspose.words.examples.Utils; - -import java.io.File; - - -public class DigitallySignedPdf -{ - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(DigitallySignedPdf.class); - - // The path to the document which is to be processed. - String filePath = dataDir + "Document.Signed.docx"; - Document doc = new Document(); - - FileFormatInfo info = FileFormatUtil.detectFileFormat(filePath); - if (info.hasDigitalSignature()) - { - System.out.println(java.text.MessageFormat.format( - "Document {0} has digital signatures, they will be lost if you open/save this document with Aspose.Words.", - new File(filePath).getName())); - } - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/Doc2PDF.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/Doc2PDF.java deleted file mode 100644 index 933b07b7..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/Doc2PDF.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - -public class Doc2PDF -{ - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(Doc2PDF.class); - - // Load the document from disk. - Document doc = new Document(dataDir + "Template.doc"); - - // Save the document in PDF format. - dataDir = dataDir + "output.pdf"; - doc.save(dataDir); - - System.out.println("\nDocument converted to PDF successfully.\nFile saved at " + dataDir); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder.java deleted file mode 100644 index b8c02c98..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.FileFormatInfo; -import com.aspose.words.FileFormatUtil; -import com.aspose.words.LoadFormat; -import com.aspose.words.examples.Utils; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; - -public class GetListOfFilesInFolder { - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(GetListOfFilesInFolder.class); - - String supportedDir = dataDir + "OutSupported" + File.separator; - String unknownDir = dataDir + "OutUnknown" + File.separator; - String encryptedDir = dataDir + "OutEncrypted" + File.separator; - String pre97Dir = dataDir + "OutPre97" + File.separator; - - File[] fileList = new File(dataDir).listFiles(); - - // Loop through all found files. - for (File file : fileList) { - if (file.isDirectory()) - continue; - - // Extract and display the file name without the path. - String nameOnly = file.getName(); - System.out.print(nameOnly); - - } - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/ImageToPdf.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/ImageToPdf.java deleted file mode 100644 index 3af16716..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/ImageToPdf.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import javax.imageio.ImageIO; -import javax.imageio.ImageReader; -import javax.imageio.stream.ImageInputStream; -import java.awt.image.BufferedImage; -import java.io.File; - - -public class ImageToPdf -{ - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(ImageToPdf.class); - - convertImageToPdf(dataDir + "Test.jpg", dataDir + "TestJpg_out_.pdf"); - convertImageToPdf(dataDir + "Test.png", dataDir + "TestPng_out_.pdf"); - convertImageToPdf(dataDir + "Test.bmp", dataDir + "TestBmp_out_.pdf"); - convertImageToPdf(dataDir + "Test.gif", dataDir + "TestGif_out_.pdf"); - System.out.println("Images converted to PDF successfully."); - } - - /** - * Converts an image to PDF using Aspose.Words for Java. - * - * @param inputFileName File name of input image file. - * @param outputFileName Output PDF file name. - */ - public static void convertImageToPdf(String inputFileName, String outputFileName) throws Exception - { - // Create Aspose.Words.Document and DocumentBuilder. - // The builder makes it simple to add content to the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - // Load images from the disk using the approriate reader. - // The file formats that can be loaded depends on the image readers available on the machine. - ImageInputStream iis = ImageIO.createImageInputStream(new File(inputFileName)); - ImageReader reader = ImageIO.getImageReaders(iis).next(); - reader.setInput(iis, false); - - try - { - // Get the number of frames in the image. - int framesCount = reader.getNumImages(true); - - // Loop through all frames. - for (int frameIdx = 0; frameIdx < framesCount; frameIdx++) - { - // Insert a section break before each new page, in case of a multi-frame image. - if (frameIdx != 0) - builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); - - // Select active frame. - BufferedImage image = reader.read(frameIdx); - - // We want the size of the page to be the same as the size of the image. - // Convert pixels to points to size the page to the actual image size. - PageSetup ps = builder.getPageSetup(); - - ps.setPageWidth(ConvertUtil.pixelToPoint(image.getWidth())); - ps.setPageHeight(ConvertUtil.pixelToPoint(image.getHeight())); - - // Insert the image into the document and position it at the top left corner of the page. - builder.insertImage( - image, - RelativeHorizontalPosition.PAGE, - 0, - RelativeVerticalPosition.PAGE, - 0, - ps.getPageWidth(), - ps.getPageHeight(), - WrapType.NONE); - } - } - - finally { - if (iis != null) { - iis.close(); - reader.dispose(); - } - } - - // Save the document to PDF. - doc.save(outputFileName); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/LargeSizeImageToPdf.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/LargeSizeImageToPdf.java deleted file mode 100644 index b7211e75..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/LargeSizeImageToPdf.java +++ /dev/null @@ -1,168 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import javax.imageio.ImageIO; -import javax.imageio.ImageReader; -import javax.imageio.stream.ImageInputStream; -import java.awt.image.BufferedImage; -import java.io.File; - - -public class LargeSizeImageToPdf -{ - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ImageToPdf.class); - - convertImageToPdf(dataDir + "Test.jpg", dataDir + "TestJpg_out_.pdf"); - convertImageToPdf(dataDir + "Test.png", dataDir + "TestPng_out_.pdf"); - convertImageToPdf(dataDir + "Test.bmp", dataDir + "TestBmp_out_.pdf"); - convertImageToPdf(dataDir + "Test.gif", dataDir + "TestGif_out_.pdf"); - - System.out.println("Large size images converted to PDF successfully."); - } - - /** - * Converts an image to PDF using Aspose.Words for Java. - * - * @param inputFileName File name of input image file. - * @param outputFileName Output PDF file name. - */ - public static void convertImageToPdf(String inputFileName, String outputFileName) throws Exception - { - // Create Aspose.Words.Document and DocumentBuilder. - // The builder makes it simple to add content to the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - // Load images from the disk using the approriate reader. - // The file formats that can be loaded depends on the image readers available on the machine. - ImageInputStream iis = ImageIO.createImageInputStream(new File(inputFileName)); - ImageReader reader = ImageIO.getImageReaders(iis).next(); - reader.setInput(iis, false); - - try - { - // Get the number of frames in the image. - int framesCount = reader.getNumImages(true); - - // Loop through all frames. - for (int frameIdx = 0; frameIdx < framesCount; frameIdx++) - { - // Insert a section break before each new page, in case of a multi-frame image. - if (frameIdx != 0) - builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); - - // Select active frame. - BufferedImage image = reader.read(frameIdx); - - // Max page size - double maxPageHeight = 1584; - double maxPageWidth = 1584; - - double currentImageHeight = ConvertUtil.pixelToPoint(image.getHeight()); - double currentImageWidth = ConvertUtil.pixelToPoint(image.getWidth()); - - if (currentImageWidth >= maxPageWidth || currentImageHeight >= maxPageHeight) - { - - // Get max image size. - double[] size = CalculateImageSize(image, maxPageHeight, maxPageWidth, currentImageHeight, currentImageWidth); - currentImageWidth = size[0]; - currentImageHeight = size[1]; - } - - // We want the size of the page to be the same as the size of the image. - // Convert pixels to points to size the page to the actual image size. - PageSetup ps = builder.getPageSetup(); - - ps.setPageWidth(currentImageWidth); - ps.setPageHeight(currentImageHeight); - - // Insert the image into the document and position it at the top left corner of the page. - Shape shape = builder.insertImage( - image, - RelativeHorizontalPosition.PAGE, - 0, - RelativeVerticalPosition.PAGE, - 0, - ps.getPageWidth(), - ps.getPageHeight(), - WrapType.NONE); - - resizeLargeImage(shape); - } - } - - finally { - if (iis != null) { - iis.close(); - reader.dispose(); - } - } - - // Save the document to PDF. - doc.save(outputFileName); - } - - public static double[] CalculateImageSize(BufferedImage img, double containerHeight, double containerWidth, double targetHeight, double targetWidth) throws Exception { - - targetHeight = containerHeight; - targetWidth = containerWidth; - - //Get size of an image - double imgHeight = ConvertUtil.pixelToPoint(img.getHeight()); - double imgWidth = ConvertUtil.pixelToPoint(img.getWidth()); - - if (imgHeight < targetHeight && imgWidth < targetWidth) - { - targetHeight = imgHeight; - targetWidth = imgWidth; - } - else - { - //Calculate size of an image in the document - double ratioWidth = imgWidth / targetWidth; - double ratioHeight = imgHeight / targetHeight; - if (ratioWidth > ratioHeight) - targetHeight = (targetHeight * (ratioHeight / ratioWidth)); - else - targetWidth = (targetWidth * (ratioWidth / ratioHeight)); - } - - double[] size = new double[2]; - - size[0] = targetWidth; //width - size[1] = targetHeight; //height - - return(size); - } - - public static void resizeLargeImage(Shape image) throws Exception { - // Return if this shape is not an image. - if (!image.hasImage()) - return; - - // Calculate the free space based on an inline or floating image. If inline we must take the page margins into account. - PageSetup ps = image.getParentParagraph().getParentSection().getPageSetup(); - double freePageWidth = image.isInline() ? ps.getPageWidth() - ps.getLeftMargin() - ps.getRightMargin() : ps.getPageWidth(); - double freePageHeight = image.isInline() ? ps.getPageHeight() - ps.getTopMargin() - ps.getBottomMargin() : ps.getPageHeight(); - - // Is one of the sides of this image too big for the page? - ImageSize size = image.getImageData().getImageSize(); - boolean exceedsMaxPageSize = size.getWidthPoints() > freePageWidth || size.getHeightPoints() > freePageHeight; - - if (exceedsMaxPageSize) { - // Calculate the ratio to fit the page size based on which side is longer. - boolean widthLonger = (size.getWidthPoints() > size.getHeightPoints()); - double ratio = widthLonger ? freePageWidth / size.getWidthPoints() : freePageHeight / size.getHeightPoints(); - - // Set the new size. - image.setWidth(size.getWidthPoints() * ratio); - image.setHeight(size.getHeightPoints() * ratio); - } - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/LoadAndSave.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/LoadAndSave.java deleted file mode 100644 index e01e5b7d..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/LoadAndSave.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.Document; -import com.aspose.words.SaveFormat; -import com.aspose.words.examples.Utils; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.sql.*; -import java.text.MessageFormat; - -public class LoadAndSave { - private static Connection mConnection; - - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(LoadAndSave.class); - String fileName = "Test File (doc).doc"; - // Load the document from disk. - Document doc = new Document(dataDir + fileName); - - // Save the finished document to disk. - doc.save(dataDir + "output.doc"); - System.out.println("Document loaded and saved successfully."); - } -} - diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/LoadAndSaveToStream.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/LoadAndSaveToStream.java deleted file mode 100644 index 32e5a1b3..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/LoadAndSaveToStream.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.Document; -import com.aspose.words.SaveFormat; -import com.aspose.words.examples.Utils; - -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.OutputStream; -import java.sql.Connection; -import java.util.stream.Stream; - -public class LoadAndSaveToStream { - private static Connection mConnection; - - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(LoadAndSaveToStream.class); - String inputFile = "Test File (doc).doc"; - String outputFile = "output.png"; - - InputStream in = new FileInputStream(dataDir + inputFile); - OutputStream out = new FileOutputStream(dataDir + outputFile); - - Document doc = new Document(in); - - // Save the finished document to disk. - doc.save(out, SaveFormat.PNG); - System.out.println("Document loaded and saved successfully."); - } -} - diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/LoadDocFromDatabase.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/LoadDocFromDatabase.java deleted file mode 100644 index 371079c8..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/LoadDocFromDatabase.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.Document; -import com.aspose.words.LoadFormat; -import com.aspose.words.LoadOptions; -import com.aspose.words.SaveFormat; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; - -public class LoadDocFromDatabase { - public static void main(String[] args) throws Exception { - - // Retrieve the blob from database - byte[] buffer = new byte[100]; - // Now we have the document in a byte array buffer - - // Create an input steam which uses byte array to read data - ByteArrayInputStream bin = new ByteArrayInputStream(buffer); - // Open the doucment from input stream - //Document doc = new Document(bin); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/LoadEncryptedDoc.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/LoadEncryptedDoc.java deleted file mode 100644 index 469fb5fa..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/LoadEncryptedDoc.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; -import com.aspose.words.*; - -public class LoadEncryptedDoc -{ - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(LoadEncryptedDoc.class); - - // Load the encrypted document from the absolute path on disk. - Document doc = new Document(dataDir + "LoadEncrypted.docx", new LoadOptions("aspose")); - - System.out.println("Encrypted document loaded successfully."); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/LoadTxt.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/LoadTxt.java deleted file mode 100644 index 38f8e17c..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/LoadTxt.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - -public class LoadTxt -{ - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(LoadTxt.class); - - // The encoding of the text file is automatically detected. - Document doc = new Document(dataDir + "LoadTxt.txt"); - - // Save as any Aspose.Words supported format, such as DOCX. - doc.save(dataDir + "output.docx"); - - System.out.println("Loaded data from text file successfully."); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/OpenDocUsingStream.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/OpenDocUsingStream.java deleted file mode 100644 index b43250f7..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/OpenDocUsingStream.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - -import java.io.FileInputStream; -import java.io.InputStream; - -public class OpenDocUsingStream { - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(OpenDocUsingStream.class); - String filename = "Test.docx"; - - InputStream in = new FileInputStream(dataDir + filename); - - Document doc = new Document(in); - System.out.println("Document opened. Total pages are " + doc.getPageCount()); - in.close(); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/OpenDocument.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/OpenDocument.java deleted file mode 100644 index e0646c27..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/OpenDocument.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.Document; -import com.aspose.words.FileFormatInfo; -import com.aspose.words.FileFormatUtil; -import com.aspose.words.LoadFormat; -import com.aspose.words.examples.Utils; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; - -public class OpenDocument{ - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(OpenDocument.class); - String filename = "Test.docx"; - - Document doc = new Document(dataDir + filename); - - - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/OpenEncryptedDocument.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/OpenEncryptedDocument.java deleted file mode 100644 index 365af0b6..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/OpenEncryptedDocument.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.Document; -import com.aspose.words.LoadOptions; -import com.aspose.words.examples.Utils; - -public class OpenEncryptedDocument { - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(OpenEncryptedDocument.class); - String filename = "LoadEncrypted.docx"; - Document doc = new Document(dataDir + filename , new LoadOptions("aspose")); - - doc.save(dataDir +"output.doc"); - - - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/PageSplitter.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/PageSplitter.java deleted file mode 100644 index d8442207..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/PageSplitter.java +++ /dev/null @@ -1,589 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; -import com.sun.media.jfxmediaimpl.MediaUtils; -import javafx.scene.shape.Path; - -import java.io.File; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Hashtable; -import java.util.Stack; - - -public class PageSplitter -{ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(PageSplitter.class); - - SplitAllDocumentsToPages(dataDir); - System.out.println("\nDocument split to pages successfully.\nFile saved at " + dataDir + "\\Out"); - } - - public static void SplitDocumentToPages(File docName) throws Exception - { - String folderName = docName.getParent(); - String fileName = docName.getName(); - String extensionName = fileName.substring(fileName.lastIndexOf(".")); - String outFolder = new File(folderName, "Out").getAbsolutePath(); - System.out.println("Processing document: " + fileName ); - - - Document doc = new Document(docName.getAbsolutePath()); - - // Create and attach collector to the document before page layout is built. - LayoutCollector layoutCollector = new LayoutCollector(doc); - - // This will build layout model and collect necessary information. - doc.updatePageLayout(); - - // Split nodes in the document into separate pages. - DocumentPageSplitter splitter = new DocumentPageSplitter(layoutCollector); - - // Save each page to the disk as a separate document. - for (int page = 1; page <= doc.getPageCount(); page++) - { - Document pageDoc = splitter.GetDocumentOfPage(page); - pageDoc.save(new File(outFolder, MessageFormat.format("{0} - page{1} Out{2}", fileName, page, extensionName)).getAbsolutePath()); - } - - // Detach the collector from the document. - layoutCollector.setDocument(null); - } - - public static void SplitAllDocumentsToPages(String folderName) throws Exception - { - File[] files = new File(folderName).listFiles(); - - for (File file : files) { - if (file.isFile()) { - SplitDocumentToPages(file); - } - } - } -} - -class DocumentPageSplitter { - /** - * Initializes new instance of this class. This method splits the document into sections so that each page - * begins and ends at a section boundary. It is recommended not to modify the document afterwards. - */ - public DocumentPageSplitter(LayoutCollector collector) throws Exception { - mPageNumberFinder = new PageNumberFinder(collector); - mPageNumberFinder.SplitNodesAcrossPages(); - } - - /** - * Gets the document of a page. - */ - public Document GetDocumentOfPage(int pageIndex) throws Exception { - return GetDocumentOfPageRange(pageIndex, pageIndex); - } - - /** - * Gets the document of a page range. - */ - public Document GetDocumentOfPageRange(int startIndex, int endIndex) throws Exception { - Document result = (Document) getDocument().deepClone(false); - - for (Section section : (Iterable
          ) mPageNumberFinder.RetrieveAllNodesOnPages(startIndex, endIndex, NodeType.SECTION)) - result.appendChild(result.importNode(section, true)); - - return result; - } - - /** - * Gets the document this instance works with. - */ - private Document getDocument() { - return mPageNumberFinder.getDocument(); - } - - private PageNumberFinder mPageNumberFinder; -} - -class PageNumberFinder { - - /** - * Initializes new instance of this class. - */ - public PageNumberFinder(LayoutCollector collector) { - mCollector = collector; - } - - /** - * Retrieves 1-based index of a page that the node begins on. - */ - public int GetPage(Node node) throws Exception { - if (mNodeStartPageLookup.containsKey(node)) - return (Integer) mNodeStartPageLookup.get(node); - - return mCollector.getStartPageIndex(node); - } - - /** - * Retrieves 1-based index of a page that the node ends on. - */ - public int GetPageEnd(Node node) throws Exception { - if (mNodeEndPageLookup.containsKey(node)) - return (Integer) mNodeEndPageLookup.get(node); - - return mCollector.getEndPageIndex(node); - } - - /** - * Returns how many pages the specified node spans over. Returns 1 if the node is contained within one page. - */ - public int PageSpan(Node node) throws Exception { - return GetPageEnd(node) - GetPage(node) + 1; - } - - /** - * Returns a list of nodes that are contained anywhere on the specified page or pages which match the specified node type. - */ - public ArrayList RetrieveAllNodesOnPages(int startPage, int endPage, int nodeType) throws Exception { - if (startPage < 1 || startPage > getDocument().getPageCount()) - throw new Exception("startPage"); - - if (endPage < 1 || endPage > getDocument().getPageCount() || endPage < startPage) - throw new Exception("endPage"); - - CheckPageListsPopulated(); - - ArrayList pageNodes = new ArrayList(); - - for (int page = startPage; page <= endPage; page++) { - // Some pages can be empty. - if (!mReversePageLookup.containsKey(page)) - continue; - - for (Node node : (Iterable) mReversePageLookup.get(page)) { - if (node.getParentNode() != null && ((nodeType == NodeType.ANY) || (nodeType == node.getNodeType())) && !pageNodes.contains(node)) - pageNodes.add(node); - } - } - - return pageNodes; - } - - /** - * Splits nodes which appear over two or more pages into separate nodes so that they still appear in the same way - * but no longer appear across a page. - */ - public void SplitNodesAcrossPages() throws Exception { - // Visit any composites which are possibly split across pages and split them into separate nodes. - getDocument().accept(new SectionSplitter(this)); - } - - /** - * Gets the document this instance works with. - */ - public Document getDocument() { - return mCollector.getDocument(); - } - - /** - * This is called by to update page numbers of split nodes. - */ - void AddPageNumbersForNode(Node node, int startPage, int endPage) { - if (startPage > 0) - mNodeStartPageLookup.put(node, startPage); - - if (endPage > 0) - mNodeEndPageLookup.put(node, endPage); - } - - private void CheckPageListsPopulated() throws Exception { - if (mReversePageLookup != null) - return; - - mReversePageLookup = new Hashtable(); - - // Add each node to a list which represent the nodes found on each page. - for (Node node : (Iterable) getDocument().getChildNodes(NodeType.ANY, true)) { - // Headers/Footers follow sections. They are not split by themselves. - if (IsHeaderFooterType(node)) - continue; - - int startPage = GetPage(node); - int endPage = GetPageEnd(node); - - for (int page = startPage; page <= endPage; page++) { - if (!mReversePageLookup.containsKey(page)) - mReversePageLookup.put(page, new ArrayList()); - - ((ArrayList) mReversePageLookup.get(page)).add(node); - } - } - } - - private static boolean IsHeaderFooterType(Node node) { - return node.getNodeType() == NodeType.HEADER_FOOTER || node.getAncestor(NodeType.HEADER_FOOTER) != null; - } - - // Maps node to a start/end page numbers. This is used to override baseline page numbers provided by collector when document is split. - private Hashtable mNodeStartPageLookup = new Hashtable(); - private Hashtable mNodeEndPageLookup = new Hashtable(); - // Maps page number to a list of nodes found on that page. - private Hashtable mReversePageLookup; - private LayoutCollector mCollector; -} - -class SectionSplitter extends DocumentVisitor { - public SectionSplitter(PageNumberFinder pageNumberFinder) { - mPageNumberFinder = pageNumberFinder; - } - - - public int visitParagraphStart(Paragraph paragraph) throws Exception { - if (paragraph.isListItem()) { - List paraList = paragraph.getListFormat().getList(); - ListLevel currentLevel = paragraph.getListFormat().getListLevel(); - - // Since we have encountered a list item we need to check if this will reset - // any subsequent list levels and if so then update the numbering of the level. - int currentListLevelNumber = paragraph.getListFormat().getListLevelNumber(); - for (int i = currentListLevelNumber + 1; i < paraList.getListLevels().getCount(); i++) { - ListLevel paraLevel = paraList.getListLevels().get(i); - - if (paraLevel.getRestartAfterLevel() >= currentListLevelNumber) { - // This list level needs to be reset after the current list number. - mListLevelToListNumberLookup.put(paraLevel, paraLevel.getStartAt()); - } - } - - // A list which was used on a previous page is present on a different page, the list - // needs to be copied so list numbering is retained when extracting individual pages. - if (ContainsListLevelAndPageChanged(paragraph)) { - List copyList = paragraph.getDocument().getLists().addCopy(paraList); - mListLevelToListNumberLookup.put(currentLevel, paragraph.getListLabel().getLabelValue()); - - // Set the numbering of each list level to start at the numbering of the level on the previous page. - for (int i = 0; i < paraList.getListLevels().getCount(); i++) { - ListLevel paraLevel = paraList.getListLevels().get(i); - - if (mListLevelToListNumberLookup.containsKey(paraLevel)) - copyList.getListLevels().get(i).setStartAt((Integer) mListLevelToListNumberLookup.get(paraLevel)); - } - - mListToReplacementListLookup.put(paraList, copyList); - } - - if (mListToReplacementListLookup.containsKey(paraList)) { - // This paragraph belongs to a list from a previous page. Apply the replacement list. - paragraph.getListFormat().setList((List) mListToReplacementListLookup.get(paraList)); - // This is a trick to get the spacing of the list level to set correctly. - paragraph.getListFormat().setListLevelNumber(paragraph.getListFormat().getListLevelNumber() + 0); - } - - mListLevelToPageLookup.put(currentLevel, mPageNumberFinder.GetPage(paragraph)); - mListLevelToListNumberLookup.put(currentLevel, paragraph.getListLabel().getLabelValue()); - } - - Section prevSection = (Section) paragraph.getParentSection().getPreviousSibling(); - Paragraph prevBodyPara = null; - - if (paragraph.getPreviousSibling() != null && paragraph.getPreviousSibling().getNodeType() == NodeType.PARAGRAPH) - prevBodyPara = (Paragraph) paragraph.getPreviousSibling(); - - Paragraph prevSectionPara = prevSection != null && paragraph == paragraph.getParentSection().getBody().getFirstChild() ? prevSection.getBody().getLastParagraph() : null; - Paragraph prevParagraph = prevBodyPara != null ? prevBodyPara : prevSectionPara; - - if (paragraph.isEndOfSection() && !paragraph.hasChildNodes()) - paragraph.remove(); - - // Paragraphs across pages can merge or remove spacing depending upon the previous paragraph. - if (prevParagraph != null) { - if (mPageNumberFinder.GetPage(paragraph) != mPageNumberFinder.GetPageEnd(prevParagraph)) { - if (paragraph.isListItem() && prevParagraph.isListItem() && !prevParagraph.isEndOfSection()) - prevParagraph.getParagraphFormat().setSpaceAfter(0); - else if (prevParagraph.getParagraphFormat().getStyleName() == paragraph.getParagraphFormat().getStyleName() && paragraph.getParagraphFormat().getNoSpaceBetweenParagraphsOfSameStyle()) - paragraph.getParagraphFormat().setSpaceBefore(0); - else if (paragraph.getParagraphFormat().getPageBreakBefore() || (prevParagraph.isEndOfSection() && prevSection.getPageSetup().getSectionStart() != SectionStart.NEW_COLUMN)) - paragraph.getParagraphFormat().setSpaceBefore(Math.max(paragraph.getParagraphFormat().getSpaceBefore() - prevParagraph.getParagraphFormat().getSpaceAfter(), 0)); - else - paragraph.getParagraphFormat().setSpaceBefore(0); - } - } - - return VisitorAction.CONTINUE; - } - - public int visitSectionStart(Section section) throws Exception { - mSectionCount++; - Section previousSection = (Section) section.getPreviousSibling(); - - // If there is a previous section attempt to copy any linked header footers otherwise they will not appear in an - // extracted document if the previous section is missing. - if (previousSection != null) { - if (!section.getPageSetup().getRestartPageNumbering()) { - section.getPageSetup().setRestartPageNumbering(true); - section.getPageSetup().setPageStartingNumber(previousSection.getPageSetup().getPageStartingNumber() + mPageNumberFinder.PageSpan(previousSection)); - } - - for (HeaderFooter previousHeaderFooter : previousSection.getHeadersFooters()) { - if (section.getHeadersFooters().getByHeaderFooterType(previousHeaderFooter.getHeaderFooterType()) == null) { - HeaderFooter newHeaderFooter = (HeaderFooter) previousSection.getHeadersFooters().getByHeaderFooterType(previousHeaderFooter.getHeaderFooterType()).deepClone(true); - section.getHeadersFooters().add(newHeaderFooter); - } - } - } - - // Manually set the result of these fields before sections are split. - for (HeaderFooter headerFooter : section.getHeadersFooters()) { - for (Field field : headerFooter.getRange().getFields()) { - if (field.getType() == FieldType.FIELD_SECTION || field.getType() == FieldType.FIELD_SECTION_PAGES) { - field.setResult((field.getType() == FieldType.FIELD_SECTION) ? Integer.toString(mSectionCount) : - Integer.toString(mPageNumberFinder.PageSpan(section))); - - field.isLocked(true); - } - } - } - - // All fields in the body should stay the same, this also improves field update time. - for (Field field : section.getBody().getRange().getFields()) - field.isLocked(true); - - return VisitorAction.CONTINUE; - } - - public int visitDocumentEnd(Document doc) throws Exception { - // All sections have separate headers and footers now, update the fields in all headers and footers - // to the correct values. This allows each page to maintain the correct field results even when - // PAGE or IF fields are used. - doc.updateFields(); - - for (HeaderFooter headerFooter : (Iterable) doc.getChildNodes(NodeType.HEADER_FOOTER, true)) { - for (Field field : headerFooter.getRange().getFields()) - field.isLocked(true); - } - - return VisitorAction.CONTINUE; - } - - public int visitSmartTagEnd(SmartTag smartTag) throws Exception { - if (IsCompositeAcrossPage(smartTag)) - SplitComposite(smartTag); - - return VisitorAction.CONTINUE; - } - -// public int visitCustomXmlMarkupEnd(CustomXmlMarkup customXmlMarkup) throws Exception { -// if (IsCompositeAcrossPage(customXmlMarkup)) -// SplitComposite(customXmlMarkup); -// -// return VisitorAction.CONTINUE; -// } - - public int visitStructuredDocumentTagEnd(StructuredDocumentTag sdt) throws Exception { - if (IsCompositeAcrossPage(sdt)) - SplitComposite(sdt); - - return VisitorAction.CONTINUE; - } - - public int visitCellEnd(Cell cell) throws Exception { - if (IsCompositeAcrossPage(cell)) - SplitComposite(cell); - - return VisitorAction.CONTINUE; - } - - public int visitRowEnd(Row row) throws Exception { - if (IsCompositeAcrossPage(row)) - SplitComposite(row); - - return VisitorAction.CONTINUE; - } - - public int visitTableEnd(Table table) throws Exception { - if (IsCompositeAcrossPage(table)) { - // Copy any header rows to other pages. - Row[] rows = table.getRows().toArray(); - - for (Table cloneTable : (Iterable
          ) SplitComposite(table)) { - for (Row row : rows) { - if (row.getRowFormat().getHeadingFormat()) - cloneTable.prependChild(row.deepClone(true)); - } - } - } - - return VisitorAction.CONTINUE; - } - - public int visitParagraphEnd(Paragraph paragraph) throws Exception { - if (IsCompositeAcrossPage(paragraph)) { - for (Paragraph clonePara : (Iterable) SplitComposite(paragraph)) { - // Remove list numbering from the cloned paragraph but leave the indent the same - // as the paragraph is supposed to be part of the item before. - if (paragraph.isListItem()) { - double textPosition = clonePara.getListFormat().getListLevel().getTextPosition(); - clonePara.getListFormat().removeNumbers(); - clonePara.getParagraphFormat().setLeftIndent(textPosition); - } - - // Reset spacing of split paragraphs as additional spacing is removed. - clonePara.getParagraphFormat().setSpaceBefore(0); - paragraph.getParagraphFormat().setSpaceAfter(0); - } - } - - return VisitorAction.CONTINUE; - } - - public int visitSectionEnd(Section section) throws Exception { - if (IsCompositeAcrossPage(section)) { - // If a TOC field spans across more than one page then the hyperlink formatting may show through. - // Remove direct formatting to avoid this. - for (FieldStart start : (Iterable) section.getChildNodes(NodeType.FIELD_START, true)) { - if (start.getFieldType() == FieldType.FIELD_TOC) { - Field field = start.getField(); - Node node = field.getSeparator(); - - while ((node = node.nextPreOrder(section)) != field.getEnd()) - if (node.getNodeType() == NodeType.RUN) - ((Run) node).getFont().clearFormatting(); - } - } - - for (Section cloneSection : (Iterable
          ) SplitComposite(section)) { - cloneSection.getPageSetup().setSectionStart(SectionStart.NEW_PAGE); - cloneSection.getPageSetup().setRestartPageNumbering(true); - cloneSection.getPageSetup().setPageStartingNumber(section.getPageSetup().getPageStartingNumber() + (section.getDocument().indexOf(cloneSection) - section.getDocument().indexOf(section))); - cloneSection.getPageSetup().setDifferentFirstPageHeaderFooter(false); - - RemovePageBreaksFromParagraph(cloneSection.getBody().getLastParagraph()); - } - - RemovePageBreaksFromParagraph(section.getBody().getLastParagraph()); - - // Add new page numbering for the body of the section as well. - mPageNumberFinder.AddPageNumbersForNode(section.getBody(), mPageNumberFinder.GetPage(section), mPageNumberFinder.GetPageEnd(section)); - } - - return VisitorAction.CONTINUE; - } - - private boolean IsCompositeAcrossPage(CompositeNode composite) throws Exception { - return (mPageNumberFinder.PageSpan(composite) > 1); - } - - private boolean ContainsListLevelAndPageChanged(Paragraph para) throws Exception { - return mListLevelToPageLookup.containsKey(para.getListFormat().getListLevel()) && (Integer) mListLevelToPageLookup.get(para.getListFormat().getListLevel()) != mPageNumberFinder.GetPage(para); - } - - private void RemovePageBreaksFromParagraph(Paragraph para) throws Exception { - if (para != null) { - for (Run run : para.getRuns()) - run.setText(run.getText().replace(ControlChar.PAGE_BREAK, "")); - } - } - - private ArrayList SplitComposite(CompositeNode composite) throws Exception { - ArrayList splitNodes = new ArrayList(); - for (Node splitNode : (Iterable) FindChildSplitPositions(composite)) - splitNodes.add(SplitCompositeAtNode(composite, splitNode)); - - return splitNodes; - } - - private ArrayList FindChildSplitPositions(CompositeNode node) throws Exception { - // A node may span across multiple pages so a list of split positions is returned. - // The split node is the first node on the next page. - ArrayList splitList = new ArrayList(); - - int startingPage = mPageNumberFinder.GetPage(node); - - Node[] childNodes = node.getNodeType() == NodeType.SECTION ? - ((Section) node).getBody().getChildNodes().toArray() : node.getChildNodes().toArray(); - - for (Node childNode : childNodes) { - int pageNum = mPageNumberFinder.GetPage(childNode); - - // If the page of the child node has changed then this is the split position. Add - // this to the list. - if (pageNum > startingPage) { - splitList.add(childNode); - startingPage = pageNum; - } - - if (mPageNumberFinder.PageSpan(childNode) > 1) - mPageNumberFinder.AddPageNumbersForNode(childNode, pageNum, pageNum); - } - - // Split composites backward so the cloned nodes are inserted in the right order. - Collections.reverse(splitList); - - return splitList; - } - - private CompositeNode SplitCompositeAtNode(CompositeNode baseNode, Node targetNode) throws Exception { - CompositeNode cloneNode = (CompositeNode) baseNode.deepClone(false); - - Node node = targetNode; - int currentPageNum = mPageNumberFinder.GetPage(baseNode); - - // Move all nodes found on the next page into the copied node. Handle row nodes separately. - if (baseNode.getNodeType() != NodeType.ROW) { - CompositeNode composite = cloneNode; - - if (baseNode.getNodeType() == NodeType.SECTION) { - cloneNode = (CompositeNode) baseNode.deepClone(true); - Section section = (Section) cloneNode; - section.getBody().removeAllChildren(); - - composite = section.getBody(); - } - - while (node != null) { - Node nextNode = node.getNextSibling(); - composite.appendChild(node); - node = nextNode; - } - } else { - // If we are dealing with a row then we need to add in dummy cells for the cloned row. - int targetPageNum = mPageNumberFinder.GetPage(targetNode); - Node[] childNodes = baseNode.getChildNodes().toArray(); - - for (Node childNode : childNodes) { - int pageNum = mPageNumberFinder.GetPage(childNode); - - if (pageNum == targetPageNum) { - cloneNode.getLastChild().remove(); - cloneNode.appendChild(childNode); - } else if (pageNum == currentPageNum) { - cloneNode.appendChild(childNode.deepClone(false)); - if (cloneNode.getLastChild().getNodeType() != NodeType.CELL) - ((CompositeNode) cloneNode.getLastChild()).appendChild(((CompositeNode) childNode).getFirstChild().deepClone(false)); - } - } - } - - // Insert the split node after the original. - baseNode.getParentNode().insertAfter(cloneNode, baseNode); - - // Update the new page numbers of the base node and the clone node including its descendents. - // This will only be a single page as the cloned composite is split to be on one page. - int currentEndPageNum = mPageNumberFinder.GetPageEnd(baseNode); - mPageNumberFinder.AddPageNumbersForNode(baseNode, currentPageNum, currentEndPageNum - 1); - mPageNumberFinder.AddPageNumbersForNode(cloneNode, currentEndPageNum, currentEndPageNum); - - for (Node childNode : (Iterable) cloneNode.getChildNodes(NodeType.ANY, true)) - mPageNumberFinder.AddPageNumbersForNode(childNode, currentEndPageNum, currentEndPageNum); - - return cloneNode; - } - - private Hashtable mListLevelToListNumberLookup = new Hashtable(); - private Hashtable mListToReplacementListLookup = new Hashtable(); - private Hashtable mListLevelToPageLookup = new Hashtable(); - private PageNumberFinder mPageNumberFinder; - private int mSectionCount; -} - diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/SaveDocToDatabase.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/SaveDocToDatabase.java deleted file mode 100644 index 12bd8170..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/SaveDocToDatabase.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.Document; -import com.aspose.words.SaveFormat; - -import java.io.ByteArrayOutputStream; - -public class SaveDocToDatabase { - public static void main(String[] args) throws Exception { - // Create a new empty document - Document doc = new Document(); - // Create an output stream which uses byte array to save data - ByteArrayOutputStream aout = new ByteArrayOutputStream(); - // Save the document to byte array - doc.save(aout, SaveFormat.DOCX); - // Get the byte array from output steam - // the byte array now contains the document - byte[] buffer = aout.toByteArray(); - // Save the document to database blob - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/SendToClientBrowser.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/SendToClientBrowser.java deleted file mode 100644 index 7236dcdb..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/SendToClientBrowser.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - -public class SendToClientBrowser { - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(SendToClientBrowser.class); - String filename = "test.docx"; - - Document doc = new Document(dataDir + filename); - dataDir = dataDir + "output.doc"; - doc.save(dataDir); - - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/SpecifySaveOption.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/SpecifySaveOption.java deleted file mode 100644 index 05f5e10b..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/SpecifySaveOption.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.Document; -import com.aspose.words.LoadOptions; -import com.aspose.words.examples.Utils; -import com.aspose.words.SaveFormat; -import com.aspose.words.*; -import java.io.*; -public class SpecifySaveOption -{ - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(SpecifySaveOption.class); - String fileName = "TestFile RenderShape.docx"; - // Load the document. - Document doc = new Document(dataDir + fileName); - - // This is the directory we want the exported images to be saved to. - File imagesDir = new File(dataDir, "Images"); - - // The folder specified needs to exist and should be empty. - if(imagesDir.exists()) - imagesDir.delete(); - - imagesDir.mkdir(); - - // Set an option to export form fields as plain text, not as HTML input elements. - HtmlSaveOptions options = new HtmlSaveOptions(SaveFormat.HTML); - options.setExportTextInputFormFieldAsText(true); - options.setImagesFolder(imagesDir.getPath()); - dataDir = dataDir + Utils.GetOutputFilePath(fileName); - doc.save(dataDir, options); - System.out.println("\nSave option specified successfully.\nFile saved at " + dataDir); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/SplitIntoHtmlPages.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/SplitIntoHtmlPages.java deleted file mode 100644 index 457c8b05..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/SplitIntoHtmlPages.java +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright 2001-2015 Aspose Pty Ltd. All Rights Reserved. - * - * This file is part of Aspose.Words. The source code in this file - * is only intended as a supplement to the documentation, and is provided - * "as is", without warranty of any kind, either expressed or implied. - */ - -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; -import java.io.File; -import java.util.ArrayList; - -public class SplitIntoHtmlPages -{ - public static void main(String[] args) throws Exception - { - // You need to have a valid license for Aspose.Words. - // The best way is to embed the license as a resource into the project - // and specify only file name without path in the following call. - // Aspose.Words.License license = new Aspose.Words.License(); - // license.SetLicense(@"Aspose.Words.lic"); - - - // The path to the documents directory. - String dataDir = Utils.getDataDir(SplitIntoHtmlPages.class); - - String srcFileName = dataDir + "SOI 2007-2012-DeeM with footnote added.doc"; - String tocTemplate = dataDir + "TocTemplate.doc"; - - File outDir = new File(dataDir, "Out"); - outDir.mkdirs(); - - // This class does the job. - Worker w = new Worker(); - w.execute(srcFileName, tocTemplate, outDir.getPath()); - - System.out.println("Document split into HTML pages successfully."); - } -} - -/** - * A custom data source for Aspose.Words mail merge. - * Returns topic objects. - */ -class TocMailMergeDataSource implements IMailMergeDataSource -{ - TocMailMergeDataSource(ArrayList topics) throws Exception - { - mTopics = topics; - // Initialize to BOF. - mIndex = -1; - } - - public boolean moveNext() throws Exception - { - if (mIndex < mTopics.size() - 1) - { - mIndex++; - return true; - } - else - { - // Reached EOF, return false. - return false; - } - } - - public boolean getValue(String fieldName, Object[] fieldValue) throws Exception - { - if ("TocEntry".equals(fieldName)) - { - // The template document is supposed to have only one field called "TocEntry". - fieldValue[0] = mTopics.get(mIndex); - return true; - } - else - { - fieldValue[0] = null; - return false; - } - } - - public String getTableName() throws Exception { return "TOC"; } - - public IMailMergeDataSource getChildDataSource(String tableName) throws Exception - { - return null; - } - - private final ArrayList mTopics; - private int mIndex; -} - -/** - * A simple class to hold a topic title and HTML file name together. - */ -class Topic -{ - Topic(String title, String fileName) throws Exception - { - mTitle = title; - mFileName = fileName; - } - - String getTitle() throws Exception { return mTitle; } - - String getFileName() throws Exception { return mFileName; } - - private final String mTitle; - private final String mFileName; -} - -/** - *This class takes a Microsoft Word document, splits it into topics at paragraphs formatted - * with the Heading 1 style and saves every topic as an HTML file. - * - * Also generates contents.html file that provides links to all saved topics. - */ -class Worker -{ - /** - * Performs the Word to HTML conversion. - * - * @param srcFileName The MS Word file to convert. - * @param tocTemplate An MS Word file that is used as a template to build - * a table of contents. This file needs to have a mail merge region called "TOC" defined - * and one mail merge field called "TocEntry". - * @param dstDir The output directory where to write HTML files. Must exist. - */ - void execute(String srcFileName, String tocTemplate, String dstDir) throws Exception - { - mDoc = new Document(srcFileName); - mTocTemplate = tocTemplate; - mDstDir = dstDir; - - ArrayList topicStartParas = selectTopicStarts(); - insertSectionBreaks(topicStartParas); - ArrayList topics = saveHtmlTopics(); - saveTableOfContents(topics); - } - - /** - * Selects heading paragraphs that must become topic starts. - * We can't modify them in this loop, we have to remember them in an array first. - */ - private ArrayList selectTopicStarts() throws Exception - { - NodeCollection paras = mDoc.getChildNodes(NodeType.PARAGRAPH, true, false); - ArrayList topicStartParas = new ArrayList(); - - for (Paragraph para : (Iterable) paras) - { - int style = para.getParagraphFormat().getStyleIdentifier(); - if (style == StyleIdentifier.HEADING_1) - topicStartParas.add(para); - } - - return topicStartParas; - } - - /** - * Inserts section breaks before the specified paragraphs. - */ - private void insertSectionBreaks(ArrayList topicStartParas) throws Exception - { - DocumentBuilder builder = new DocumentBuilder(mDoc); - for (Paragraph para : (Iterable) topicStartParas) - { - Section section = para.getParentSection(); - - // Insert section break if the paragraph is not at the beginning of a section already. - if (para != section.getBody().getFirstParagraph()) - { - builder.moveTo(para.getFirstChild()); - builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); - - // This is the paragraph that was inserted at the end of the now old section. - // We don't really need the extra paragraph, we just needed the section. - section.getBody().getLastParagraph().remove(); - } - } - } - - /** - * Splits the current document into one topic per section and saves each topic - * as an HTML file. Returns a collection of Topic objects. - */ - private ArrayList saveHtmlTopics() throws Exception - { - ArrayList topics = new ArrayList(); - for (int sectionIdx = 0; sectionIdx < mDoc.getSections().getCount(); sectionIdx++) - { - Section section = mDoc.getSections().get(sectionIdx); - - String paraText = section.getBody().getFirstParagraph().getText(); - - // The text of the heading paragaph is used to generate the HTML file name. - String fileName = makeTopicFileName(paraText); - if ("".equals(fileName)) - fileName = "UNTITLED SECTION " + sectionIdx; - - fileName = new File(mDstDir, fileName + ".html").getPath(); - - // The text of the heading paragraph is also used to generate the title for the TOC. - String title = makeTopicTitle(paraText); - if ("".equals(title)) - title = "UNTITLED SECTION " + sectionIdx; - - Topic topic = new Topic(title, fileName); - topics.add(topic); - - saveHtmlTopic(section, topic); - } - - return topics; - } - - /** - * Leaves alphanumeric characters, replaces white space with underscore - * and removes all other characters from a string. - */ - private static String makeTopicFileName(String paraText) throws Exception - { - StringBuilder b = new StringBuilder(); - for (int i = 0; i < paraText.length(); i++) - { - char c = paraText.charAt(i); - if (Character.isLetterOrDigit(c)) - b.append(c); - else if (c == ' ') - b.append('_'); - } - return b.toString(); - } - - /** - * Removes the last character (which is a paragraph break character from the given string). - */ - private static String makeTopicTitle(String paraText) throws Exception - { - return paraText.substring((0), (0) + (paraText.length() - 1)); - } - - /** - * Saves one section of a document as an HTML file. - * Any embedded images are saved as separate files in the same folder as the HTML file. - */ - private static void saveHtmlTopic(Section section, Topic topic) throws Exception - { - Document dummyDoc = new Document(); - dummyDoc.removeAllChildren(); - dummyDoc.appendChild(dummyDoc.importNode(section, true, ImportFormatMode.KEEP_SOURCE_FORMATTING)); - - dummyDoc.getBuiltInDocumentProperties().setTitle(topic.getTitle()); - - HtmlSaveOptions saveOptions = new HtmlSaveOptions(); - saveOptions.setPrettyFormat(true); - // This is to allow headings to appear to the left of main text. - saveOptions.setAllowNegativeLeftIndent(true); - saveOptions.setExportHeadersFootersMode(ExportHeadersFootersMode.NONE); - - dummyDoc.save(topic.getFileName(), saveOptions); - } - - /** - * Generates a table of contents for the topics and saves to contents.html. - */ - private void saveTableOfContents(ArrayList topics) throws Exception - { - Document tocDoc = new Document(mTocTemplate); - - // We use a custom mail merge even handler defined below. - tocDoc.getMailMerge().setFieldMergingCallback(new HandleTocMergeField()); - // We use a custom mail merge data source based on the collection of the topics we created. - tocDoc.getMailMerge().executeWithRegions(new TocMailMergeDataSource(topics)); - - tocDoc.save(new File(mDstDir, "contents.html").getPath()); - } - - private class HandleTocMergeField implements IFieldMergingCallback - { - public void fieldMerging(FieldMergingArgs e) throws Exception - { - if (mBuilder == null) - mBuilder = new DocumentBuilder(e.getDocument()); - - // Our custom data source returns topic objects. - Topic topic = (Topic)e.getFieldValue(); - - // We use the document builder to move to the current merge field and insert a hyperlink. - mBuilder.moveToMergeField(e.getFieldName()); - mBuilder.insertHyperlink(topic.getTitle(), topic.getFileName(), false); - - // Signal to the mail merge engine that it does not need to insert text into the field - // as we've done it already. - e.setText(""); - } - - public void imageFieldMerging(ImageFieldMergingArgs args) throws Exception - { - // Do nothing. - } - - private DocumentBuilder mBuilder; - } - - private Document mDoc; - private String mTocTemplate; - private String mDstDir; -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/loading_saving/Word2Help.java b/Examples/src/main/java/com/aspose/words/examples/loading_saving/Word2Help.java deleted file mode 100644 index 8af1b0aa..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/loading_saving/Word2Help.java +++ /dev/null @@ -1,739 +0,0 @@ -package com.aspose.words.examples.loading_saving; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; -import org.w3c.dom.Element; - -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Source; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; -import java.io.*; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - - -/** - * This project converts documentation stored inside a DOC format to a series of HTML documents. This output is in - * a form that can then be easily compiled together into a single compiled help file (CHM) by using - * the Microsoft HTML Help Workshop application. - */ -public class Word2Help -{ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(Word2Help.class); - - // Specifies the destination directory where the HTML files are output. - File outPath = new File(dataDir, "Out"); - - // Remove any existing output and recreate the Out folder. - if(outPath.exists()) - { - for(File file : outPath.listFiles()) - { - file.delete(); - } - } - - outPath.mkdirs(); - String outDir = outPath.getAbsolutePath(); - - // Specifies the part of the URLs to remove. If there are any hyperlinks that start - // with the above URL, this URL is removed. This allows the document designer to include - // links to the HTML API and they will be "corrected" so they work both in the online - // HTML and also in the compiled CHM. - String fixUrl = ""; - - // *** LICENSING *** - // An Aspose.Words license is required to use this project fully. - // Without a license Aspose.Words will work in evaluation mode and truncate documents - // and output watermarks. - // - // You can download a free 30-day trial license from the Aspose site. The easiest way is to set the license is to - // include the license in the executing directory and uncomment the following code. - // - // Aspose.Words.License license = new Aspose.Words.License(); - // license.setLicense("Aspose.Words.lic"); - System.out.println(MessageFormat.format("Extracting topics from {0}.", dataDir)); - - TopicCollection topics = new TopicCollection(dataDir, fixUrl); - topics.addFromDir(dataDir); - topics.writeHtml(outDir); - topics.writeContentXml(outDir); - - System.out.println("Conversion completed successfully."); - } -} - -/** - * This "facade" class makes it easier to work with a hyperlink field in a Word document. - * - * A hyperlink is represented by a HYPERLINK field in a Word document. A field in Aspose.Words - * consists of several nodes and it might be difficult to work with all those nodes directly. - * This is a simple implementation and will work only if the hyperlink code and name - * each consist of one Run only. - * - * [FieldStart][Run - field code][FieldSeparator][Run - field result][FieldEnd] - * - * The field code contains a string in one of these formats: - * HYPERLINK "url" - * HYPERLINK \l "bookmark name" - * - * The field result contains text that is displayed to the user. - */ -class Hyperlink -{ - public Hyperlink(FieldStart fieldStart) throws Exception - { - if (fieldStart == null) - throw new IllegalArgumentException("fieldStart"); - if (fieldStart.getFieldType() != FieldType.FIELD_HYPERLINK) - throw new IllegalArgumentException("Field start type must be FieldHyperlink."); - - mFieldStart = fieldStart; - - // Find field separator node. - mFieldSeparator = findNextSibling(mFieldStart, NodeType.FIELD_SEPARATOR); - if (mFieldSeparator == null) - throw new Exception("Cannot find field separator."); - - // Find field end node. Normally field end will always be found, but in the example document - // there happens to be a paragraph break included in the hyperlink and this puts the field end - // in the next paragraph. It will be much more complicated to handle fields which span several - // paragraphs correctly, but in this case allowing field end to be null is enough for our purposes. - mFieldEnd = findNextSibling(mFieldSeparator, NodeType.FIELD_END); - - // Field code looks something like [ HYPERLINK "http:\\www.myurl.com" ], but it can consist of several runs. - String fieldCode = getTextSameParent(mFieldStart.getNextSibling(), mFieldSeparator); - - Matcher match = G_REGEX.matcher(fieldCode.trim()); - - if(match.find()) - { - mIsLocal = match.group(1) != null; - mTarget = match.group(2); - } - } - - /* - * Gets or sets the display name of the hyperlink. - */ - public String getName() throws Exception - { - return getTextSameParent(mFieldSeparator, mFieldEnd); - } - - public void setName(String value) throws Exception - { - // Hyperlink display name is stored in the field result which is a Run - // node between field separator and field end. - Run fieldResult = (Run)mFieldSeparator.getNextSibling(); - fieldResult.setText(value); - - // But sometimes the field result can consist of more than one run, delete these runs. - removeSameParent(fieldResult.getNextSibling(), mFieldEnd); - } - - /* - * Gets or sets the target url or bookmark name of the hyperlink. - */ - public String getTarget() throws Exception - { - return mTarget; - } - - public void setTarget(String value) throws Exception - { - mTarget = value; - updateFieldCode(); - } - - /* - * True if the hyperlink's target is a bookmark inside the document. False if the hyperlink is a url. - */ - public boolean isLocal() throws Exception - { - return mIsLocal; - } - - public void setLocal(boolean value) throws Exception - { - mIsLocal = value; - updateFieldCode(); - } - - /** - * Updates the field code. - */ - private void updateFieldCode() throws Exception - { - // Field code is stored in a Run node between field start and field separator. - Run fieldCode = (Run)mFieldStart.getNextSibling(); - fieldCode.setText(java.text.MessageFormat.format("HYPERLINK {0}\"{1}\"", ((mIsLocal) ? "\\l " : ""), mTarget)); - - // But sometimes the field code can consist of more than one run, delete these runs. - removeSameParent(fieldCode.getNextSibling(), mFieldSeparator); - } - - /** - * Goes through siblings starting from the start node until it finds a node of the specified type or null. - */ - private static Node findNextSibling(Node start, int nodeType) throws Exception - { - for (Node node = start; node != null; node = node.getNextSibling()) - { - if (node.getNodeType() == nodeType) - return node; - } - return null; - } - - /* - * Retrieves text from start up to but not including the end node. - */ - private static String getTextSameParent(Node start, Node end) throws Exception - { - if ((end != null) && (start.getParentNode() != end.getParentNode())) - throw new IllegalArgumentException("Start and end nodes are expected to have the same parent."); - - StringBuilder builder = new StringBuilder(); - for (Node child = start; child != end; child = child.getNextSibling()) - builder.append(child.getText()); - return builder.toString(); - } - - /* - * Removes nodes from start up to but not including the end node. - * Start and end are assumed to have the same parent. - */ - private static void removeSameParent(Node start, Node end) throws Exception - { - if ((end != null) && (start.getParentNode() != end.getParentNode())) - throw new IllegalArgumentException("Start and end nodes are expected to have the same parent."); - - Node curChild = start; - while (curChild != end) - { - Node nextChild = curChild.getNextSibling(); - curChild.remove(); - curChild = nextChild; - } - } - - private final Node mFieldStart; - private final Node mFieldSeparator; - private final Node mFieldEnd; - private String mTarget; - private boolean mIsLocal; - - private static final Pattern G_REGEX = Pattern.compile( - "\\S+" + // One or more non spaces HYPERLINK or other word in other languages - "\\s+" + // One or more spaces - "(?:\"\"\\s+)?" + // Non capturing optional "" and one or more spaces, found in one of the customers files. - "(\\\\l\\s+)?" + // Optional \l flag followed by one or more spaces - "\"" + // One apostrophe - "([^\"]+)" + // One or more chars except apostrophe (hyperlink target) - "\"" // One closing apostrophe - ); -} - -/** - * Central storage for regular expressions used in the project. - */ -class RegularExpressions -{ - // This class is static. No instance creation is allowed. - private RegularExpressions() throws Exception {} - - /** - * Regular expression specifying html title (framing tags excluded). - */ - public static Pattern getHtmlTitle() throws Exception - { - if (gHtmlTitle == null) - { - gHtmlTitle = Pattern.compile(HTML_TITLE_PATTERN, - Pattern.CASE_INSENSITIVE); - } - return gHtmlTitle; - } - - /** - * Regular expression specifying html head. - */ - public static Pattern getHtmlHead() throws Exception - { - if (gHtmlHead == null) - { - gHtmlHead = Pattern.compile(HTML_HEAD_PATTERN, - Pattern.CASE_INSENSITIVE); - } - return gHtmlHead; - } - - /** - * Regular expression specifying space right after div keyword in the first div declaration of html body. - */ - public static Pattern getHtmlBodyDivStart() throws Exception - { - if (gHtmlBodyDivStart == null) - { - gHtmlBodyDivStart = Pattern.compile(HTML_BODY_DIV_START_PATTERN, - Pattern.CASE_INSENSITIVE); - } - return gHtmlBodyDivStart; - } - - private static final String HTML_TITLE_PATTERN = "(?<=\\).*?(?=\\)"; - private static Pattern gHtmlTitle; - - private static final String HTML_HEAD_PATTERN = "\\.*?\\"; - private static Pattern gHtmlHead; - - private static final String HTML_BODY_DIV_START_PATTERN = "(?<=\\\\s{0,200}\\ 8)) - throwTopicException("This topic does not start with a heading style paragraph.", section); - - mTitle = headingPara.getText().trim(); - if ("".equals(mTitle)) - throwTopicException("This topic heading does not have text.", section); - - // We actually remove the heading paragraph because

          will be output in the banner. - headingPara.remove(); - - mTopicDoc.getBuiltInDocumentProperties().setTitle(mTitle); - - fixHyperlinks(section.getDocument(), fixUrl); - } - - private static void throwTopicException(String message, Section section) throws Exception - { - throw new Exception(message + " Section text: " + section.getBody().toString(SaveFormat.TEXT).substring(0, 50)); - } - - private void fixHyperlinks(DocumentBase originalDoc, String fixUrl) throws Exception - { - if (fixUrl.endsWith("/")) - fixUrl = fixUrl.substring(0, fixUrl.length() - 1); - - NodeCollection fieldStarts = mTopicDoc.getChildNodes(NodeType.FIELD_START, true); - for (FieldStart fieldStart : (Iterable) fieldStarts) - { - if (fieldStart.getFieldType() != FieldType.FIELD_HYPERLINK) - continue; - - Hyperlink hyperlink = new Hyperlink(fieldStart); - if (hyperlink.isLocal()) - { - // We use "Hyperlink to a place in this document" feature of Microsoft Word - // to create local hyperlinks between topics within the same doc file. - // It causes MS Word to auto generate the bookmark name. - String bmkName = hyperlink.getTarget(); - - // But we have to follow the bookmark to get the text of the topic heading paragraph - // in order to be able to build the proper filename of the topic file. - Bookmark bmk = originalDoc.getRange().getBookmarks().get(bmkName); - - // String test1 = MessageFormat.format("Found a link to a bookmark, but cannot locate the bookmark. Name:{0}.", bmkName); - - if (bmk == null) - throw new Exception(MessageFormat.format("Found a link to a bookmark, but cannot locate the bookmark. Name:{0}.", bmkName)); - - Paragraph para = (Paragraph)bmk.getBookmarkStart().getParentNode(); - String topicName = para.getText().trim(); - - hyperlink.setTarget(headingToFileName(topicName) + ".html"); - hyperlink.setLocal(false); - } - else - { - // We "fix" URL like this: - // http://www.aspose.com/Products/Aspose.Words/Api/Aspose.Words.Body.html - // by changing them into this: - // Aspose.Words.Body.html - if (hyperlink.getTarget().startsWith(fixUrl) && - (hyperlink.getTarget().length() > (fixUrl.length() + 1))) - { - hyperlink.setTarget(hyperlink.getTarget().substring(fixUrl.length() + 1)); - } - } - } - } - - public void writeHtml(String htmlHeader, String htmlBanner, String htmlFooter, String outDir) throws Exception - { - String fileName = new File(outDir, getFileName()).getAbsolutePath(); - - HtmlSaveOptions saveOptions = new HtmlSaveOptions(); - saveOptions.setPrettyFormat(true); - // This is to allow headings to appear to the left of main text. - saveOptions.setAllowNegativeLeftIndent(true); - // Disable headers and footers. - saveOptions.setExportHeadersFootersMode(ExportHeadersFootersMode.NONE); - - // Export the document to HTML. - mTopicDoc.save(fileName, saveOptions); - - // We need to modify the HTML string, read HTML back. - String html; - FileInputStream reader = null; - - try{ - reader = new FileInputStream(fileName); - byte[] fileBytes = new byte[reader.available()]; - reader.read(fileBytes); - html = new String(fileBytes); - } - - finally { if (reader != null) reader.close(); } - - // Builds the HTML element. - String header = htmlHeader.replaceFirst(RegularExpressions.getHtmlTitle().pattern(), mTitle); - - // Applies the new element instead of the original one. - html = html.replaceFirst(RegularExpressions.getHtmlHead().pattern(), header); - html = html.replaceFirst(RegularExpressions.getHtmlBodyDivStart().pattern(), " id=\"nstext\""); - - String banner = htmlBanner.replace("###TOPIC_NAME###", mTitle); - - // Add the standard banner. - html = html.replace("", "" + banner); - - // Add the standard footer. - html = html.replace("", htmlFooter + ""); - - FileOutputStream writer = null; - - try{ - writer = new FileOutputStream(fileName); - writer.write(html.getBytes()); - } - - finally { if (writer != null) writer.close(); } - } - - /** - * Removes various characters from the header to form a file name that does not require escaping. - */ - private static String headingToFileName(String heading) throws Exception - { - StringBuilder b = new StringBuilder(); - for (int i = 0; i < heading.length(); i++) - { - char c = heading.charAt(i); - if (Character.isLetterOrDigit(c)) - b.append(c); - } - - return b.toString(); - } - - public Document getDocument() throws Exception { return mTopicDoc; } - - /** - * Gets the name of the topic html file without path. - */ - public String getFileName() throws Exception { return headingToFileName(mTitle) + ".html"; } - - public String getTitle() throws Exception { return mTitle; } - - public int getHeadingLevel() throws Exception { return mHeadingLevel; } - - /** - * Returns true if the topic has no text (the heading paragraph has already been removed from the topic). - */ - public boolean isHeadingOnly() throws Exception - { - Body body = mTopicDoc.getFirstSection().getBody(); - return (body.getFirstParagraph() == null); - } - - private final Document mTopicDoc; - private final String mTitle; - private final int mHeadingLevel; -} - -/** - * This is the main class. - * Loads Word document(s), splits them into topics, saves HTML files and builds content.xml. - */ -class TopicCollection -{ - /** - * Ctor. - * - * @param htmlTemplatesDir The directory that contains header.html, banner.html and footer.html files. - * - * @param fixUrl The url that will be removed from any hyperlinks that start with this url. - * This allows turning some absolute URLS into relative ones. - */ - public TopicCollection(String htmlTemplatesDir, String fixUrl) throws Exception - { - mTopics = new ArrayList(); - mFixUrl = fixUrl; - mHtmlHeader = readFile(htmlTemplatesDir + "header.html"); - mHtmlBanner = readFile(htmlTemplatesDir + "banner.html"); - mHtmlFooter = readFile(htmlTemplatesDir + "footer.html"); - } - - /** - * Processes all DOC files found in the specified directory. - * Loads and splits each document into separate topics. - */ - public void addFromDir(String dirName) throws Exception - { - FilenameFilter fileFilter = new FilenameFilter() { - - public boolean accept(File dir, String name) { - return name.endsWith(".doc"); - } - }; - - for (File filename : new File(dirName).listFiles(fileFilter)) - addFromFile(filename.getAbsolutePath()); - } - - /** - * Processes a specified DOC file. Loads and splits into topics. - */ - public void addFromFile(String fileName) throws Exception - { - Document doc = new Document(fileName); - insertTopicSections(doc); - addTopics(doc); - } - - /** - * Saves all topics as HTML files. - */ - public void writeHtml(String outDir) throws Exception - { - for (TopicWord2Help topic : (Iterable) mTopics) - { - if (!topic.isHeadingOnly()) - topic.writeHtml(mHtmlHeader, mHtmlBanner, mHtmlFooter, outDir); - } - } - - /** - * Saves the content.xml file that describes the tree of topics. - */ - public void writeContentXml(String outDir) throws Exception - { - DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance(); - javax.xml.parsers.DocumentBuilder parser = fact.newDocumentBuilder(); - org.w3c.dom.Document doc = parser.newDocument(); - - Element root = doc.createElement("content"); - root.setAttribute("dir", outDir); - doc.appendChild(root); - - Element currentElement = root; - - for (int i = 0; i < mTopics.size(); i++) - { - TopicWord2Help topic = (TopicWord2Help)mTopics.get(i); - - int nextTopicIdx = i + 1; - TopicWord2Help nextTopic = (nextTopicIdx < mTopics.size()) ? (TopicWord2Help)mTopics.get(i + 1) : null; - - int nextHeadingLevel = (nextTopic != null) ? nextTopic.getHeadingLevel() : 0; - - if (nextHeadingLevel > topic.getHeadingLevel()) - { - // Next topic is nested, therefore we have to start a book. - // We only allow increase level at a time. - if (nextHeadingLevel != topic.getHeadingLevel() + 1) - throw new Exception("Topic is nested for more than one level at a time. Title: " + topic.getTitle()); - - currentElement = writeBookStart(currentElement, topic); - } - else if (nextHeadingLevel < topic.getHeadingLevel()) - { - // Next topic is one or more levels higher in the outline. - // Write out the current topic. - writeItem(currentElement, topic.getTitle(), topic.getFileName()); - - // End one or more nested topics could have ended at this point. - int levelsToClose = topic.getHeadingLevel() - nextHeadingLevel; - while (levelsToClose > 0) - { - currentElement = (Element)currentElement.getParentNode(); - levelsToClose--; - } - } - else - { - // A topic at the current level and it has no children. - writeItem(currentElement, topic.getTitle(), topic.getFileName()); - } - } - - // Prepare the DOM document for writing - Source source = new DOMSource(doc); - - // Prepare the output file - File file = new File(outDir, "content.xml"); - FileOutputStream outputStream = new FileOutputStream(file.getAbsolutePath()); - StreamResult result = new StreamResult(new OutputStreamWriter(outputStream,"UTF-8")); // UTF-8 encoding must be specified in order for the output to have proper indentation. - - // Write the DOM document to disk. - TransformerFactory tf = TransformerFactory.newInstance(); - tf.setAttribute("indent-number", 2); // Set the indentation for child elements. - - // Export as XML. - Transformer transformer = tf.newTransformer(); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.transform(source, result); - } - - /** - * Inserts section breaks that delimit the topics. - * - * @param doc The document where to insert the section breaks. - */ - private static void insertTopicSections(Document doc) throws Exception - { - DocumentBuilder builder = new DocumentBuilder(doc); - - NodeCollection paras = doc.getChildNodes(NodeType.PARAGRAPH, true, false); - ArrayList topicStartParas = new ArrayList(); - - for (Paragraph para : (Iterable) paras) - { - int style = para.getParagraphFormat().getStyleIdentifier(); - if ((style >= StyleIdentifier.HEADING_1) && (style <= MAX_TOPIC_HEADING) && - (para.hasChildNodes())) - { - // Select heading paragraphs that must become topic starts. - // We can't modify them in this loop, we have to remember them in an array first. - topicStartParas.add(para); - } - else if ((style > MAX_TOPIC_HEADING) && (style <= StyleIdentifier.HEADING_9)) - { - // Pull up headings. For example: if Heading 1-4 become topics, then I want Headings 5+ - // to become Headings 4+. Maybe I want to pull up even higher? - para.getParagraphFormat().setStyleIdentifier(style - 1); - } - } - - for (Paragraph para : (Iterable) topicStartParas) - { - Section section = para.getParentSection(); - - // Insert section break if the paragraph is not at the beginning of a section already. - if (para != section.getBody().getFirstParagraph()) - { - builder.moveTo(para.getFirstChild()); - builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); - - // This is the paragraph that was inserted at the end of the now old section. - // We don't really need the extra paragraph, we just needed the section. - section.getBody().getLastParagraph().remove(); - } - } - } - - /** - * Goes through the sections in the document and adds them as topics to the collection. - */ - private void addTopics(Document doc) throws Exception - { - for (Section section : doc.getSections()) - { - try - { - TopicWord2Help topic = new TopicWord2Help(section, mFixUrl); - mTopics.add(topic); - } - catch (Exception e) - { - // If one topic fails, we continue with others. - System.out.println(e.getMessage()); - } - } - } - - private static Element writeBookStart(Element root, TopicWord2Help topic) throws Exception - { - Element book = root.getOwnerDocument().createElement("book"); - root.appendChild(book); - - book.setAttribute("name", topic.getTitle()); - - if (!topic.isHeadingOnly()) - book.setAttribute("href", topic.getFileName()); - - return book; - } - - private static void writeItem(Element root, String name, String href) throws Exception - { - Element item = root.getOwnerDocument().createElement("item"); - root.appendChild(item); - - item.setAttribute("name", name); - item.setAttribute("href", href); - } - - private static String readFile(String fileName) throws Exception - { - FileInputStream reader = null; - try - { - reader = new FileInputStream(fileName); - byte[] fileBytes = new byte[reader.available()]; - - reader.read(fileBytes); - - return new String(fileBytes); - } - - finally { - if (reader != null) - reader.close(); - } - } - - private final ArrayList mTopics; - private final String mFixUrl; - private final String mHtmlHeader; - private final String mHtmlBanner; - private final String mHtmlFooter; - - /** - * Specifies the maximum Heading X number. - * All of the headings above or equal to this will be put into their own topics. - */ - private static final int MAX_TOPIC_HEADING = StyleIdentifier.HEADING_4; -} - diff --git a/Examples/src/main/java/com/aspose/words/examples/mail_merge/AdvancedMailMergeFeatures.java b/Examples/src/main/java/com/aspose/words/examples/mail_merge/AdvancedMailMergeFeatures.java deleted file mode 100644 index 79d4fd1c..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/mail_merge/AdvancedMailMergeFeatures.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.aspose.words.examples.mail_merge; - -import com.aspose.words.Document; - -public class AdvancedMailMergeFeatures { - - public static void main(String[] args) { - - } - - /** - * Add a mapping when a merge field in a document and a data field in a data - * source have different names. - */ - private static void addMappingWhenMergeFieldAndDataFieldHaveDifferentNames(Document doc) { - doc.getMailMerge().getMappedDataFields().add("MyFieldName_InDocument", "MyFieldName_InDataSource"); - } - - /** - * Get names of all merge fields in a document. - */ - private static void getNamesOfAllMergeFields(Document doc) throws Exception { - String[] fieldNames = doc.getMailMerge().getFieldNames(); - } - - /** - * Delete all merge fields from a document without executing mail merge. - */ - private static void deletingMergeFields(Document doc) throws Exception { - doc.getMailMerge().deleteFields(); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/mail_merge/ApplyCustomFormattingDuringMailMerge.java b/Examples/src/main/java/com/aspose/words/examples/mail_merge/ApplyCustomFormattingDuringMailMerge.java deleted file mode 100644 index 131836d1..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/mail_merge/ApplyCustomFormattingDuringMailMerge.java +++ /dev/null @@ -1,128 +0,0 @@ -package com.aspose.words.examples.mail_merge; - -import java.awt.Color; -import java.sql.ResultSet; - -import javax.sql.rowset.RowSetMetaDataImpl; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.FieldMergingArgs; -import com.aspose.words.IFieldMergingCallback; -import com.aspose.words.ImageFieldMergingArgs; -import com.aspose.words.examples.Utils; -import com.aspose.words.net.System.Data.DataTable; -import com.sun.rowset.CachedRowSetImpl; - -public class ApplyCustomFormattingDuringMailMerge { - - private static final String dataDir = Utils.getSharedDataDir(ApplyCustomFormattingDuringMailMerge.class) + "MailMerge/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(dataDir + "MailMerge.AlternatingRows.doc"); - - // Add a handler for the MergeField event. - doc.getMailMerge().setFieldMergingCallback(new HandleMergeFieldAlternatingRows()); - - // Execute mail merge with regions. - DataTable dataTable = getSuppliersDataTable(); - doc.getMailMerge().executeWithRegions(dataTable); - - doc.save(dataDir + "MailMerge.AlternatingRows Out.doc"); - } - - /** - * Returns true if the value is odd; false if the value is even. - */ - public static boolean isOdd(int value) throws Exception { - return (value % 2 != 0); - } - - /** - * Create DataTable and fill it with data. In real life this DataTable - * should be filled from a database. - */ - private static DataTable getSuppliersDataTable() throws Exception { - java.sql.ResultSet resultSet = createCachedRowSet(new String[] { "CompanyName", "ContactName" }); - - for (int i = 0; i < 10; i++) - addRow(resultSet, new String[] { "Company " + Integer.toString(i), "Contact " + Integer.toString(i) }); - - return new DataTable(resultSet, "Suppliers"); - } - - /** - * A helper method that creates an empty Java disconnected ResultSet with - * the specified columns. - */ - private static ResultSet createCachedRowSet(String[] columnNames) throws Exception { - RowSetMetaDataImpl metaData = new RowSetMetaDataImpl(); - metaData.setColumnCount(columnNames.length); - for (int i = 0; i < columnNames.length; i++) { - metaData.setColumnName(i + 1, columnNames[i]); - metaData.setColumnType(i + 1, java.sql.Types.VARCHAR); - } - - CachedRowSetImpl rowSet = new CachedRowSetImpl(); - rowSet.setMetaData(metaData); - - return rowSet; - } - - /** - * A helper method that adds a new row with the specified values to a - * disconnected ResultSet. - */ - private static void addRow(ResultSet resultSet, String[] values) throws Exception { - resultSet.moveToInsertRow(); - - for (int i = 0; i < values.length; i++) - resultSet.updateString(i + 1, values[i]); - - resultSet.insertRow(); - - // This "dance" is needed to add rows to the end of the result set properly. - // If I do something else then rows are either added at the front or the result - // set throws an exception about a deleted row during mail merge. - resultSet.moveToCurrentRow(); - resultSet.last(); - } -} - -class HandleMergeFieldAlternatingRows implements IFieldMergingCallback { - /** - * Called for every merge field encountered in the document. We can either - * return some data to the mail merge engine or do something else with the - * document. In this case we modify cell formatting. - */ - public void fieldMerging(FieldMergingArgs e) throws Exception { - if (mBuilder == null) - mBuilder = new DocumentBuilder(e.getDocument()); - - // This way we catch the beginning of a new row. - if (e.getFieldName().equals("CompanyName")) { - // Select the color depending on whether the row number is even or odd. - Color rowColor; - if (ApplyCustomFormattingDuringMailMerge.isOdd(mRowIdx)) - rowColor = new Color(213, 227, 235); - else - rowColor = new Color(242, 242, 242); - - // There is no way to set cell properties for the whole row at the moment, - // so we have to iterate over all cells in the row. - for (int colIdx = 0; colIdx < 4; colIdx++) { - mBuilder.moveToCell(0, mRowIdx, colIdx, 0); - mBuilder.getCellFormat().getShading().setBackgroundPatternColor(rowColor); - } - - mRowIdx++; - } - } - - public void imageFieldMerging(ImageFieldMergingArgs args) throws Exception { - // Do nothing. - } - - private DocumentBuilder mBuilder; - private int mRowIdx; -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/mail_merge/ApplyCustomLogicToEmptyRegions.java b/Examples/src/main/java/com/aspose/words/examples/mail_merge/ApplyCustomLogicToEmptyRegions.java deleted file mode 100644 index 8aaf2373..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/mail_merge/ApplyCustomLogicToEmptyRegions.java +++ /dev/null @@ -1,312 +0,0 @@ -package com.aspose.words.examples.mail_merge; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; -import com.aspose.words.net.System.Data.DataRelation; -import com.aspose.words.net.System.Data.DataSet; -import com.aspose.words.net.System.Data.DataTable; -import com.sun.rowset.CachedRowSetImpl; - -import javax.sql.rowset.RowSetMetaDataImpl; -import java.sql.ResultSet; -import java.util.ArrayList; - -public class ApplyCustomLogicToEmptyRegions { - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(ApplyCustomLogicToEmptyRegions.class); - - Document doc = new Document(dataDir + "TestFile.doc"); - - // Create a data source which has some data missing. - // This will result in some regions that are merged and some that remain after executing mail merge. - DataSet data = getDataSource(); - - // Make sure that we have not set the removal of any unused regions as we will handle them manually. - // We achieve this by removing the RemoveUnusedRegions flag from the cleanup options by using the AND and NOT bitwise operators. - doc.getMailMerge().setCleanupOptions(doc.getMailMerge().getCleanupOptions() & ~MailMergeCleanupOptions.REMOVE_UNUSED_REGIONS); - - // Execute mail merge. Some regions will be merged with data, others left unmerged. - doc.getMailMerge().executeWithRegions(data); - - // The regions which contained data now would of been merged. Any regions which had no data and were - // not merged will still remain in the document. - Document mergedDoc = doc.deepClone(); //ExSkip - // Apply logic to each unused region left in the document using the logic set out in the handler. - // The handler class must implement the IFieldMergingCallback interface. - executeCustomLogicOnEmptyRegions(doc, new EmptyRegionsHandler()); - - // Save the output document to disk. - doc.save(dataDir + "TestFile.CustomLogicEmptyRegions1 Out.doc"); - - // Reload the original merged document. - doc = mergedDoc.deepClone(); - - // Apply different logic to unused regions this time. - executeCustomLogicOnEmptyRegions(doc, new EmptyRegionsHandler_MergeTable()); - - doc.save(dataDir + "TestFile.CustomLogicEmptyRegions2 Out.doc"); - - // Reload the original merged document. - doc = mergedDoc.deepClone(); - - ArrayList regions = new ArrayList(); - regions.add("ContactDetails"); - executeCustomLogicOnEmptyRegions(doc, new EmptyRegionsHandler(), regions); - - doc.save(dataDir + "TestFile.CustomLogicEmptyRegions3 Out.doc"); - - System.out.println("Mail merge performed successfully."); - } - - /** - * Returns a DataSet object containing a DataTable for the unmerged regions - * in the specified document. If regionsList is null all regions found - * within the document are included. If an ArrayList instance is present the - * only the regions specified in the list that are found in the document are - * added. - */ - private static DataSet createDataSourceFromDocumentRegions(Document doc, ArrayList regionsList) throws Exception { - final String TABLE_START_MARKER = "TableStart:"; - DataSet dataSet = new DataSet(); - String tableName = null; - - for (String fieldName : doc.getMailMerge().getFieldNames()) { - if (fieldName.contains(TABLE_START_MARKER)) { - tableName = fieldName.substring(TABLE_START_MARKER.length()); - } else if (tableName != null) { - // Only add the table as a new DataTable if it doesn't already exists in the DataSet. - if (dataSet.getTables().get(tableName) == null) { - ResultSet resultSet = createCachedRowSet(new String[] { fieldName }); - - // We only need to add the first field for the handler to be called for the fields in the region. - if (regionsList == null || regionsList.contains(tableName)) { - addRow(resultSet, new String[] { "FirstField" }); - } - - dataSet.getTables().add(new DataTable(resultSet, tableName)); - } - tableName = null; - } - } - - return dataSet; - } - - /** - * Applies logic defined in the passed handler class to all unused regions - * in the document. This allows to manually control how unused regions are - * handled in the document. - * - * @param doc - * The document containing unused regions. - * @param handler - * The handler which implements the IFieldMergingCallback - * interface and defines the logic to be applied to each unmerged - * region. - */ - public static void executeCustomLogicOnEmptyRegions(Document doc, IFieldMergingCallback handler) throws Exception { - executeCustomLogicOnEmptyRegions(doc, handler, null); // Pass null to handle all regions found in the document. - } - - /** - * Applies logic defined in the passed handler class to specific unused - * regions in the document as defined in regionsList. This allows to - * manually control how unused regions are handled in the document. - * - * @param doc - * The document containing unused regions. - * @param handler - * The handler which implements the IFieldMergingCallback - * interface and defines the logic to be applied to each unmerged - * region. - * @param regionsList - * A list of strings corresponding to the region names that are - * to be handled by the supplied handler class. Other regions - * encountered will not be handled and are removed automatically. - */ - public static void executeCustomLogicOnEmptyRegions(Document doc, IFieldMergingCallback handler, ArrayList regionsList) throws Exception { - // Certain regions can be skipped from applying logic to by not adding the table name inside the CreateEmptyDataSource method. - // Enable this cleanup option so any regions which are not handled by the user's logic are removed automatically. - doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_UNUSED_REGIONS); - - // Set the user's handler which is called for each unmerged region. - doc.getMailMerge().setFieldMergingCallback(handler); - - // Execute mail merge using the dummy dataset. The dummy data source contains the table names of - // each unmerged region in the document (excluding ones that the user may have specified to be skipped). This will allow the handler - // to be called for each field in the unmerged regions. - doc.getMailMerge().executeWithRegions(createDataSourceFromDocumentRegions(doc, regionsList)); - } - - /** - * A helper method that creates an empty Java disconnected ResultSet with - * the specified columns. - */ - private static ResultSet createCachedRowSet(String[] columnNames) throws Exception { - RowSetMetaDataImpl metaData = new RowSetMetaDataImpl(); - metaData.setColumnCount(columnNames.length); - for (int i = 0; i < columnNames.length; i++) { - metaData.setColumnName(i + 1, columnNames[i]); - metaData.setColumnType(i + 1, java.sql.Types.VARCHAR); - } - - CachedRowSetImpl rowSet = new CachedRowSetImpl(); - rowSet.setMetaData(metaData); - - return rowSet; - } - - /** - * A helper method that adds a new row with the specified values to a - * disconnected ResultSet. - */ - private static void addRow(ResultSet resultSet, String[] values) throws Exception { - resultSet.moveToInsertRow(); - - for (int i = 0; i < values.length; i++) - resultSet.updateString(i + 1, values[i]); - - resultSet.insertRow(); - - // This "dance" is needed to add rows to the end of the result set properly. - // If I do something else then rows are either added at the front or the result - // set throws an exception about a deleted row during mail merge. - resultSet.moveToCurrentRow(); - resultSet.last(); - } - - public static class EmptyRegionsHandler implements IFieldMergingCallback { - /** - * Called for each field belonging to an unmerged region in the - * document. - */ - public void fieldMerging(FieldMergingArgs args) throws Exception { - // Change the text of each field of the ContactDetails region individually. - if ("ContactDetails".equals(args.getTableName())) { - // Set the text of the field based off the field name. - if ("Name".equals(args.getFieldName())) - args.setText("(No details found)"); - else if ("Number".equals(args.getFieldName())) - args.setText("(N/A)"); - } - - // Remove the entire table of the Suppliers region. Also check if the previous paragraph - // before the table is a heading paragraph and if so remove that too. - if ("Suppliers".equals(args.getTableName())) { - Table table = (Table) args.getField().getStart().getAncestor(NodeType.TABLE); - - // Check if the table has been removed from the document already. - if (table.getParentNode() != null) { - // Try to find the paragraph which precedes the table before the table is removed from the document. - if (table.getPreviousSibling() != null && table.getPreviousSibling().getNodeType() == NodeType.PARAGRAPH) { - Paragraph previousPara = (Paragraph) table.getPreviousSibling(); - if (isHeadingParagraph(previousPara)) - previousPara.remove(); - } - - table.remove(); - } - } - } - - /** - * Returns true if the paragraph uses any Heading style e.g Heading 1 to - * Heading 9 - */ - private boolean isHeadingParagraph(Paragraph para) throws Exception { - return (para.getParagraphFormat().getStyleIdentifier() >= StyleIdentifier.HEADING_1 && para.getParagraphFormat().getStyleIdentifier() <= StyleIdentifier.HEADING_9); - } - - public void imageFieldMerging(ImageFieldMergingArgs args) throws Exception { - // Do Nothing - } - } - - public static class EmptyRegionsHandler_MergeTable implements IFieldMergingCallback { - /** - * Called for each field belonging to an unmerged region in the - * document. - */ - public void fieldMerging(FieldMergingArgs args) throws Exception { - // Store the parent paragraph of the current field for easy access. - Paragraph parentParagraph = args.getField().getStart().getParentParagraph(); - - // Define the logic to be used when the ContactDetails region is encountered. - // The region is removed and replaced with a single line of text stating that there are no records. - if ("ContactDetails".equals(args.getTableName())) { - // Called for the first field encountered in a region. This can be used to execute logic on the first field - // in the region without needing to hard code the field name. Often the base logic is applied to the first field and - // different logic for other fields. The rest of the fields in the region will have a null FieldValue. - if ("FirstField".equals(args.getFieldValue())) { - // Remove the "Name:" tag from the start of the paragraph - parentParagraph.getRange().replace("Name:", "", false, false); - // Set the text of the first field to display a message stating that there are no records. - args.setText("No records to display"); - } else { - // We have already inserted our message in the paragraph belonging to the first field. The other paragraphs in the region - // will still remain so we want to remove these. A check is added to ensure that the paragraph has not already been removed. - // which may happen if more than one field is included in a paragraph. - if (parentParagraph.getParentNode() != null) - parentParagraph.remove(); - } - } - - if ("Suppliers".equals(args.getTableName())) { - if ("FirstField".equals(args.getFieldValue())) { - // We will use the first paragraph to display our message. Make it centered within the table. The other fields in other cells - // within the table will be merged and won't be displayed so we don't need to do anything else with them. - parentParagraph.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); - args.setText("No records to display"); - } - - // Merge the cells of the table together. - Cell cell = (Cell) parentParagraph.getAncestor(NodeType.CELL); - if (cell != null) { - if (cell.isFirstCell()) - cell.getCellFormat().setHorizontalMerge(CellMerge.FIRST); // If this cell is the first cell in the table then the merge is started using "CellMerge.First". - else - cell.getCellFormat().setHorizontalMerge(CellMerge.PREVIOUS); // Otherwise the merge is continued using "CellMerge.Previous". - } - } - - } - - public void imageFieldMerging(ImageFieldMergingArgs args) throws Exception { - // Do Nothing - } - } - - /** - * Returns the data used to merge the TestFile document. This dataset - * purposely contains only rows for the StoreDetails region and only a - * select few for the child region. - */ - private static DataSet getDataSource() throws Exception { - // Create empty disconnected Java result sets. - ResultSet storeDetailsResultSet = createCachedRowSet(new String[] { "ID", "Name", "Address", "City", "Country" }); - ResultSet contactDetailsResultSet = createCachedRowSet(new String[] { "ID", "Name", "Number" }); - - // Create new Aspose.Words DataSet and DataTable objects to be used for mail merge. - DataSet data = new DataSet(); - DataTable storeDetails = new DataTable(storeDetailsResultSet, "StoreDetails"); - DataTable contactDetails = new DataTable(contactDetailsResultSet, "ContactDetails"); - - // Add the data to the tables. - addRow(storeDetailsResultSet, new String[] { "0", "Hungry Coyote Import Store", "2732 Baker Blvd", "Eugene", "USA" }); - addRow(storeDetailsResultSet, new String[] { "1", "Great Lakes Food Market", "City Center Plaza, 516 Main St.", "San Francisco", "USA" }); - - // Add data to the child table only for the first record. - addRow(contactDetailsResultSet, new String[] { "0", "Thomas Hardy", "(206) 555-9857 ext 237" }); - addRow(contactDetailsResultSet, new String[] { "0", "Elizabeth Brown", "(206) 555-9857 ext 764" }); - - // Include the tables in the DataSet. - data.getTables().add(storeDetails); - data.getTables().add(contactDetails); - - // Setup the relation between the parent table (StoreDetails) and the child table (ContactDetails). - data.getRelations().add(new DataRelation("StoreDetailsToContactDetails", storeDetails, contactDetails, new String[] { "ID" }, new String[] { "ID" })); - - return data; - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/mail_merge/ExecuteMailMergeWithRegions.java b/Examples/src/main/java/com/aspose/words/examples/mail_merge/ExecuteMailMergeWithRegions.java deleted file mode 100644 index 00b11d21..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/mail_merge/ExecuteMailMergeWithRegions.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.aspose.words.examples.mail_merge; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; -import com.aspose.words.net.System.Data.DataTable; - -public class ExecuteMailMergeWithRegions { - - private static final String dataDir = Utils.getSharedDataDir(ExecuteMailMergeWithRegions.class) + "MailMerge/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(dataDir + "MailMerge.ExecuteWithRegions.doc"); - - int orderId = 10444; - - // Perform several mail merge operations populating only part of the document each time. - // Use DataTable as a data source. - // The table name property should be set to match the name of the region defined in the document. - DataTable orderTable = getTestOrder(orderId); - doc.getMailMerge().executeWithRegions(orderTable); - - DataTable orderDetailsTable = getTestOrderDetails(orderId, "ExtendedPrice DESC"); - doc.getMailMerge().executeWithRegions(orderDetailsTable); - - doc.save(dataDir + "MailMerge.ExecuteWithRegionsDataTable Out.doc"); - } - - private static DataTable getTestOrder(int orderId) throws Exception { - java.sql.ResultSet resultSet = executeDataTable(java.text.MessageFormat.format("SELECT * FROM AsposeWordOrders WHERE OrderId = {0}", Integer.toString(orderId))); - - return new DataTable(resultSet, "Orders"); - } - - private static DataTable getTestOrderDetails(int orderId, String orderBy) throws Exception { - StringBuilder builder = new StringBuilder(); - - builder.append(java.text.MessageFormat.format("SELECT * FROM AsposeWordOrderDetails WHERE OrderId = {0}", Integer.toString(orderId))); - - if ((orderBy != null) && (orderBy.length() > 0)) { - builder.append(" ORDER BY "); - builder.append(orderBy); - } - - java.sql.ResultSet resultSet = executeDataTable(builder.toString()); - return new DataTable(resultSet, "OrderDetails"); - } - - /** - * Utility function that creates a connection, command, executes the command - * and return the result in a DataTable. - */ - private static java.sql.ResultSet executeDataTable(String commandText) throws Exception { - Class.forName("net.ucanaccess.jdbc.UcanaccessDriver"); - String connString = "jdbc:ucanaccess://" + dataDir + "Northwind.mdb"; - - // From Wikipedia: The Sun driver has a known issue with character encoding and Microsoft Access databases. - // Microsoft Access may use an encoding that is not correctly translated by the driver, leading to the replacement - // in strings of, for example, accented characters by question marks. - // - // In this case I have to set CP1252 for the European characters to come through in the data values. - java.util.Properties props = new java.util.Properties(); - props.put("charSet", "Cp1252"); - - // DSN-less DB connection. - java.sql.Connection conn = java.sql.DriverManager.getConnection(connString, props); - - // Create and execute a command. - java.sql.Statement statement = conn.createStatement(); - return statement.executeQuery(commandText); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/mail_merge/ExecuteSimpleMailMerge.java b/Examples/src/main/java/com/aspose/words/examples/mail_merge/ExecuteSimpleMailMerge.java deleted file mode 100644 index 37a178a4..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/mail_merge/ExecuteSimpleMailMerge.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.aspose.words.examples.mail_merge; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - -public class ExecuteSimpleMailMerge { - - private static final String dataDir = Utils.getSharedDataDir(ExecuteSimpleMailMerge.class) + "MailMerge/"; - - public static void main(String[] args) throws Exception { - // Open an existing document. - Document doc = new Document(dataDir + "MailMerge.ExecuteArray.doc"); - - // Trim trailing and leading whitespaces mail merge values - doc.getMailMerge().setTrimWhitespaces(false); - - // Fill the fields in the document with user data. - doc.getMailMerge().execute(new String[] { "FullName", "Company", "Address", "Address2", "City" }, - new Object[] { "James Bond", "MI5 Headquarters", "Milbank", "", "London" }); - - doc.save(dataDir + "MailMerge.ExecuteArray_Out.doc"); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/mail_merge/InsertCheckBoxesOrHTMLDuringMailMerge.java b/Examples/src/main/java/com/aspose/words/examples/mail_merge/InsertCheckBoxesOrHTMLDuringMailMerge.java deleted file mode 100644 index b1bc67ab..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/mail_merge/InsertCheckBoxesOrHTMLDuringMailMerge.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.aspose.words.examples.mail_merge; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.FieldMergingArgs; -import com.aspose.words.IFieldMergingCallback; -import com.aspose.words.ImageFieldMergingArgs; -import com.aspose.words.TextFormFieldType; -import com.aspose.words.examples.Utils; - -/** - * This sample shows how to insert check boxes and text input form fields during - * mail merge into a document. - */ -public class InsertCheckBoxesOrHTMLDuringMailMerge { - - private static final String dataDir = Utils.getSharedDataDir(InsertCheckBoxesOrHTMLDuringMailMerge.class) + "MailMerge/"; - - public static void main(String[] args) throws Exception { - execute(); - } - - private static void execute() throws Exception { - - // Load the template document. - Document doc = new Document(dataDir + "Template.doc"); - - // Setup mail merge event handler to do the custom work. - doc.getMailMerge().setFieldMergingCallback(new HandleMergeField()); - - // This is the data for mail merge. - String[] fieldNames = new String[] { "RecipientName", "SenderName", "FaxNumber", "PhoneNumber", "Subject", "Body", "Urgent", "ForReview", "PleaseComment" }; - Object[] fieldValues = new Object[] { "Josh", "Jenny", "123456789", "", "Hello", "HTML Body Test message 1", true, false, true }; - - // Execute the mail merge. - doc.getMailMerge().execute(fieldNames, fieldValues); - - // Save the finished document. - doc.save(dataDir + "Template Out.doc"); - } -} - -class HandleMergeField implements IFieldMergingCallback { - /** - * This handler is called for every mail merge field found in the document, - * for every record found in the data source. - */ - public void fieldMerging(FieldMergingArgs e) throws Exception { - if (mBuilder == null) - mBuilder = new DocumentBuilder(e.getDocument()); - - // We decided that we want all boolean values to be output as check box form fields. - if (e.getFieldValue() instanceof Boolean) { - // Move the "cursor" to the current merge field. - mBuilder.moveToMergeField(e.getFieldName()); - - // It is nice to give names to check boxes. Lets generate a name such as MyField21 or so. - String checkBoxName = java.text.MessageFormat.format("{0}{1}", e.getFieldName(), e.getRecordIndex()); - - // Insert a check box. - mBuilder.insertCheckBox(checkBoxName, (Boolean) e.getFieldValue(), 0); - - // Nothing else to do for this field. - return; - } - - // We want to insert html during mail merge. - if ("Body".equals(e.getFieldName())) { - mBuilder.moveToMergeField(e.getFieldName()); - mBuilder.insertHtml((String) e.getFieldValue()); - } - - // Another example, we want the Subject field to come out as text input form field. - if ("Subject".equals(e.getFieldName())) { - mBuilder.moveToMergeField(e.getFieldName()); - String textInputName = java.text.MessageFormat.format("{0}{1}", e.getFieldName(), e.getRecordIndex()); - mBuilder.insertTextInput(textInputName, TextFormFieldType.REGULAR, "", (String) e.getFieldValue(), 0); - } - } - - public void imageFieldMerging(ImageFieldMergingArgs args) throws Exception { - // Do nothing. - } - - private DocumentBuilder mBuilder; -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/mail_merge/InsertImagesFromADatabase.java b/Examples/src/main/java/com/aspose/words/examples/mail_merge/InsertImagesFromADatabase.java deleted file mode 100644 index 9a98b307..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/mail_merge/InsertImagesFromADatabase.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.aspose.words.examples.mail_merge; - -import java.io.ByteArrayInputStream; - -import com.aspose.words.Document; -import com.aspose.words.FieldMergingArgs; -import com.aspose.words.IFieldMergingCallback; -import com.aspose.words.ImageFieldMergingArgs; -import com.aspose.words.examples.Utils; -import com.aspose.words.net.System.Data.DataTable; - -public class InsertImagesFromADatabase { - - private static final String dataDir = Utils.getSharedDataDir(InsertImagesFromADatabase.class) + "MailMerge/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(dataDir + "MailMerge.MergeImage.doc"); - - // Set up the event handler for image fields. - doc.getMailMerge().setFieldMergingCallback(new HandleMergeImageFieldFromBlob()); - - Class.forName("net.ucanaccess.jdbc.UcanaccessDriver"); - String connString = "jdbc:ucanaccess://" + dataDir + "Northwind.mdb"; - - // DSN-less DB connection. - java.sql.Connection conn = java.sql.DriverManager.getConnection(connString); - - // Create and execute a command. - java.sql.Statement statement = conn.createStatement(); - java.sql.ResultSet resultSet = statement.executeQuery("SELECT * FROM Employees"); - - DataTable table = new DataTable(resultSet, "Employees"); - - // Perform mail merge. - doc.getMailMerge().executeWithRegions(table); - - // Close the database. - conn.close(); - - doc.save(dataDir + "MailMerge.MergeImage Out.doc"); - } -} - -class HandleMergeImageFieldFromBlob implements IFieldMergingCallback { - public void fieldMerging(FieldMergingArgs args) throws Exception { - // Do nothing. - } - - /** - * This is called when mail merge engine encounters Image:XXX merge - * field in the document. You have a chance to return an Image object, - * file name or a stream that contains the image. - */ - public void imageFieldMerging(ImageFieldMergingArgs e) throws Exception { - // The field value is a byte array, just cast it and create a stream on it. - ByteArrayInputStream imageStream = new ByteArrayInputStream((byte[]) e.getFieldValue()); - // Now the mail merge engine will retrieve the image from the stream. - e.setImageStream(imageStream); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/mail_merge/MailMergeFormFields.java b/Examples/src/main/java/com/aspose/words/examples/mail_merge/MailMergeFormFields.java deleted file mode 100644 index 3d9d5a9b..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/mail_merge/MailMergeFormFields.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.aspose.words.examples.mail_merge; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - - -/** - * This sample shows how to insert check boxes and text input form fields during mail merge into a document. - */ -public class MailMergeFormFields -{ - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(MailMergeFormFields.class); - - // Load the template document. - Document doc = new Document(dataDir + "Template.doc"); - - // Setup mail merge event handler to do the custom work. - doc.getMailMerge().setFieldMergingCallback(new HandleMergeField()); - - // This is the data for mail merge. - String[] fieldNames = new String[] {"RecipientName", "SenderName", "FaxNumber", "PhoneNumber", - "Subject", "Body", "Urgent", "ForReview", "PleaseComment"}; - Object[] fieldValues = new Object[] {"Josh", "Jenny", "123456789", "", "Hello", - "Test message 1", true, false, true}; - - // Execute the mail merge. - doc.getMailMerge().execute(fieldNames, fieldValues); - - // Save the finished document. - doc.save(dataDir + "Template Out.doc"); - - System.out.println("Mail merge performed successfully."); - } - - private static class HandleMergeField implements IFieldMergingCallback - { - /** - * This handler is called for every mail merge field found in the document, - * for every record found in the data source. - */ - public void fieldMerging(FieldMergingArgs e) throws Exception - { - if (mBuilder == null) - mBuilder = new DocumentBuilder(e.getDocument()); - - // We decided that we want all boolean values to be output as check box form fields. - if (e.getFieldValue() instanceof Boolean) - { - // Move the "cursor" to the current merge field. - mBuilder.moveToMergeField(e.getFieldName()); - - // It is nice to give names to check boxes. Lets generate a name such as MyField21 or so. - String checkBoxName = java.text.MessageFormat.format("{0}{1}", e.getFieldName(), e.getRecordIndex()); - - // Insert a check box. - mBuilder.insertCheckBox(checkBoxName, (Boolean)e.getFieldValue(), 0); - - - // Nothing else to do for this field. - return; - } - - // Another example, we want the Subject field to come out as text input form field. - if ("Subject".equals(e.getFieldName())) - { - mBuilder.moveToMergeField(e.getFieldName()); - String textInputName = java.text.MessageFormat.format("{0}{1}", e.getFieldName(), e.getRecordIndex()); - mBuilder.insertTextInput(textInputName, TextFormFieldType.REGULAR, "", (String)e.getFieldValue(), 0); - } - } - - public void imageFieldMerging(ImageFieldMergingArgs args) throws Exception - { - // Do nothing. - } - - private DocumentBuilder mBuilder; - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/mail_merge/MailMergeFromXMLUsingIMailMergeDataSource.java b/Examples/src/main/java/com/aspose/words/examples/mail_merge/MailMergeFromXMLUsingIMailMergeDataSource.java deleted file mode 100644 index 3228fa03..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/mail_merge/MailMergeFromXMLUsingIMailMergeDataSource.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.aspose.words.examples.mail_merge; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - -public class MailMergeFromXMLUsingIMailMergeDataSource { - - /** - * This sample demonstrates how to execute mail merge with data from an XML - * data source. The XML file is read into memory, stored in a DOM and passed - * to a custom data source implementing IMailMergeDataSource. This returns - * each value from XML when called by the mail merge engine. - */ - private static final String dataDir = Utils.getSharedDataDir(MailMergeFromXMLUsingIMailMergeDataSource.class) + "MailMerge/"; - - public static void main(String[] args) throws Exception { - - // Use DocumentBuilder from the javax.xml.parsers package and Document class from the org.w3c.dom package to read - // the XML data file and store it in memory. - DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - // Parse the XML data. - org.w3c.dom.Document xmlData = db.parse(dataDir + "Customers.xml"); - - // Open a template document. - Document doc = new Document(dataDir + "TestFile.doc"); - - // Note that this class also works with a single repeatable region (and any nested regions). - // To merge multiple regions at the same time from a single XML data source, use the XmlMailMergeDataSet class. - // e.g doc.getMailMerge().executeWithRegions(new XmlMailMergeDataSet(xmlData)); - doc.getMailMerge().execute(new XmlMailMergeDataTable(xmlData, "customer")); - - // Save the output document. - doc.save(dataDir + "TestFile Out.doc"); - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/mail_merge/MailMergeUsingMustacheTemplateSyntax.java b/Examples/src/main/java/com/aspose/words/examples/mail_merge/MailMergeUsingMustacheTemplateSyntax.java deleted file mode 100644 index c26998d2..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/mail_merge/MailMergeUsingMustacheTemplateSyntax.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.aspose.words.examples.mail_merge; - -import javax.xml.parsers.DocumentBuilderFactory; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - -public class MailMergeUsingMustacheTemplateSyntax { - - private static final String dataDir = Utils.getSharedDataDir(MailMergeUsingMustacheTemplateSyntax.class) + "MailMerge/"; - - public static void main(String[] args) throws Exception { - // Performs a simple insertion of data into merge fields and sends the document to the browser inline. - simpleInsertionOfDataIntoMergeFields(); - - useMailMergeUsingMustacheSyntax(); - } - - public static void simpleInsertionOfDataIntoMergeFields() throws Exception { - // Open an existing document. - Document doc = new Document(dataDir + "MailMerge.ExecuteArray.doc"); - - doc.getMailMerge().setUseNonMergeFields(true); - - // Fill the fields in the document with user data. - doc.getMailMerge().execute(new String[] { "FullName", "Company", "Address", "Address2", "City" }, new Object[] { "James Bond", "MI5 Headquarters", "Milbank", "", "London" }); - - doc.save(dataDir + "MailMerge.ExecuteArray_Out.doc"); - } - - public static void useMailMergeUsingMustacheSyntax() throws Exception { - // Use DocumentBuilder from the javax.xml.parsers package and Document class from the org.w3c.dom package to read - // the XML data file and store it in memory. - javax.xml.parsers.DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - - // Parse the XML data. - org.w3c.dom.Document xmlData = db.parse(dataDir + "Vendors.xml"); - - // Open a template document. - Document doc = new Document(dataDir + "VendorTemplate.doc"); - - doc.getMailMerge().setUseNonMergeFields(true); - // Note that this class also works with a single repeatable region (and any nested regions). - // To merge multiple regions at the same time from a single XML data source, use the XmlMailMergeDataSet class. - // e.g doc.getMailMerge().executeWithRegions(new XmlMailMergeDataSet(xmlData)); - doc.getMailMerge().executeWithRegions(new XmlMailMergeDataSet(xmlData)); - - // Save the output document. - doc.save(dataDir + "MailMergeUsingMustacheSyntax_Out.docx"); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/mail_merge/MultipleDocsInMailMerge.java b/Examples/src/main/java/com/aspose/words/examples/mail_merge/MultipleDocsInMailMerge.java deleted file mode 100644 index 1544a342..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/mail_merge/MultipleDocsInMailMerge.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.aspose.words.examples.mail_merge; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - -import java.io.File; -import java.sql.*; -import java.text.MessageFormat; -import java.util.Hashtable; - - -public class MultipleDocsInMailMerge -{ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(MultipleDocsInMailMerge.class); - - produceMultipleDocuments(dataDir, "TestFile.doc"); - } - - public static void produceMultipleDocuments(String dataDir, String srcDoc) throws Exception - { - // Open the database connection. - ResultSet rs = getData(dataDir, "SELECT * FROM Customers"); - - // Open the template document. - Document doc = new Document(dataDir + srcDoc); - - // A record of how many documents that have been generated so far. - int counter = 1; - - // Loop though all records in the data source. - while(rs.next()) - { - // Clone the template instead of loading it from disk (for speed). - Document dstDoc = (Document)doc.deepClone(true); - - // Extract the data from the current row of the ResultSet into a Hashtable. - Hashtable dataMap = getRowData(rs); - - // Execute mail merge. - dstDoc.getMailMerge().execute(keySetToArray(dataMap), dataMap.values().toArray()); - - // Save the document. - dstDoc.save(MessageFormat.format(dataDir + "TestFile Out {0}.doc", counter++)); - } - } - - /** - * Creates a Hashtable from the name and value of each column in the current row of the ResultSet. - */ - public static Hashtable getRowData(ResultSet rs) throws Exception - { - ResultSetMetaData metaData = rs.getMetaData(); - Hashtable values = new Hashtable(); - - for(int i = 1; i <= metaData.getColumnCount(); i++) - { - values.put(metaData.getColumnName(i), rs.getObject(i)); - } - - return values; - } - - /** - * Utility function that returns the keys of a Hashtable as an array of Strings. - */ - public static String[] keySetToArray(Hashtable table) - { - return (String[])table.keySet().toArray(new String[table.size()]); - } - - /** - * Utility function that creates a connection to the Database. - */ - public static ResultSet getData(String dataDir, String query) throws Exception - { - // Load a DB driver that is used by the demos - Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); - // Compose connection string. - String connectionString = "jdbc:odbc:DRIVER={Microsoft Access Driver (*.mdb)};" + - "DBQ=" + new File(dataDir, "Customers.mdb") + ";UID=Admin"; - // DSN-less DB connection. - Connection connection = DriverManager.getConnection(connectionString); - - Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); - - return statement.executeQuery(query); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/mail_merge/MustacheTemplateSyntax.java b/Examples/src/main/java/com/aspose/words/examples/mail_merge/MustacheTemplateSyntax.java deleted file mode 100644 index 631fd433..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/mail_merge/MustacheTemplateSyntax.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.aspose.words.examples.mail_merge; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; -import javax.xml.parsers.DocumentBuilderFactory; - -public class MustacheTemplateSyntax { - - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(MustacheTemplateSyntax.class); - - // Use DocumentBuilder from the javax.xml.parsers package and Document class from the org.w3c.dom package to read - // the XML data file and store it in memory. - javax.xml.parsers.DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - - // Parse the XML data. - org.w3c.dom.Document xmlData = db.parse(dataDir + "Orders.xml"); - - // Open a template document. - Document doc = new Document(dataDir + "ExecuteTemplate.doc"); - - doc.getMailMerge().setUseNonMergeFields(true); - - // Note that this class also works with a single repeatable region (and any nested regions). - // To merge multiple regions at the same time from a single XML data source, use the XmlMailMergeDataSet class. - // e.g doc.getMailMerge().executeWithRegions(new XmlMailMergeDataSet(xmlData)); - doc.getMailMerge().executeWithRegions(new XmlMailMergeDataSet(xmlData)); - - // Save the output document. - doc.save(dataDir + "Output.docx"); - - System.out.println("Mail merge performed successfully."); - } - -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/mail_merge/NestedMailMergeRegions.java b/Examples/src/main/java/com/aspose/words/examples/mail_merge/NestedMailMergeRegions.java deleted file mode 100644 index f95332ad..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/mail_merge/NestedMailMergeRegions.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.aspose.words.examples.mail_merge; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.Statement; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; -import com.aspose.words.net.System.Data.DataRelation; -import com.aspose.words.net.System.Data.DataSet; -import com.aspose.words.net.System.Data.DataTable; - -public class NestedMailMergeRegions { - - private static final String dataDir = Utils.getSharedDataDir(NestedMailMergeRegions.class) + "MailMerge/"; - private static Connection mConnection; - - public static void main(String[] args) throws Exception { - - // Create the dataset which will hold each DataTable used for mail merge. - DataSet pizzaDs = new DataSet(); - - // Create a connection to the database - createConnection(dataDir); - - // Populate each DataTable from the database. Each query which returns a ResultSet object containing the data from the table. - // This ResultSet is wrapped into an Aspose.Words implementation of the DataTable class and added to a DataSet. - DataTable orders = new DataTable(executeQuery("SELECT * from Orders"), "Orders"); - pizzaDs.getTables().add(orders); - - DataTable itemDetails = new DataTable(executeQuery("SELECT * from Items"), "Items"); - pizzaDs.getTables().add(itemDetails); - - // In order for nested mail merge to work, the mail merge engine must know the relation between parent and child tables. - // Add a DataRelation to specify relations between these tables. - pizzaDs.getRelations().add(new DataRelation("OrderToItemDetails", orders, itemDetails, new String[] { "OrderID" }, new String[] { "OrderID" })); - - // Open the template document. - Document doc = new Document(dataDir + "Invoice Template.doc"); - - // Trim trailing and leading whitespaces mail merge values - //doc.getMailMerge().setTrimWhitespaces(false); - - // Execute nested mail merge with regions - doc.getMailMerge().executeWithRegions(pizzaDs); - - // Save the output to disk - doc.save(dataDir + "Invoice Out.doc"); - - assert doc.getMailMerge().getFieldNames().length == 0 : "There was a problem with mail merge"; - } - - /** - * Executes a query to the demo database using a new statement and returns - * the result in a ResultSet. - */ - protected static ResultSet executeQuery(String query) throws Exception { - return createStatement().executeQuery(query); - } - - /** - * Utility function that creates a connection to the Database. - */ - public static void createConnection(String dataDir) throws Exception { - Class.forName("net.ucanaccess.jdbc.UcanaccessDriver"); - String connectionString = "jdbc:ucanaccess://" + dataDir + "InvoiceDB.mdb"; - - // Create a connection to the database. - mConnection = DriverManager.getConnection(connectionString); - } - - /** - * Utility function that creates a statement to the database. - */ - public static Statement createStatement() throws Exception { - return mConnection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/mail_merge/ProduceMultipleDocumentsDuringMailMerge.java b/Examples/src/main/java/com/aspose/words/examples/mail_merge/ProduceMultipleDocumentsDuringMailMerge.java deleted file mode 100644 index 1d7c939d..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/mail_merge/ProduceMultipleDocumentsDuringMailMerge.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.aspose.words.examples.mail_merge; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - -import java.sql.*; -import java.text.MessageFormat; -import java.util.Hashtable; - -public class ProduceMultipleDocumentsDuringMailMerge { - - private static final String dataDir = Utils.getSharedDataDir(ProduceMultipleDocumentsDuringMailMerge.class) + "MailMerge/"; - - public static void main(String[] args) throws Exception { - - produceMultipleDocuments(dataDir, "TestFile.doc"); - } - - public static void produceMultipleDocuments(String dataDir, String srcDoc) throws Exception { - // Open the database connection. - ResultSet rs = getData(dataDir, "SELECT * FROM Customers"); - - // Open the template document. - Document doc = new Document(dataDir + srcDoc); - - // A record of how many documents that have been generated so far. - int counter = 1; - - // Loop though all records in the data source. - while (rs.next()) { - // Clone the template instead of loading it from disk (for speed). - Document dstDoc = (Document) doc.deepClone(true); - - // Extract the data from the current row of the ResultSet into a Hashtable. - Hashtable dataMap = getRowData(rs); - - // Execute mail merge. - dstDoc.getMailMerge().execute(keySetToArray(dataMap), dataMap.values().toArray()); - - // Save the document. - dstDoc.save(MessageFormat.format(dataDir + "TestFile Out {0}.doc", counter++)); - } - } - - /** - * Creates a Hashtable from the name and value of each column in the current - * row of the ResultSet. - */ - public static Hashtable getRowData(ResultSet rs) throws Exception { - ResultSetMetaData metaData = rs.getMetaData(); - Hashtable values = new Hashtable(); - - for (int i = 1; i <= metaData.getColumnCount(); i++) { - values.put(metaData.getColumnName(i), rs.getObject(i)); - } - - return values; - } - - /** - * Utility function that returns the keys of a Hashtable as an array of - * Strings. - */ - public static String[] keySetToArray(Hashtable table) { - return (String[]) table.keySet().toArray(new String[table.size()]); - } - - /** - * Utility function that creates a connection to the Database. - */ - public static ResultSet getData(String dataDir, String query) throws Exception { - - Class.forName("net.ucanaccess.jdbc.UcanaccessDriver"); - String connectionString = "jdbc:ucanaccess://" + dataDir + "Customers.mdb"; - - // DSN-less DB connection. - Connection connection = DriverManager.getConnection(connectionString); - - Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); - - return statement.executeQuery(query); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/mail_merge/RemoveEmptyRegions.java b/Examples/src/main/java/com/aspose/words/examples/mail_merge/RemoveEmptyRegions.java deleted file mode 100644 index 3e455208..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/mail_merge/RemoveEmptyRegions.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.aspose.words.examples.mail_merge; - -import com.aspose.words.Document; -import com.aspose.words.MailMergeCleanupOptions; -import com.aspose.words.examples.Utils; -import com.aspose.words.net.System.Data.DataSet; - - -public class RemoveEmptyRegions -{ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(RemoveEmptyRegions.class); - - // Open the document. - Document doc = new Document(dataDir + "TestFile.doc"); - - // Create a dummy data source containing no data. - DataSet data = new DataSet(); - - // Set the appropriate mail merge clean up options to remove any unused regions from the document. - doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_UNUSED_REGIONS); - - // Execute mail merge which will have no effect as there is no data. However the regions found in the document will be removed - // automatically as they are unused. - doc.getMailMerge().executeWithRegions(data); - - // Save the output document to disk. - doc.save(dataDir + "Output.doc"); - - assert doc.getMailMerge().getFieldNames().length == 0: "Error: There are still unused regions remaining in the document"; - - System.out.println("Non empty regions removed during mail merge successfully."); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/mail_merge/RemoveUnmergedRegions.java b/Examples/src/main/java/com/aspose/words/examples/mail_merge/RemoveUnmergedRegions.java deleted file mode 100644 index 56660d30..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/mail_merge/RemoveUnmergedRegions.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.aspose.words.examples.mail_merge; - -import com.aspose.words.Document; -import com.aspose.words.MailMergeCleanupOptions; -import com.aspose.words.examples.Utils; -import com.aspose.words.net.System.Data.DataSet; - -public class RemoveUnmergedRegions { - - private static final String dataDir = Utils.getSharedDataDir(RemoveUnmergedRegions.class) + "MailMerge/"; - - public static void main(String[] args) throws Exception { - - // Open the document. - Document doc = new Document(dataDir + "TestFile.doc"); - - // Create a dummy data source containing no data. - DataSet data = new DataSet(); - - // Set the appropriate mail merge clean up options to remove any unused regions from the document. - doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_UNUSED_REGIONS); - - // Execute mail merge which will have no effect as there is no data. However the regions found in the document will be removed - // automatically as they are unused. - doc.getMailMerge().executeWithRegions(data); - - // Save the output document to disk. - doc.save(dataDir + "TestFile.RemoveEmptyRegions Out.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/mail_merge/XMLMailMerge.java b/Examples/src/main/java/com/aspose/words/examples/mail_merge/XMLMailMerge.java deleted file mode 100644 index 4d5ab581..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/mail_merge/XMLMailMerge.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.aspose.words.examples.mail_merge; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; - -/** - * This sample demonstrates how to execute mail merge with data from an XML data - * source. The XML file is read into memory, stored in a DOM and passed to a - * custom data source implementing IMailMergeDataSource. This returns each value - * from XML when called by the mail merge engine. - */ -public class XMLMailMerge { - - private static final String dataDir = Utils.getSharedDataDir(XMLMailMerge.class) + "MailMerge/"; - - public static void main(String[] args) throws Exception { - - // Use DocumentBuilder from the javax.xml.parsers package and Document class from the org.w3c.dom package to read - // the XML data file and store it in memory. - DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - // Parse the XML data. - org.w3c.dom.Document xmlData = db.parse(dataDir + "Customers.xml"); - - // Open a template document. - Document doc = new Document(dataDir + "TestFile.doc"); - - // Note that this class also works with a single repeatable region (and any nested regions). - // To merge multiple regions at the same time from a single XML data source, use the XmlMailMergeDataSet class. - // e.g doc.getMailMerge().executeWithRegions(new XmlMailMergeDataSet(xmlData)); - doc.getMailMerge().execute(new XmlMailMergeDataTable(xmlData, "customer")); - - // Save the output document. - doc.save(dataDir + "TestFile Out.doc"); - - System.out.println("Mail merge performed successfully."); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/mail_merge/XmlMailMergeDataSet.java b/Examples/src/main/java/com/aspose/words/examples/mail_merge/XmlMailMergeDataSet.java deleted file mode 100644 index ff9c1612..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/mail_merge/XmlMailMergeDataSet.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.aspose.words.examples.mail_merge; - -import com.aspose.words.IMailMergeDataSource; -import com.aspose.words.IMailMergeDataSourceRoot; - -public class XmlMailMergeDataSet implements IMailMergeDataSourceRoot -{ - /** - * Creates a new XmlMailMergeDataSet for the specified XML document. All regions in the document can be - * merged at once using this class. - * - * @param xmlDoc The DOM object which contains the parsed XML data. - */ - public XmlMailMergeDataSet(org.w3c.dom.Document xmlDoc) - { - mXmlDoc = xmlDoc; - } - - public IMailMergeDataSource getDataSource(String tableName) throws Exception - { - return new XmlMailMergeDataTable(mXmlDoc, tableName); - } - - private org.w3c.dom.Document mXmlDoc; -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/mail_merge/XmlMailMergeDataTable.java b/Examples/src/main/java/com/aspose/words/examples/mail_merge/XmlMailMergeDataTable.java deleted file mode 100644 index 4fa02905..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/mail_merge/XmlMailMergeDataTable.java +++ /dev/null @@ -1,150 +0,0 @@ -package com.aspose.words.examples.mail_merge; - -import com.aspose.words.IMailMergeDataSource; -import org.w3c.dom.Element; -import org.w3c.dom.Node; - -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpression; -import javax.xml.xpath.XPathFactory; -import java.util.HashMap; - -/** - * A custom mail merge data source that allows you to merge data from an XML - * document into Word templates. This class demonstrates how data can be read - * from a custom data source (XML parsed and loaded into a DOM) and merged into - * a document using the IMailMergeDataSource interface. - * - * An instance of this class represents a single table in the data source and in - * the template. Note: We are using the Document and Node class from the - * org.w3c.dom package here and not from Aspose.Words. - */ -public class XmlMailMergeDataTable implements IMailMergeDataSource { - /** - * Creates a new XmlMailMergeDataSource for the specified XML document and - * table name. - * - * @param xmlDoc - * The DOM object which contains the parsed XML data. - * @param tableName - * The name of the element in the data source where the data of - * the region is extracted from. - */ - public XmlMailMergeDataTable(org.w3c.dom.Document xmlDoc, String tableName) throws Exception { - this(xmlDoc.getDocumentElement(), tableName); - } - - /** - * Private constructor that is also called by GetChildDataSource. - */ - private XmlMailMergeDataTable(Node rootNode, String tableName) throws Exception { - mTableName = tableName; - - // Get the first element on this level matching the table name. - mCurrentNode = (Node) retrieveExpression("./" + tableName).evaluate(rootNode, XPathConstants.NODE); - } - - /** - * The name of the data source. Used by Aspose.Words only when executing - * mail merge with repeatable regions. - */ - public String getTableName() { - return mTableName; - } - - /** - * Aspose.Words calls this method to get a value for every data field. - */ - public boolean getValue(String fieldName, Object[] fieldValue) throws Exception { - // Attempt to retrieve the child node matching the field name by using XPath. - Node value = (Node) retrieveExpression(fieldName).evaluate(mCurrentNode, XPathConstants.NODE); - // We also look for the field name in attributes of the element node. - Element nodeAsElement = (Element) mCurrentNode; - - if (value != null) { - // Field exists in the data source as a child node, pass the value and return true. - // This merges the data into the document. - fieldValue[0] = value.getTextContent(); - return true; - } else if (nodeAsElement.hasAttribute(fieldName)) { - // Field exists in the data source as an attribute of the current node, pass the value and return true. - // This merges the data into the document. - fieldValue[0] = nodeAsElement.getAttribute(fieldName); - return true; - } else { - // Field does not exist in the data source, return false. - // No value will be merged for this field and it is left over in the document. - return false; - } - } - - /** - * Moves to the next record in a collection. This method is a little - * different then the regular implementation as we are walking over an XML - * document stored in a DOM. - */ - public boolean moveNext() { - if (!isEof()) { - // Don't move to the next node if this the first record to be merged. - if (!mIsFirstRecord) { - // Find the next node which is an element and matches the table name represented by this class. - // This skips any text nodes and any elements which belong to a different table. - do { - mCurrentNode = mCurrentNode.getNextSibling(); - } while ((mCurrentNode != null) && !(mCurrentNode.getNodeName().equals(mTableName) && (mCurrentNode.getNodeType() == Node.ELEMENT_NODE))); - } else { - mIsFirstRecord = false; - } - } - - return (!isEof()); - } - - /** - * If the data source contains nested data this method will be called to - * retrieve the data for the child table. In the XML data source nested data - * this should look like this: - * - * - * - * ParentName - * - * Content - * - * - * - */ - public IMailMergeDataSource getChildDataSource(String tableName) throws Exception { - return new XmlMailMergeDataTable(mCurrentNode, tableName); - } - - private boolean isEof() { - return (mCurrentNode == null); - } - - /** - * Returns a cached version of a compiled XPathExpression if available, - * otherwise creates a new expression. - */ - private XPathExpression retrieveExpression(String path) throws Exception { - XPathExpression expression; - - if (mExpressionSet.containsKey(path)) { - expression = (XPathExpression) mExpressionSet.get(path); - } else { - expression = mXPath.compile(path); - mExpressionSet.put(path, expression); - } - return expression; - } - - /** - * Instance variables. - */ - private Node mCurrentNode; - private boolean mIsFirstRecord = true; - private final String mTableName; - private final HashMap mExpressionSet = new HashMap(); - private final XPath mXPath = XPathFactory.newInstance().newXPath(); -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/HeadersAndFooters/CreateHeadersFootersUsingDocumentBuilder.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/HeadersAndFooters/CreateHeadersFootersUsingDocumentBuilder.java deleted file mode 100644 index c2bd1bc7..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/HeadersAndFooters/CreateHeadersFootersUsingDocumentBuilder.java +++ /dev/null @@ -1,154 +0,0 @@ -package com.aspose.words.examples.programming_documents.HeadersAndFooters; - -import com.aspose.words.BreakType; -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.HeaderFooter; -import com.aspose.words.HeaderFooterType; -import com.aspose.words.Orientation; -import com.aspose.words.PageSetup; -import com.aspose.words.ParagraphAlignment; -import com.aspose.words.PreferredWidth; -import com.aspose.words.RelativeHorizontalPosition; -import com.aspose.words.RelativeVerticalPosition; -import com.aspose.words.Row; -import com.aspose.words.Section; -import com.aspose.words.WrapType; -import com.aspose.words.examples.Utils; -import com.aspose.words.examples.programming_documents.tables.creation.BuildTableFromDataTable; - -public class CreateHeadersFootersUsingDocumentBuilder { - - private static final String dataDir = Utils.getSharedDataDir(CreateHeadersFootersUsingDocumentBuilder.class) + "HeadersAndFooters/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - Section currentSection = builder.getCurrentSection(); - PageSetup pageSetup = currentSection.getPageSetup(); - - // Specify if we want headers/footers of the first page to be different from other pages. - // You can also use PageSetup.OddAndEvenPagesHeaderFooter property to specify - // different headers/footers for odd and even pages. - pageSetup.setDifferentFirstPageHeaderFooter(true); - - // --- Create header for the first page. --- - pageSetup.setHeaderDistance(20); - builder.moveToHeaderFooter(HeaderFooterType.HEADER_FIRST); - builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); - - // Set font properties for header text. - builder.getFont().setName("Arial"); - builder.getFont().setBold(true); - builder.getFont().setSize(14); - // Specify header title for the first page. - builder.write("Aspose.Words Header/Footer Creation Primer - Title Page."); - - // --- Create header for pages other than first. --- - pageSetup.setHeaderDistance(20); - builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); - - // Insert absolutely positioned image into the top/left corner of the header. - // Distance from the top/left edges of the page is set to 10 points. - String imageFileName = dataDir + "Aspose.Words.gif"; - builder.insertImage(imageFileName, RelativeHorizontalPosition.PAGE, 10, RelativeVerticalPosition.PAGE, 10, 50, 50, WrapType.THROUGH); - - builder.getParagraphFormat().setAlignment(ParagraphAlignment.RIGHT); - // Specify another header title for other pages. - builder.write("Aspose.Words Header/Footer Creation Primer."); - - // --- Create footer for pages other than first. --- - builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); - - // We use table with two cells to make one part of the text on the line (with page numbering) - // to be aligned left, and the other part of the text (with copyright) to be aligned right. - builder.startTable(); - - // Clear table borders - builder.getCellFormat().clearFormatting(); - - builder.insertCell(); - // Set first cell to 1/3 of the page width. - builder.getCellFormat().setPreferredWidth(PreferredWidth.fromPercent(100 / 3)); - - // Insert page numbering text here. - // It uses PAGE and NUMPAGES fields to auto calculate current page number and total number of pages. - builder.write("Page "); - builder.insertField("PAGE", ""); - builder.write(" of "); - builder.insertField("NUMPAGES", ""); - - // Align this text to the left. - builder.getCurrentParagraph().getParagraphFormat().setAlignment(ParagraphAlignment.LEFT); - - builder.insertCell(); - // Set the second cell to 2/3 of the page width. - builder.getCellFormat().setPreferredWidth(PreferredWidth.fromPercent(100 * 2 / 3)); - - builder.write("(C) 2001 Aspose Pty Ltd. All rights reserved."); - - // Align this text to the right. - builder.getCurrentParagraph().getParagraphFormat().setAlignment(ParagraphAlignment.RIGHT); - - builder.endRow(); - builder.endTable(); - - builder.moveToDocumentEnd(); - // Make page break to create a second page on which the primary headers/footers will be seen. - builder.insertBreak(BreakType.PAGE_BREAK); - - // Make section break to create a third page with different page orientation. - builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); - - // Get the new section and its page setup. - currentSection = builder.getCurrentSection(); - pageSetup = currentSection.getPageSetup(); - - // Set page orientation of the new section to landscape. - pageSetup.setOrientation(Orientation.LANDSCAPE); - - // This section does not need different first page header/footer. - // We need only one title page in the document and the header/footer for this page - // has already been defined in the previous section - pageSetup.setDifferentFirstPageHeaderFooter(false); - - // This section displays headers/footers from the previous section by default. - // Call currentSection.HeadersFooters.LinkToPrevious(false) to cancel this. - // Page width is different for the new section and therefore we need to set - // a different cell widths for a footer table. - currentSection.getHeadersFooters().linkToPrevious(false); - - // If we want to use the already existing header/footer set for this section - // but with some minor modifications then it may be expedient to copy headers/footers - // from the previous section and apply the necessary modifications where we want them. - copyHeadersFootersFromPreviousSection(currentSection); - - // Find the footer that we want to change. - HeaderFooter primaryFooter = currentSection.getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY); - - Row row = primaryFooter.getTables().get(0).getFirstRow(); - row.getFirstCell().getCellFormat().setPreferredWidth(PreferredWidth.fromPercent(100 / 3)); - row.getLastCell().getCellFormat().setPreferredWidth(PreferredWidth.fromPercent(100 * 2 / 3)); - - // Save the resulting document. - doc.save(dataDir + "HeaderFooter.Primer_Out.doc"); - } - - /** - * Clones and copies headers/footers form the previous section to the specified section. - */ - private static void copyHeadersFootersFromPreviousSection(Section section) throws Exception - { - Section previousSection = (Section)section.getPreviousSibling(); - - if (previousSection == null) - return; - - section.getHeadersFooters().clear(); - - for (HeaderFooter headerFooter : previousSection.getHeadersFooters()) - section.getHeadersFooters().add(headerFooter.deepClone(true)); - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/HeadersAndFooters/RemoveFootersButLeaveHeadersIntact.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/HeadersAndFooters/RemoveFootersButLeaveHeadersIntact.java deleted file mode 100644 index 32af5904..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/HeadersAndFooters/RemoveFootersButLeaveHeadersIntact.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.aspose.words.examples.programming_documents.HeadersAndFooters; - -import com.aspose.words.Document; -import com.aspose.words.HeaderFooter; -import com.aspose.words.HeaderFooterType; -import com.aspose.words.Section; -import com.aspose.words.examples.Utils; -import com.aspose.words.examples.programming_documents.tables.creation.BuildTableFromDataTable; - -public class RemoveFootersButLeaveHeadersIntact { - - private static final String dataDir = Utils.getSharedDataDir(BuildTableFromDataTable.class) + "HeadersAndFooters/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(dataDir + "HeaderFooter.RemoveFooters.doc"); - - for (Section section : doc.getSections()) { - // Up to three different footers are possible in a section (for first, even and odd pages). - // We check and delete all of them. - HeaderFooter footer; - - footer = section.getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_FIRST); - if (footer != null) - footer.remove(); - - // Primary footer is the footer used for odd pages. - footer = section.getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY); - if (footer != null) - footer.remove(); - - footer = section.getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_EVEN); - if (footer != null) - footer.remove(); - } - - doc.save(dataDir + "HeaderFooter.RemoveFooters Out.doc"); - - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/Hyperlink/ReplaceHyperlinks.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/Hyperlink/ReplaceHyperlinks.java deleted file mode 100644 index f1d24333..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/Hyperlink/ReplaceHyperlinks.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.aspose.words.examples.programming_documents.Hyperlink; - -import com.aspose.words.Document; -import com.aspose.words.Field; -import com.aspose.words.FieldHyperlink; -import com.aspose.words.FieldType; -import com.aspose.words.examples.Utils; - -public class ReplaceHyperlinks { - - // The path to the documents directory. - private static final String dataDir = Utils.getSharedDataDir(ReplaceHyperlinks.class) + "Hyperlink/"; - - public static void main(String[] args) throws Exception { - - String newUrl = "http://www.aspose.com"; - String newName = "Aspose - The .NET & Java Component Publisher"; - - // Open the document. - Document doc = new Document(dataDir + "ReplaceHyperlinks.docx"); - for (Field field : doc.getRange().getFields()) { - if (field.getType() == FieldType.FIELD_HYPERLINK) { - FieldHyperlink hyperlink = (FieldHyperlink) field; - - // Some hyperlinks can be local (links to bookmarks inside the document), ignore these. - if (hyperlink.getSubAddress() != null) - continue; - - hyperlink.setAddress(newUrl); - hyperlink.setResult(newName); - } - doc.save(dataDir + "ReplaceHyperlinks_Out.doc"); - } - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/Ranges/RangesDeleteText.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/Ranges/RangesDeleteText.java deleted file mode 100644 index fbb78af7..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/Ranges/RangesDeleteText.java +++ /dev/null @@ -1,24 +0,0 @@ - -package com.aspose.words.examples.programming_documents.Ranges; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - - -public class RangesDeleteText -{ - private static String gDataDir; - - public static void main(String[] args) throws Exception - { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(RangesDeleteText.class); - - Document doc = new Document(dataDir + "Document.doc"); - doc.getSections().get(0).getRange().delete(); - - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/Ranges/RangesGetText.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/Ranges/RangesGetText.java deleted file mode 100644 index d08f3e44..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/Ranges/RangesGetText.java +++ /dev/null @@ -1,24 +0,0 @@ - -package com.aspose.words.examples.programming_documents.Ranges; - -import com.aspose.words.Document; -import com.aspose.words.ImportFormatMode; -import com.aspose.words.examples.Utils; - - -public class RangesGetText -{ - private static String gDataDir; - - public static void main(String[] args) throws Exception - { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(RangesGetText.class); - - Document doc = new Document(dataDir + "Document.doc"); - String text = doc.getText(); - System.out.println(text); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/Theme/GetThemeProperties.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/Theme/GetThemeProperties.java deleted file mode 100644 index 7c359bc7..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/Theme/GetThemeProperties.java +++ /dev/null @@ -1,27 +0,0 @@ - -package com.aspose.words.examples.programming_documents.Theme; - -import com.aspose.words.Document; -import com.aspose.words.Theme; -import com.aspose.words.examples.Utils; - - -public class GetThemeProperties { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(GetThemeProperties.class); - - Document doc = new Document(dataDir + "Document.doc"); - - Theme theme = doc.getTheme(); - // Major (Headings) font for Latin characters. - System.out.println(theme.getMajorFonts().getLatin()); - // Minor (Body) font for EastAsian characters. - System.out.println(theme.getMinorFonts().getEastAsian()); - // Color for theme color Accent 1. - System.out.println(theme.getColors().getAccent1()); - - //System.out.println("Table auto fit to contents successfully."); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/Theme/SetThemeProperties.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/Theme/SetThemeProperties.java deleted file mode 100644 index 4c6dce93..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/Theme/SetThemeProperties.java +++ /dev/null @@ -1,28 +0,0 @@ - -package com.aspose.words.examples.programming_documents.Theme; - -import com.aspose.words.Document; -import com.aspose.words.Theme; -import com.aspose.words.examples.Utils; -import javafx.scene.paint.Color; - - -public class SetThemeProperties -{ - public static void main(String[] args) throws Exception - { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(SetThemeProperties.class); - - Document doc = new Document(dataDir +"Document.doc"); - - Theme theme = doc.getTheme(); - // Set Times New Roman font as Body theme font for Latin Character. - theme.getMinorFonts().setLatin("Algerian"); - // Set Color.Gold for theme color Hyperlink. - theme.getColors().setHyperlink(java.awt.Color.DARK_GRAY); - doc.save(dataDir+ "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/AccessBookmarks.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/AccessBookmarks.java deleted file mode 100644 index d7b9c122..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/AccessBookmarks.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.aspose.words.examples.programming_documents.bookmarks; - -import com.aspose.words.Bookmark; -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - - -public class AccessBookmarks { - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(AccessBookmarks.class); - Document doc = new Document(dataDir + "Bookmark.doc"); - Bookmark bookmark1 = doc.getRange().getBookmarks().get(0); - - Bookmark bookmark = doc.getRange().getBookmarks().get("MyBookmark"); - doc.save(dataDir + "output.doc"); - System.out.println("\nTable bookmarked successfully.\nFile saved at " + dataDir); - } - -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/BookmarkNameAndText.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/BookmarkNameAndText.java deleted file mode 100644 index 1891193f..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/BookmarkNameAndText.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.aspose.words.examples.programming_documents.bookmarks; - -import com.aspose.words.Bookmark; -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - - -public class BookmarkNameAndText -{ - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(BookmarkNameAndText.class); - - Document doc = new Document(dataDir + "Bookmark.doc"); - // Use the indexer of the Bookmarks collection to obtain the desired bookmark. - Bookmark bookmark = doc.getRange().getBookmarks().get("MyBookmark"); - - // Get the name and text of the bookmark. - String name = bookmark.getName(); - String text = bookmark.getText(); - - // Set the name and text of the bookmark. - bookmark.setName("RenamedBookmark"); - bookmark.setText("This is a new bookmarked text."); - System.out.println("\nBookmark name and text set successfully."); - - } - -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/BookmarkTable.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/BookmarkTable.java deleted file mode 100644 index e538965e..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/BookmarkTable.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.aspose.words.examples.programming_documents.bookmarks; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.PdfSaveOptions; -import com.aspose.words.examples.Utils; - - -public class BookmarkTable -{ - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(BookmarkTable.class); - //Create empty document - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - // We call this method to start building the table. - builder.startTable(); - builder.insertCell(); - - // Start bookmark here after calling InsertCell - builder.startBookmark("MyBookmark"); - - builder.write("Row 1, Cell 1 Content."); - - // Build the second cell - builder.insertCell(); - builder.write("Row 1, Cell 2 Content."); - // Call the following method to end the row and start a new row. - builder.endRow(); - - // Build the first cell of the second row. - builder.insertCell(); - builder.write("Row 2, Cell 1 Content"); - - // Build the second cell. - builder.insertCell(); - builder.write("Row 2, Cell 2 Content."); - builder.endRow(); - - // Signal that we have finished building the table. - builder.endTable(); - - //End of bookmark - builder.endBookmark("MyBookmark"); - - doc.save(dataDir+ "output.doc"); - System.out.println("\nTable bookmarked successfully.\nFile saved at " + dataDir); - } - -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/CopyBookmarkedText.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/CopyBookmarkedText.java deleted file mode 100644 index bedfddca..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/CopyBookmarkedText.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.aspose.words.examples.programming_documents.bookmarks; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - - -/** - * Shows how to copy bookmarked text from one document to another while preserving all content and formatting. - * - * Does not cover all cases possible (bookmark can start/end in various places of a document - * making copying scenario more complex). - * - * Supported scenarios at the moment are: - * - * 1. Bookmark start and end are in the same section of the document, but in different paragraphs. - * Complete paragraphs are copied. - */ -public class CopyBookmarkedText -{ - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(CopyBookmarkedText.class); - - // Load the source document. - Document srcDoc = new Document(dataDir + "Template.doc"); - - // This is the bookmark whose content we want to copy. - Bookmark srcBookmark = srcDoc.getRange().getBookmarks().get("ntf010145060"); - - // We will be adding to this document. - Document dstDoc = new Document(); - - // Let's say we will be appending to the end of the body of the last section. - CompositeNode dstNode = dstDoc.getLastSection().getBody(); - - // It is a good idea to use this import context object because multiple nodes are being imported. - // If you import multiple times without a single context, it will result in many styles created. - NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - - // Do it once. - appendBookmarkedText(importer, srcBookmark, dstNode); - - // Do it one more time for fun. - appendBookmarkedText(importer, srcBookmark, dstNode); - - // Save the finished document. - dstDoc.save(dataDir + "Template Out.doc"); - - System.out.println("Bookmarked text copied successfully."); - } - - /** - * Copies content of the bookmark and adds it to the end of the specified node. - * The destination node can be in a different document. - * - * @param importer Maintains the import context. - * @param srcBookmark The input bookmark. - * @param dstNode Must be a node that can contain paragraphs (such as a Story). - */ - private static void appendBookmarkedText(NodeImporter importer, Bookmark srcBookmark, CompositeNode dstNode) throws Exception - { - // This is the paragraph that contains the beginning of the bookmark. - Paragraph startPara = (Paragraph)srcBookmark.getBookmarkStart().getParentNode(); - - // This is the paragraph that contains the end of the bookmark. - Paragraph endPara = (Paragraph)srcBookmark.getBookmarkEnd().getParentNode(); - - if ((startPara == null) || (endPara == null)) - throw new IllegalStateException("Parent of the bookmark start or end is not a paragraph, cannot handle this scenario yet."); - - // Limit ourselves to a reasonably simple scenario. - if (startPara.getParentNode() != endPara.getParentNode()) - throw new IllegalStateException("Start and end paragraphs have different parents, cannot handle this scenario yet."); - - // We want to copy all paragraphs from the start paragraph up to (and including) the end paragraph, - // therefore the node at which we stop is one after the end paragraph. - Node endNode = endPara.getNextSibling(); - - // This is the loop to go through all paragraph-level nodes in the bookmark. - for (Node curNode = startPara; curNode != endNode; curNode = curNode.getNextSibling()) - { - // This creates a copy of the current node and imports it (makes it valid) in the context - // of the destination document. Importing means adjusting styles and list identifiers correctly. - Node newNode = importer.importNode(curNode, true); - - // Now we simply append the new node to the destination. - dstNode.appendChild(newNode); - } - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/CreateBookmark.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/CreateBookmark.java deleted file mode 100644 index aa59b9c8..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/CreateBookmark.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.aspose.words.examples.programming_documents.bookmarks; - -import com.aspose.words.Bookmark; -import com.aspose.words.*; -import com.aspose.words.Row; -import com.aspose.words.SaveFormat.*; -import com.aspose.words.examples.Utils; - - -public class CreateBookmark -{ - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(CreateBookmark.class); - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - builder.startBookmark("MyBookmark"); - builder.writeln("Text inside a bookmark."); - builder.endBookmark("MyBookmark"); - - builder.startBookmark("Nested Bookmark"); - builder.writeln("Text inside a NestedBookmark."); - builder.endBookmark("Nested Bookmark"); - - builder.writeln("Text after Nested Bookmark."); - builder.endBookmark("My Bookmark"); - - PdfSaveOptions options = new PdfSaveOptions(); - options.getOutlineOptions().setDefaultBookmarksOutlineLevel(1); - options.getOutlineOptions().setDefaultBookmarksOutlineLevel(2); - - doc.save(dataDir + "output.pdf"); - System.out.println("\nBookmark created successfully."); - } - -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/GetAndSetBookmarkNameAndText.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/GetAndSetBookmarkNameAndText.java deleted file mode 100644 index f75d1173..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/GetAndSetBookmarkNameAndText.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.aspose.words.examples.programming_documents.bookmarks; - -import com.aspose.words.Bookmark; -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - - -public class GetAndSetBookmarkNameAndText -{ - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(GetAndSetBookmarkNameAndText.class); - - Document doc = new Document(dataDir + "Bookmark.doc"); - // Use the indexer of the Bookmarks collection to obtain the desired bookmark. - Bookmark bookmark = doc.getRange().getBookmarks().get("MyBookmark"); - - // Get the name and text of the bookmark. - String name = bookmark.getName(); - String text = bookmark.getText(); - - // Set the name and text of the bookmark. - bookmark.setName("RenamedBookmark"); - bookmark.setText("This is a new bookmarked text."); - System.out.println("\nBookmark name and text set successfully."); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/InsertBookmarksWithWhiteSpaces.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/InsertBookmarksWithWhiteSpaces.java deleted file mode 100644 index a2359a18..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/InsertBookmarksWithWhiteSpaces.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.aspose.words.examples.programming_documents.bookmarks; - -import com.aspose.words.Bookmark; -import com.aspose.words.*; -import com.aspose.words.Row; -import com.aspose.words.SaveFormat.*; -import com.aspose.words.examples.Utils; - - -public class InsertBookmarksWithWhiteSpaces -{ - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(InsertBookmarksWithWhiteSpaces.class); - - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - builder.startBookmark("My Bookmark"); - builder.writeln("Text inside a bookmark."); - - builder.startBookmark("Nested Bookmark"); - builder.writeln("Text inside a NestedBookmark."); - builder.endBookmark("Nested Bookmark"); - - builder.writeln("Text after Nested Bookmark."); - builder.endBookmark("My Bookmark"); - - - PdfSaveOptions options = new PdfSaveOptions(); - options.getOutlineOptions().getBookmarksOutlineLevels().add("My Bookmark", 1); - options.getOutlineOptions().getBookmarksOutlineLevels().add("Nested Bookmark", 2); - - dataDir = dataDir + "Insert.Bookmarks_out_.pdf"; - doc.save(dataDir, options); - - System.out.println("\nBookmarks with white spaces inserted successfully.\nFile saved at " + dataDir); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/ObtainBookmarkByIndexAndName.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/ObtainBookmarkByIndexAndName.java deleted file mode 100644 index 9ecbca2b..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/ObtainBookmarkByIndexAndName.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.aspose.words.examples.programming_documents.bookmarks; - -import com.aspose.words.Bookmark; -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - - -public class ObtainBookmarkByIndexAndName -{ - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(ObtainBookmarkByIndexAndName.class); - - Document doc = new Document(dataDir + "Bookmarks.doc"); - - // By index. - Bookmark bookmark1 = doc.getRange().getBookmarks().get(0); - System.out.println("\nBookmark by index is " + bookmark1.getText()); - // By name. - Bookmark bookmark2 = doc.getRange().getBookmarks().get("Bookmark2"); - System.out.println("\nBookmark by name is " + bookmark2.getText()); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/UntangleRowBookmarks.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/UntangleRowBookmarks.java deleted file mode 100644 index 83e75e2c..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/bookmarks/UntangleRowBookmarks.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.aspose.words.examples.programming_documents.bookmarks; - -import com.aspose.words.Bookmark; -import com.aspose.words.Document; -import com.aspose.words.Row; -import com.aspose.words.examples.Utils; - - -public class UntangleRowBookmarks -{ - /** - * The main entry point for the application. - */ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(UntangleRowBookmarks.class); - - // Load a document. - Document doc = new Document(dataDir + "TestDefect1352.doc"); - - // This perform the custom task of putting the row bookmark ends into the same row with the bookmark starts. - untangleRowBookmarks(doc); - - // Now we can easily delete rows by a bookmark without damaging any other row's bookmarks. - deleteRowByBookmark(doc, "ROW2"); - - // This is just to check that the other bookmark was not damaged. - if (doc.getRange().getBookmarks().get("ROW1").getBookmarkEnd() == null) - throw new Exception("Wrong, the end of the bookmark was deleted."); - - // Save the finished document. - doc.save(dataDir + "TestDefect1352 Out.doc"); - - System.out.println("Untangled row bookmarks successfully."); - } - - private static void untangleRowBookmarks(Document doc) throws Exception - { - for (Bookmark bookmark : doc.getRange().getBookmarks()) - { - // Get the parent row of both the bookmark and bookmark end node. - Row row1 = (Row)bookmark.getBookmarkStart().getAncestor(Row.class); - Row row2 = (Row)bookmark.getBookmarkEnd().getAncestor(Row.class); - - // If both rows are found okay and the bookmark start and end are contained - // in adjacent rows, then just move the bookmark end node to the end - // of the last paragraph in the last cell of the top row. - if ((row1 != null) && (row2 != null) && (row1.getNextSibling() == row2)) - row1.getLastCell().getLastParagraph().appendChild(bookmark.getBookmarkEnd()); - } - } - - private static void deleteRowByBookmark(Document doc, String bookmarkName) throws Exception - { - // Find the bookmark in the document. Exit if cannot find it. - Bookmark bookmark = doc.getRange().getBookmarks().get(bookmarkName); - if (bookmark == null) - return; - - // Get the parent row of the bookmark. Exit if the bookmark is not in a row. - Row row = (Row)bookmark.getBookmarkStart().getAncestor(Row.class); - if (row == null) - return; - - // Remove the row. - row.remove(); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/charts/ChartAppearance.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/charts/ChartAppearance.java deleted file mode 100644 index f1ba648e..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/charts/ChartAppearance.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.aspose.words.examples.programming_documents.charts; - -import com.aspose.words.Chart; -import com.aspose.words.ChartSeries; -import com.aspose.words.ChartType; -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.LegendPosition; -import com.aspose.words.MarkerSymbol; -import com.aspose.words.Shape; -import com.aspose.words.examples.Utils; - -public class ChartAppearance { - - public static final String dataDir = Utils.getSharedDataDir(OOXMLCharts.class) + "Charts/"; - - public static void main(String[] args) throws Exception { - // Working with Charts through Shape.Chart Object - changeChartAppearanceUsingShapeChartObject(); - - // Working with Single ChartSeries Class - workingWithSingleChartSeries(); - - //All single ChartSeries have default ChartDataPoint options, lets change them - changeDefaultChartDataPointOptions(); - } - - private static void changeChartAppearanceUsingShapeChartObject() throws Exception { - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - Shape shape = builder.insertChart(ChartType.LINE, 432, 252); - Chart chart = shape.getChart(); - - // Determines whether the title shall be shown for this chart. Default is true. - chart.getTitle().setShow(true); - - // Setting chart Title. - chart.getTitle().setText("Sample Line Chart Title"); - - // Determines whether other chart elements shall be allowed to overlap title. - chart.getTitle().setOverlay(false); - - // Please note if null or empty value is specified as title text, auto generated title will be shown. - - // Determines how legend shall be shown for this chart. - chart.getLegend().setPosition(LegendPosition.LEFT); - chart.getLegend().setOverlay(true); - - doc.save(dataDir + "ChartAppearance_out.docx"); - } - - private static void workingWithSingleChartSeries() throws Exception { - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - Shape shape = builder.insertChart(ChartType.LINE, 432, 252); - - // Get first series. - ChartSeries series0 = shape.getChart().getSeries().get(0); - - // Get second series. - ChartSeries series1 = shape.getChart().getSeries().get(1); - - // Change first series name. - series0.setName("My Name1"); - - // Change second series name. - series1.setName("My Name2"); - - // You can also specify whether the line connecting the points on the chart shall be smoothed using Catmull-Rom splines. - series0.setSmooth(true); - series1.setSmooth(true); - - doc.save(dataDir + "SingleChartSeries_out.docx"); - } - - private static void changeDefaultChartDataPointOptions() throws Exception { - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - Shape shape = builder.insertChart(ChartType.LINE, 432, 252); - - // Get first series. - ChartSeries series0 = shape.getChart().getSeries().get(0); - - // Get second series. - ChartSeries series1 = shape.getChart().getSeries().get(1); - - // Specifies whether by default the parent element shall inverts its colors if the value is negative. - series0.setInvertIfNegative(true); - - // Set default marker symbol and size. - series0.getMarker().setSymbol(MarkerSymbol.CIRCLE); - series0.getMarker().setSize(15); - - series1.getMarker().setSymbol(MarkerSymbol.STAR); - series1.getMarker().setSize(10); - - doc.save(dataDir + "ChartDataPoints_out.docx"); - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/charts/OOXMLCharts.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/charts/OOXMLCharts.java deleted file mode 100644 index a31ff3c4..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/charts/OOXMLCharts.java +++ /dev/null @@ -1,125 +0,0 @@ -package com.aspose.words.examples.programming_documents.charts; - -import java.text.SimpleDateFormat; -import java.util.Date; - -import com.aspose.words.Chart; -import com.aspose.words.ChartSeriesCollection; -import com.aspose.words.ChartType; -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.Shape; -import com.aspose.words.examples.Utils; - -public class OOXMLCharts { - - public static final String dataDir = Utils.getSharedDataDir(OOXMLCharts.class) + "Charts/"; - - public static void main(String[] args) throws Exception { - - // Insert Column chart - insertColumnChart1(); - insertColumnChart2(); - - // Insert Scatter chart - insertScatterChart(); - - // Insert Area chart - insertAreaChart(); - - // Insert Bubble chart - insertBubbleChart(); - } - - public static void insertColumnChart1() throws Exception { - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - // Add chart with default data. You can specify different chart types and sizes. - Shape shape = builder.insertChart(ChartType.COLUMN, 432, 252); - - // Chart property of Shape contains all chart related options. - Chart chart = shape.getChart(); - - // Get chart series collection. - ChartSeriesCollection seriesColl = chart.getSeries(); - - // Delete default generated series. - seriesColl.clear(); - - // Create category names array, in this example we have two categories. - String[] categories = new String[] { "AW Category 1", "AW Category 2" }; - - // Adding new series. Please note, data arrays must not be empty and arrays must be the same size. - seriesColl.add("AW Series 1", categories, new double[] { 1, 2 }); - seriesColl.add("AW Series 2", categories, new double[] { 3, 4 }); - seriesColl.add("AW Series 3", categories, new double[] { 5, 6 }); - seriesColl.add("AW Series 4", categories, new double[] { 7, 8 }); - seriesColl.add("AW Series 5", categories, new double[] { 9, 10 }); - - doc.save(dataDir + "TestInsertChartColumn1_out.docx"); - } - - public static void insertColumnChart2() throws Exception { - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - // Insert Column chart. - Shape shape = builder.insertChart(ChartType.COLUMN, 432, 252); - Chart chart = shape.getChart(); - - // Use this overload to add series to any type of Bar, Column, Line and Surface charts. - chart.getSeries().add("AW Series 1", new String[] { "AW Category 1", "AW Category 2" }, new double[] { 1, 2 }); - - doc.save(dataDir + "TestInsertColumnChart2_out.docx"); - } - - public static void insertScatterChart() throws Exception { - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - // Insert Scatter chart. - Shape shape = builder.insertChart(ChartType.SCATTER, 432, 252); - Chart chart = shape.getChart(); - - // Use this overload to add series to any type of Scatter charts. - chart.getSeries().add("AW Series 1", new double[] { 0.7, 1.8, 2.6 }, new double[] { 2.7, 3.2, 0.8 }); - - doc.save(dataDir + "TestInsertScatterChart_out.docx"); - } - - public static void insertAreaChart() throws Exception { - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - // Insert Area chart. - Shape shape = builder.insertChart(ChartType.AREA, 432, 252); - Chart chart = shape.getChart(); - - SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); - Date date1 = sdf.parse("01/01/2016"); - Date date2 = sdf.parse("02/02/2016"); - Date date3 = sdf.parse("03/03/2016"); - Date date4 = sdf.parse("04/04/2016"); - Date date5 = sdf.parse("05/05/2016"); - - // Use this overload to add series to any type of Area, Radar and Stock charts. - chart.getSeries().add ("AW Series 1", new Date[] {date1, date2, date3, date4, date5}, new double[] {32, 32, 28, 12, 15}); - - doc.save(dataDir + "TestInsertAreaChart_out.docx"); - } - - public static void insertBubbleChart() throws Exception { - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - // Insert Bubble chart. - Shape shape = builder.insertChart(ChartType.BUBBLE, 432, 252); - Chart chart = shape.getChart(); - - // Use this overload to add series to any type of Bubble charts. - chart.getSeries().add("AW Series 1", new double[] { 0.7, 1.8, 2.6 }, new double[] { 2.7, 3.2, 0.8 }, new double[] { 10, 4, 8 }); - - doc.save(dataDir + "TestInsertBubbleChart_out.docx"); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/charts/WorkWithChartDataLabelOfASingleChartSeries.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/charts/WorkWithChartDataLabelOfASingleChartSeries.java deleted file mode 100644 index e914afe5..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/charts/WorkWithChartDataLabelOfASingleChartSeries.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.aspose.words.examples.programming_documents.charts; - -import com.aspose.words.ChartDataLabel; -import com.aspose.words.ChartDataLabelCollection; -import com.aspose.words.ChartSeries; -import com.aspose.words.ChartType; -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.Shape; -import com.aspose.words.examples.Utils; - -public class WorkWithChartDataLabelOfASingleChartSeries { - - public static final String dataDir = Utils.getSharedDataDir(OOXMLCharts.class) + "Charts/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - Shape shape = builder.insertChart(ChartType.BAR, 432, 252); - - // Get first series. - ChartSeries series0 = shape.getChart().getSeries().get(0); - - ChartDataLabelCollection dataLabelCollection = series0.getDataLabels(); - - // Add data label to the first and second point of the first series. - ChartDataLabel chartDataLabel00 = dataLabelCollection.add(0); - ChartDataLabel chartDataLabel01 = dataLabelCollection.add(1); - - // Set properties. - chartDataLabel00.setShowLegendKey(true); - - // By default, when you add data labels to the data points in a pie chart, leader lines are displayed for data labels that are - // positioned far outside the end of data points. Leader lines create a visual connection between a data label and its - // corresponding data point. - chartDataLabel00.setShowLeaderLines(true); - - chartDataLabel00.setShowCategoryName(false); - chartDataLabel00.setShowPercentage(false); - chartDataLabel00.setShowSeriesName(true); - chartDataLabel00.setShowValue(true); - chartDataLabel00.setSeparator("/"); - - chartDataLabel01.setShowValue(true); - - doc.save(dataDir + "ChartDataLabelOfASingleChartSeries_out.docx"); - } - -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/charts/WorkWithChartSeriesCollectionOfChart.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/charts/WorkWithChartSeriesCollectionOfChart.java deleted file mode 100644 index 6a09af85..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/charts/WorkWithChartSeriesCollectionOfChart.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.aspose.words.examples.programming_documents.charts; - -import com.aspose.words.Chart; -import com.aspose.words.ChartSeriesCollection; -import com.aspose.words.ChartType; -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.Shape; - -public class WorkWithChartSeriesCollectionOfChart { - - public static void main(String[] args) throws Exception { - - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - Shape shape = builder.insertChart(ChartType.LINE, 432, 252); - // Chart property of Shape contains all chart related options. - Chart chart = shape.getChart(); - - // Get chart series collection. - ChartSeriesCollection seriesCollection = chart.getSeries(); - - // Check series count. - System.out.println(seriesCollection.getCount()); - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/charts/WorkWithSingleChartDataPointOfAChartSeries.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/charts/WorkWithSingleChartDataPointOfAChartSeries.java deleted file mode 100644 index a2023e26..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/charts/WorkWithSingleChartDataPointOfAChartSeries.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.aspose.words.examples.programming_documents.charts; - -import com.aspose.words.ChartDataPoint; -import com.aspose.words.ChartDataPointCollection; -import com.aspose.words.ChartSeries; -import com.aspose.words.ChartType; -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.MarkerSymbol; -import com.aspose.words.Shape; -import com.aspose.words.examples.Utils; - -public class WorkWithSingleChartDataPointOfAChartSeries { - - public static final String dataDir = Utils.getSharedDataDir(OOXMLCharts.class) + "Charts/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - Shape shape = builder.insertChart(ChartType.LINE, 432, 252); - - // Get first series. - ChartSeries series0 = shape.getChart().getSeries().get(0); - - // Get second series. - ChartSeries series1 = shape.getChart().getSeries().get(1); - - ChartDataPointCollection dataPointCollection = series0.getDataPoints(); - - // Add data point to the first and second point of the first series. - ChartDataPoint dataPoint00 = dataPointCollection.add(0); - ChartDataPoint dataPoint01 = dataPointCollection.add(1); - - // Set explosion. - dataPoint00.setExplosion(50); - - // Set marker symbol and size. - dataPoint00.getMarker().setSymbol(MarkerSymbol.CIRCLE); - dataPoint00.getMarker().setSize(15); - - dataPoint01.getMarker().setSymbol(MarkerSymbol.DIAMOND); - dataPoint01.getMarker().setSize(20); - - // Add data point to the third point of the second series. - ChartDataPoint dataPoint12 = series1.getDataPoints().add(2); - dataPoint12.setInvertIfNegative(true); - dataPoint12.getMarker().setSymbol(MarkerSymbol.STAR); - dataPoint12.getMarker().setSize(20); - - doc.save(dataDir + "SingleChartDataPointOfAChartSeries_out.docx"); - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/comments/AddComments.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/comments/AddComments.java deleted file mode 100644 index cf3f720e..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/comments/AddComments.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.aspose.words.examples.programming_documents.comments; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.util.Date; - -@SuppressWarnings("unchecked") -public class AddComments { - public static void main(String[] args) throws Exception { - - String dataDir = Utils.getDataDir(AddComments.class); - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - builder.write("Some text is added."); - - Comment comment = new Comment(doc, "Awais Hafeez", "AH", new Date()); - builder.getCurrentParagraph().appendChild(comment); - comment.getParagraphs().add(new Paragraph(doc)); - comment.getFirstParagraph().getRuns().add(new Run(doc, "Comment text.")); - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/comments/AnchorComment.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/comments/AnchorComment.java deleted file mode 100644 index af66a06f..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/comments/AnchorComment.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.aspose.words.examples.programming_documents.comments; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.util.Date; - -@SuppressWarnings("unchecked") -public class AnchorComment { - public static void main(String[] args) throws Exception { - - String dataDir = Utils.getDataDir(AnchorComment.class); - Document doc = new Document(); - - Paragraph para1 = new Paragraph(doc); - Run run1 = new Run(doc, "Some "); - Run run2 = new Run(doc, "text "); - para1.appendChild(run1); - para1.appendChild(run2); - doc.getFirstSection().getBody().appendChild(para1); - - Paragraph para2 = new Paragraph(doc); - Run run3 = new Run(doc, "is "); - Run run4 = new Run(doc, "added "); - para2.appendChild(run3); - para2.appendChild(run4); - doc.getFirstSection().getBody().appendChild(para2); - - Comment comment = new Comment(doc, "Awais Hafeez", "AH", new Date()); - comment.getParagraphs().add(new Paragraph(doc)); - comment.getFirstParagraph().getRuns().add(new Run(doc, "Comment text.")); - - CommentRangeStart commentRangeStart = new CommentRangeStart(doc, comment.getId()); - CommentRangeEnd commentRangeEnd = new CommentRangeEnd(doc, comment.getId()); - - run1.getParentNode().insertAfter(commentRangeStart, run1); - run3.getParentNode().insertAfter(commentRangeEnd, run3); - commentRangeEnd.getParentNode().insertAfter(comment, commentRangeEnd); - - doc.save(dataDir + "output.doc"); - - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/comments/CreateSimpleDocumentUsingDocumentBuilder.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/comments/CreateSimpleDocumentUsingDocumentBuilder.java deleted file mode 100644 index 2bcacac5..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/comments/CreateSimpleDocumentUsingDocumentBuilder.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.aspose.words.examples.programming_documents.comments; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.util.ArrayList; - -@SuppressWarnings("unchecked") -public class CreateSimpleDocumentUsingDocumentBuilder { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(CreateSimpleDocumentUsingDocumentBuilder.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - builder.write("Aspose_Words_Java"); - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/comments/ExtractCommentsByAuthor.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/comments/ExtractCommentsByAuthor.java deleted file mode 100644 index a8d41b20..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/comments/ExtractCommentsByAuthor.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.aspose.words.examples.programming_documents.comments; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.util.ArrayList; - -@SuppressWarnings("unchecked") -public class ExtractCommentsByAuthor { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ExtractCommentsByAuthor.class); - - String authorName = "ks"; - // Open the document. - Document doc = new Document(dataDir + "TestFile.doc"); - ArrayList collectedComments = new ArrayList(); - // Collect all comments in the document - NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true); - // Look through all comments and gather information about those written by the authorName author. - for (Comment comment : (Iterable) comments) { - if (comment.getAuthor().equals(authorName)) - collectedComments.add(comment.getAuthor() + " " + comment.getDateTime() + " " + comment.toString(SaveFormat.TEXT)); - } - System.out.print(collectedComments); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/comments/ProcessComments.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/comments/ProcessComments.java deleted file mode 100644 index a0fb7e45..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/comments/ProcessComments.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.aspose.words.examples.programming_documents.comments; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.util.ArrayList; - -@SuppressWarnings("unchecked") -public class ProcessComments { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ProcessComments.class); - - // Open the document. - Document doc = new Document(dataDir + "TestFile.doc"); - - for (String comment : (Iterable) extractComments(doc)) - System.out.print(comment); - - // Remove comments by the "pm" author. - removeComments(doc, "pm"); - System.out.println("Comments from \"pm\" are removed!"); - - // Extract the information about the comments of the "ks" author. - for (String comment : (Iterable) extractComments(doc, "ks")) - System.out.print(comment); - - // Remove all comments. - removeComments(doc); - System.out.println("All comments are removed!"); - - // Save the document. - doc.save(dataDir + "output.doc"); - - } - - //ExFor:Comment.Author - //ExFor:Comment.DateTime - //ExId:ProcessComments_Extract_All - //ExSummary:Extracts the author name, date&time and text of all comments in the document. - static ArrayList extractComments(Document doc) throws Exception { - ArrayList collectedComments = new ArrayList(); - // Collect all comments in the document - NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true); - // Look through all comments and gather information about them. - for (Comment comment : (Iterable) comments) { - collectedComments.add(comment.getAuthor() + " " + comment.getDateTime() + " " + comment.toString(SaveFormat.TEXT)); - } - return collectedComments; - } - - //ExId:ProcessComments_Extract_Author - //ExSummary:Extracts the author name, date&time and text of the comments by the specified author. - static ArrayList extractComments(Document doc, String authorName) throws Exception { - ArrayList collectedComments = new ArrayList(); - // Collect all comments in the document - NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true); - // Look through all comments and gather information about those written by the authorName author. - for (Comment comment : (Iterable) comments) { - if (comment.getAuthor().equals(authorName)) - collectedComments.add(comment.getAuthor() + " " + comment.getDateTime() + " " + comment.toString(SaveFormat.TEXT)); - } - return collectedComments; - } - - //ExId:ProcessComments_Remove_All - //ExSummary:Removes all comments in the document. - static void removeComments(Document doc) throws Exception { - // Collect all comments in the document - NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true); - // Remove all comments. - comments.clear(); - } - - //ExId:ProcessComments_Remove_Author - //ExSummary:Removes comments by the specified author. - static void removeComments(Document doc, String authorName) throws Exception { - // Collect all comments in the document - NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true); - // Look through all comments and remove those written by the authorName author. - for (int i = comments.getCount() - 1; i >= 0; i--) { - Comment comment = (Comment) comments.get(i); - if (comment.getAuthor().equals(authorName)) - comment.remove(); - } - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/comments/RemoveComments.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/comments/RemoveComments.java deleted file mode 100644 index e83a368f..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/comments/RemoveComments.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.aspose.words.examples.programming_documents.comments; - -import com.aspose.words.Document; -import com.aspose.words.NodeCollection; -import com.aspose.words.NodeType; -import com.aspose.words.examples.Utils; - -@SuppressWarnings("unchecked") -public class RemoveComments { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(RemoveComments.class); - - // Open the document. - Document doc = new Document(dataDir + "TestFile.doc"); - // Collect all comments in the document - NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true); - // Remove all comments. - comments.clear(); - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/comments/RemoveCommentsByAuthor.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/comments/RemoveCommentsByAuthor.java deleted file mode 100644 index e4401472..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/comments/RemoveCommentsByAuthor.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.aspose.words.examples.programming_documents.comments; - -import com.aspose.words.Comment; -import com.aspose.words.Document; -import com.aspose.words.NodeCollection; -import com.aspose.words.NodeType; -import com.aspose.words.examples.Utils; - -@SuppressWarnings("unchecked") -public class RemoveCommentsByAuthor { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(RemoveCommentsByAuthor.class); - - // Open the document. - Document doc = new Document(dataDir + "TestFile.doc"); - String authorName = "pm"; - // Collect all comments in the document - NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true); - // Look through all comments and remove those written by the authorName author. - for (int i = comments.getCount() - 1; i >= 0; i--) { - Comment comment = (Comment) comments.get(i); - if (comment.getAuthor().equals(authorName)) - comment.remove(); - } - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/AccessStyles.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/AccessStyles.java deleted file mode 100644 index 8cc57574..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/AccessStyles.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.Style; -import com.aspose.words.StyleCollection; - -public class AccessStyles { - - public static void main(String[] args) throws Exception { - accessStyles(); - - iterateThroughStyles(); - } - - public static void accessStyles() throws Exception { - Document doc = new Document(); - StyleCollection styles = doc.getStyles(); - - for (Style style : styles) - System.out.println(style.getName()); - } - - public static void iterateThroughStyles() throws Exception { - Document doc = new Document(); - - for(int i =0; i < doc.getStyles().getCount(); i++) - System.out.println(doc.getStyles().get(i).getName()); - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/AddGroupShape.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/AddGroupShape.java deleted file mode 100644 index 94117867..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/AddGroupShape.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import java.awt.Dimension; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.GroupShape; -import com.aspose.words.Shape; -import com.aspose.words.ShapeType; -import com.aspose.words.examples.Utils; -import com.aspose.words.examples.programming_documents.tables.creation.BuildTableFromDataTable; - -public class AddGroupShape { - - private static final String dataDir = Utils.getSharedDataDir(BuildTableFromDataTable.class) + "Document/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(); - doc.ensureMinimum(); - GroupShape gs = new GroupShape(doc); - - Shape shape = new Shape(doc, ShapeType.ACCENT_BORDER_CALLOUT_1); - shape.setWidth(100); - shape.setHeight(100); - gs.appendChild(shape); - - Shape shape1 = new Shape(doc, ShapeType.ACTION_BUTTON_BEGINNING); - shape1.setLeft(100); - shape1.setWidth(100); - shape1.setHeight(200); - gs.appendChild(shape1); - - gs.setWidth(200); - gs.setHeight(200); - - gs.setCoordSize(new Dimension(200, 200)); - - DocumentBuilder builder = new DocumentBuilder(doc); - builder.insertNode(gs); - - doc.save(dataDir + "AddGroupShape_out.docx"); - - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/CheckBoxTypeContentControl.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/CheckBoxTypeContentControl.java deleted file mode 100644 index 5aa69db8..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/CheckBoxTypeContentControl.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - - -public class CheckBoxTypeContentControl { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(CheckBoxTypeContentControl.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - StructuredDocumentTag stdCheckBox =new StructuredDocumentTag(doc, SdtType.CHECKBOX, MarkupLevel.INLINE); - - builder.insertNode(stdCheckBox); - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/CloneDocument.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/CloneDocument.java deleted file mode 100644 index d086da32..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/CloneDocument.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; -import com.aspose.words.examples.programming_documents.document.properties.AccessingDocumentProperties; - -public class CloneDocument { - - public static final String dataDir = Utils.getSharedDataDir(AccessingDocumentProperties.class) + "Document/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(dataDir + "Document.doc"); - Document clone = doc.deepClone(); - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ComboBoxContentControl.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ComboBoxContentControl.java deleted file mode 100644 index 6b1d551b..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ComboBoxContentControl.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.awt.*; - - -public class ComboBoxContentControl { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ComboBoxContentControl.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - StructuredDocumentTag sdt =new StructuredDocumentTag(doc, SdtType.COMBO_BOX, MarkupLevel.BLOCK); - - sdt.getListItems().add(new SdtListItem("Choose an item", "3")); - sdt.getListItems().add(new SdtListItem("Item 1", "1")); - sdt.getListItems().add(new SdtListItem("Item 2", "2")); - - doc.getFirstSection().getBody().appendChild(sdt); - - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/CompareTwoWordDocuments.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/CompareTwoWordDocuments.java deleted file mode 100644 index de3f074b..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/CompareTwoWordDocuments.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import java.util.Date; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; -import com.aspose.words.examples.programming_documents.tables.creation.BuildTableFromDataTable; - -public class CompareTwoWordDocuments { - - private static final String dataDir = Utils.getSharedDataDir(BuildTableFromDataTable.class) + "Document/"; - - public static void main(String[] args) throws Exception { - // Example Shows Normal Comparison Case - normalComparisonCase(); - - // Case when Document has Revisions already so Comparison is not Possible - caseWhenDocumentHasRevisions(); - - // Shows how to test that Word Documents are "Equal" - wordDocumentsAreEqual(); - } - - public static void normalComparisonCase() throws Exception { - Document docA = new Document(dataDir + "DocumentA.doc"); - Document docB = new Document(dataDir + "DocumentB.doc"); - docA.compare(docB, "user", new Date()); // docA now contains changes as revisions - } - - public static void caseWhenDocumentHasRevisions() throws Exception { - Document docA = new Document(dataDir + "DocumentA.doc"); - Document docB = new Document(dataDir + "DocumentB.doc"); - docA.compare(docB, "user", new Date()); // exception is thrown. - } - - public static void wordDocumentsAreEqual() throws Exception { - Document docA = new Document(dataDir + "DocumentA.doc"); - Document docB = new Document(dataDir + "DocumentB.doc"); - docA.compare(docB, "user", new Date()); - if(docA.getRevisions().getCount() == 0) - System.out.println("Documents are equal"); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ConvertBetweenMeasurementUnits.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ConvertBetweenMeasurementUnits.java deleted file mode 100644 index b9672a30..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ConvertBetweenMeasurementUnits.java +++ /dev/null @@ -1,39 +0,0 @@ - - - -/* - * Copyright 2001-2014 Aspose Pty Ltd. All Rights Reserved. - * - * This file is part of Aspose.Words. The source code in this file - * is only intended as a supplement to the documentation, and is provided - * "as is", without warranty of any kind, either expressed or implied. - */ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.Font; -import com.aspose.words.examples.Utils; - -import java.awt.*; - - -public class ConvertBetweenMeasurementUnits { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ConvertBetweenMeasurementUnits.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - PageSetup pageSetup = builder.getPageSetup(); - pageSetup.setTopMargin(ConvertUtil.inchToPoint(1.0)); - pageSetup.setBottomMargin(ConvertUtil.inchToPoint(1.0)); - pageSetup.setLeftMargin(ConvertUtil.inchToPoint(1.5)); - pageSetup.setRightMargin(ConvertUtil.inchToPoint(1.5)); - pageSetup.setHeaderDistance(ConvertUtil.inchToPoint(0.2)); - pageSetup.setFooterDistance(ConvertUtil.inchToPoint(0.2)); - doc.save(dataDir + "output.doc"); - - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderApplyBordersAndShadingToParagraph.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderApplyBordersAndShadingToParagraph.java deleted file mode 100644 index e4eaee65..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderApplyBordersAndShadingToParagraph.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.awt.*; - - -public class DocumentBuilderApplyBordersAndShadingToParagraph { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderApplyBordersAndShadingToParagraph.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - // Set paragraph borders - BorderCollection borders = builder.getParagraphFormat().getBorders(); - borders.setDistanceFromText(20); - borders.getByBorderType(BorderType.LEFT).setLineStyle(LineStyle.DOUBLE); - borders.getByBorderType(BorderType.RIGHT).setLineStyle(LineStyle.DOUBLE); - borders.getByBorderType(BorderType.TOP).setLineStyle(LineStyle.DOUBLE); - borders.getByBorderType(BorderType.BOTTOM).setLineStyle(LineStyle.DOUBLE); - // Set paragraph shading - Shading shading = builder.getParagraphFormat().getShading(); - shading.setTexture(TextureIndex.TEXTURE_DIAGONAL_CROSS); - shading.setBackgroundPatternColor(Color.YELLOW); - shading.setForegroundPatternColor(Color.GREEN); - - builder.write("I'm a formatted paragraph with double border and nice shading."); - doc.save(dataDir + "output.doc"); - - - - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderApplyParagraphStyle.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderApplyParagraphStyle.java deleted file mode 100644 index 3aceeaa6..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderApplyParagraphStyle.java +++ /dev/null @@ -1,22 +0,0 @@ - -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderApplyParagraphStyle { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderApplyParagraphStyle.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.TITLE); - builder.write("Hello"); - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderBuildTable.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderBuildTable.java deleted file mode 100644 index 1261b9dd..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderBuildTable.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderBuildTable { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderBuildTable.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - Table table = builder.startTable(); - builder.insertCell(); - table.autoFit(AutoFitBehavior.FIXED_COLUMN_WIDTHS); - - builder.getCellFormat().setVerticalAlignment(CellVerticalAlignment.CENTER); - - builder.write("This is Row 1 Cell 1"); - builder.insertCell(); - builder.write("This is Row 1 Cell 2"); - builder.endRow(); - - builder.getRowFormat().setHeight(100); - builder.getRowFormat().setHeightRule(HeightRule.EXACTLY); - builder.getCellFormat().setOrientation(TextOrientation.UPWARD); - builder.write("This is Row 2 Cell 1"); - builder.insertCell(); - builder.getCellFormat().setOrientation(TextOrientation.DOWNWARD); - builder.write("This is Row 2 Cell 2"); - builder.endRow(); - builder.endTable(); - - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderCursorPosition.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderCursorPosition.java deleted file mode 100644 index f4764a99..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderCursorPosition.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.Node; -import com.aspose.words.Paragraph; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderCursorPosition { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderCursorPosition.class); - - // Open the document. - Document doc = new Document(dataDir + "DocumentBuilder.doc"); - DocumentBuilder builder = new DocumentBuilder(doc); - Node node = builder.getCurrentNode(); - Paragraph curParagraph = builder.getCurrentParagraph(); - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderHeadersAndFooters.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderHeadersAndFooters.java deleted file mode 100644 index 5bff1e9f..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderHeadersAndFooters.java +++ /dev/null @@ -1,38 +0,0 @@ - -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderHeadersAndFooters { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderHeadersAndFooters.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - builder.getPageSetup().setDifferentFirstPageHeaderFooter(true); - builder.getPageSetup().setOddAndEvenPagesHeaderFooter(true); - - builder.moveToHeaderFooter(HeaderFooterType.HEADER_FIRST); - builder.write("Header First"); - builder.moveToHeaderFooter(HeaderFooterType.HEADER_EVEN); - builder.write("Header Even"); - builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY); - builder.write("Header Odd"); - - builder.moveToSection(0); - builder.writeln("Page1"); - builder.insertBreak(BreakType.PAGE_BREAK); - builder.writeln("Page2"); - builder.insertBreak(BreakType.PAGE_BREAK); - builder.writeln("Page3"); - - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertBookmark.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertBookmark.java deleted file mode 100644 index e3bebc26..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertBookmark.java +++ /dev/null @@ -1,24 +0,0 @@ - -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderInsertBookmark { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderInsertBookmark.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - builder.startBookmark("FineBookMark"); - builder.write("This is just a fine bookmark."); - builder.endBookmark("FineBookmark"); - doc.save(dataDir + "output.doc"); - - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertBreak.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertBreak.java deleted file mode 100644 index 6c4f5129..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertBreak.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.BreakType; -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderInsertBreak { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderInsertBreak.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - builder.write("This is Page 1"); - builder.insertBreak(BreakType.PAGE_BREAK); - - builder.write("This is Page 2"); - builder.insertBreak(BreakType.PAGE_BREAK); - - builder.write("This is Page 3"); - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertCheckBoxFormField.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertCheckBoxFormField.java deleted file mode 100644 index 4d449405..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertCheckBoxFormField.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderInsertCheckBoxFormField { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderInsertCheckBoxFormField.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - builder.insertCheckBox("CheckBox", true, true, 0); - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertComboBoxFormField.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertComboBoxFormField.java deleted file mode 100644 index 5c0b6094..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertComboBoxFormField.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderInsertComboBoxFormField { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderInsertComboBoxFormField.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - String[] items = {"One", "Two", "Three"}; - builder.insertComboBox("DropDown", items, 0); - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertField.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertField.java deleted file mode 100644 index 3f993b19..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertField.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderInsertField { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderInsertField.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - builder.getFont().setLocaleId(1031); - builder.insertField("MERGEFIELD Date1 \\@ \"dddd, d MMMM yyyy\""); - builder.write(" - "); - builder.insertField("MERGEFIELD Date2 \\@ \"dddd, d MMMM yyyy\""); - - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertFloatingImage.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertFloatingImage.java deleted file mode 100644 index 1cb80f7c..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertFloatingImage.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderInsertFloatingImage { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderInsertFloatingImage.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - builder.insertImage(dataDir + "test.jpg", - RelativeHorizontalPosition.MARGIN, - 100, - RelativeVerticalPosition.MARGIN, - 100, - 200, - 100, - WrapType.SQUARE); - - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertHtml.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertHtml.java deleted file mode 100644 index 27152f4d..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertHtml.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderInsertHtml { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderInsertHtml.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - builder.insertHtml( - "

          Paragraph right

          " + - "Implicit paragraph left" + - "
          Div center
          " + - "

          Heading 1 left.

          "); - - doc.save(dataDir + "output.doc"); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertHyperlink.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertHyperlink.java deleted file mode 100644 index 3b8e4772..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertHyperlink.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; - -import java.awt.*; - - -public class DocumentBuilderInsertHyperlink { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderInsertHyperlink.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - builder.write("Please make sure to visit "); - - // Specify font formatting for the hyperlink. - builder.getFont().setColor(Color.MAGENTA); - // builder.getFont().setUnderline(); - //builder.Font.Underline = Underline.Single; - // Insert the link. - builder.insertHyperlink("Aspose Website", "http://www.aspose.com", false); - - // Revert to default formatting. - builder.getFont().clearFormatting(); - builder.write(" for more information."); - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertInlineImage.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertInlineImage.java deleted file mode 100644 index 16b217a3..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertInlineImage.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderInsertInlineImage { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderInsertInlineImage.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - builder.insertImage(dataDir + "test.jpg"); - - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertOleObject.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertOleObject.java deleted file mode 100644 index ca5c2e70..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertOleObject.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderInsertOleObject { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderInsertOleObject.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - builder.insertOleObject("http://www.aspose.com", "htmlfile", true, true, null); - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertParagraph.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertParagraph.java deleted file mode 100644 index 7b1eb756..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertParagraph.java +++ /dev/null @@ -1,37 +0,0 @@ - -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.Font; -import com.aspose.words.examples.Utils; - -import java.awt.*; - - -public class DocumentBuilderInsertParagraph { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderInsertParagraph.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - Font font = builder.getFont(); - font.setSize(16); - font.setColor(Color.DARK_GRAY); - font.setBold(true); - font.setName("Algerian"); - font.setUnderline(2); - - ParagraphFormat paragraphFormat = builder.getParagraphFormat(); - paragraphFormat.setFirstLineIndent(12); - paragraphFormat.setAlignment(1); - paragraphFormat.setKeepTogether(true); - - - builder.write("This is a sample Paragraph"); - doc.save(dataDir + "output.doc"); - - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertTableOfContents.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertTableOfContents.java deleted file mode 100644 index 1f5758ce..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertTableOfContents.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.BreakType; -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.StyleIdentifier; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderInsertTableOfContents { - public static void main(String[] args) throws Exception { - - String dataDir = Utils.getDataDir(DocumentBuilderInsertTableOfContents.class); - - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - builder.insertTableOfContents("\\o \"1-3\" \\h \\z \\u"); - builder.insertBreak(BreakType.PAGE_BREAK); - - builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); - builder.writeln("Heading 1"); - - builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); - builder.writeln("Heading 1.1"); - builder.writeln("Heading 1.2"); - - builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); - builder.writeln("Heading 2"); - builder.writeln("Heading 3"); - - builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); - builder.writeln("Heading 3.1"); - - builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_3); - builder.writeln("Heading 3.1.1"); - builder.writeln("Heading 3.1.2"); - builder.writeln("Heading 3.1.3"); - - builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); - builder.writeln("Heading 3.2"); - builder.writeln("Heading 3.3"); - - doc.updateFields(); - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertTextInputFormField.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertTextInputFormField.java deleted file mode 100644 index e07da6f0..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertTextInputFormField.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.TextFormFieldType; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderInsertTextInputFormField { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderInsertTextInputFormField.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", "Hello", 0); - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToBookmark.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToBookmark.java deleted file mode 100644 index dc1c011a..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToBookmark.java +++ /dev/null @@ -1,25 +0,0 @@ - -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderMoveToBookmark { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderMoveToBookmark.class); - - // Open the document. - Document doc = new Document(dataDir + "DocumentBuilder.doc"); - DocumentBuilder builder = new DocumentBuilder(doc); - - builder.moveToBookmark("CoolBookmark"); - builder.writeln("This is a very cool bookmark."); - - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToBookmarkEnd.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToBookmarkEnd.java deleted file mode 100644 index 88c7c571..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToBookmarkEnd.java +++ /dev/null @@ -1,25 +0,0 @@ - -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderMoveToBookmarkEnd { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderMoveToBookmarkEnd.class); - - // Open the document. - Document doc = new Document(dataDir + "DocumentBuilder.doc"); - DocumentBuilder builder = new DocumentBuilder(doc); - - builder.moveToBookmark("CoolBookmark", false, true); - builder.writeln("This is a very cool bookmark."); - - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToDocumentStartEnd.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToDocumentStartEnd.java deleted file mode 100644 index a072a0f9..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToDocumentStartEnd.java +++ /dev/null @@ -1,28 +0,0 @@ - -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderMoveToDocumentStartEnd { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderMoveToDocumentStartEnd.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - builder.moveToDocumentEnd(); - builder.write("\n\nThis is the end of the document."); - - builder.insertParagraph(); - builder.moveToDocumentStart(); - builder.write("\nThis is the beginning of the document."); - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToMergeField.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToMergeField.java deleted file mode 100644 index 80380074..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToMergeField.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderMoveToMergeField { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderMoveToMergeField.class); - - // Open the document. - Document doc = new Document(dataDir + "DocumentBuilder.doc"); - DocumentBuilder builder = new DocumentBuilder(doc); - - builder.moveToMergeField("NiceMergeField"); - builder.writeln("This is a very nice merge field."); - // doc.save(dataDir + "output.doc"); - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToNode.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToNode.java deleted file mode 100644 index cec0b65b..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToNode.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderMoveToNode { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderMoveToNode.class); - - // Open the document. - Document doc = new Document(dataDir + "DocumentBuilder.doc"); - DocumentBuilder builder = new DocumentBuilder(doc); - builder.moveTo(doc.getFirstSection().getBody().getLastParagraph()); - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToParagraph.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToParagraph.java deleted file mode 100644 index 0c1920b0..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToParagraph.java +++ /dev/null @@ -1,25 +0,0 @@ - -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderMoveToParagraph { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderMoveToParagraph.class); - - // Open the document. - Document doc = new Document(dataDir + "DocumentBuilder.doc"); - DocumentBuilder builder = new DocumentBuilder(doc); - - builder.moveToParagraph(2, 0); - builder.writeln("This is the 3rd paragraph."); - - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToSection.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToSection.java deleted file mode 100644 index 618da6ac..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToSection.java +++ /dev/null @@ -1,24 +0,0 @@ - -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderMoveToSection { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderMoveToSection.class); - - // Open the document. - Document doc = new Document(dataDir + "DocumentBuilder.doc"); - DocumentBuilder builder = new DocumentBuilder(doc); - - builder.moveToSection(2); - builder.write("\nThis is third Section\n"); - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToTableCell.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToTableCell.java deleted file mode 100644 index e1757cb3..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToTableCell.java +++ /dev/null @@ -1,26 +0,0 @@ - -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderMoveToTableCell { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderMoveToTableCell.class); - - // Open the document. - Document doc = new Document(dataDir + "DocumentBuilder.doc"); - DocumentBuilder builder = new DocumentBuilder(doc); - - // All parameters are 0-index. Moves to the 2nd table, 3rd row, 5th cell. - builder.moveToCell(1, 2, 4, 0); - builder.writeln("Hello World!"); - - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderSetFontFormatting.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderSetFontFormatting.java deleted file mode 100644 index dc147768..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderSetFontFormatting.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.Font; -import com.aspose.words.Underline; -import com.aspose.words.examples.Utils; - -import java.awt.*; - - -public class DocumentBuilderSetFontFormatting { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderSetFontFormatting.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - Font font = builder.getFont(); - font.setSize(16); - font.setColor(Color.blue); - font.setBold(true); - font.setName("Arial"); - font.setUnderline(Underline.DOTTED); - builder.write("I'm a very nice formatted string."); - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderSetMultilevelListFormatting.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderSetMultilevelListFormatting.java deleted file mode 100644 index 9baa7ab2..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderSetMultilevelListFormatting.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderSetMultilevelListFormatting { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderSetMultilevelListFormatting.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - builder.getListFormat().applyNumberDefault(); - - builder.writeln("Item 1"); - builder.writeln("Item 2"); - - builder.getListFormat().listIndent(); - builder.writeln("Item 2.1"); - builder.writeln("Item 2.2"); - - builder.getListFormat().listIndent(); - builder.writeln("Item 2.1.1"); - builder.writeln("Item 2.2.2"); - - builder.getListFormat().listOutdent(); - builder.writeln("Item 3"); - - builder.getListFormat().removeNumbers(); - - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderSetPageSetupAndSectionFormatting.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderSetPageSetupAndSectionFormatting.java deleted file mode 100644 index cc958b36..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderSetPageSetupAndSectionFormatting.java +++ /dev/null @@ -1,27 +0,0 @@ - -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.Orientation; -import com.aspose.words.PaperSize; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderSetPageSetupAndSectionFormatting { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderSetPageSetupAndSectionFormatting.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - builder.getPageSetup().setOrientation(Orientation.LANDSCAPE); - builder.getPageSetup().setLeftMargin(50); - builder.getPageSetup().setPaperSize(PaperSize.PAPER_10_X_14); - - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderSetParagraphFormatting.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderSetParagraphFormatting.java deleted file mode 100644 index c06f37cd..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderSetParagraphFormatting.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.ParagraphAlignment; -import com.aspose.words.ParagraphFormat; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderSetParagraphFormatting { - public static void main(String[] args) throws Exception { - - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderSetParagraphFormatting.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - ParagraphFormat paragraphFormat = builder.getParagraphFormat(); - paragraphFormat.setAlignment(ParagraphAlignment.CENTER); - paragraphFormat.setLeftIndent(50); - paragraphFormat.setRightIndent(50); - paragraphFormat.setSpaceAfter(25); - paragraphFormat.setKeepTogether(true); - - builder.writeln("I'm a very nice formatted paragraph. I'm intended to demonstrate how the left and right indents affect word wrapping."); - builder.writeln("I'm another nice formatted paragraph. I'm intended to demonstrate how the space after paragraph looks like."); - doc.save(dataDir + "output.doc"); - - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderSetTableCellFormatting.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderSetTableCellFormatting.java deleted file mode 100644 index 34c51b89..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderSetTableCellFormatting.java +++ /dev/null @@ -1,32 +0,0 @@ - -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderSetTableCellFormatting { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderSetTableCellFormatting.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - builder.insertCell(); - CellFormat cellFormat =builder.getCellFormat(); - cellFormat.setWidth(250); - cellFormat.setLeftPadding(30); - cellFormat.setRightPadding(30); - cellFormat.setBottomPadding(30); - cellFormat.setTopPadding(30); - - builder.writeln("I'm a wonderful formatted cell."); - builder.endRow(); - builder.endTable(); - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderSetTableRowFormatting.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderSetTableRowFormatting.java deleted file mode 100644 index d0c46605..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentBuilderSetTableRowFormatting.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - - -public class DocumentBuilderSetTableRowFormatting { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentBuilderSetTableRowFormatting.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - Table table = builder.startTable(); - builder.insertCell(); - - RowFormat rowFormat = builder.getRowFormat(); - rowFormat.setHeight(100); - rowFormat.setHeightRule(HeightRule.EXACTLY); - - table.setBottomPadding(30); - table.setTopPadding(30); - table.setLeftPadding(30); - table.setRightPadding(30); - builder.writeln("I'm a wonderful formatted row."); - - builder.endRow(); - builder.endTable(); - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentInDB.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentInDB.java deleted file mode 100644 index 1eff1faa..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/DocumentInDB.java +++ /dev/null @@ -1,181 +0,0 @@ - -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.SaveFormat; -import com.aspose.words.examples.Utils; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.sql.*; -import java.text.MessageFormat; - - -public class DocumentInDB -{ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(DocumentInDB.class); - - String dbName = dataDir + "DocDB.mdb"; - final String FILE_NAME = "TestFile.doc"; - - // Create a connection to the database. - createConnection(dbName); - - // Open the document. - Document doc = new Document(dataDir + FILE_NAME); - - //ExStart - //ExId:DocumentInDB_Main - //ExSummary:Stores the document to a database, then reads the same document back again, and finally deletes the record containing the document from the database. - // Store the document to the database. - storeToDatabase(doc); - // Read the document from the database and store the file to disk. - Document dbDoc = readFromDatabase(FILE_NAME); - - // Save the retrieved document to disk. - String newFileName = new File(FILE_NAME).getName() + " from DB" + FILE_NAME.substring(FILE_NAME.lastIndexOf(".")); - dbDoc.save(dataDir + newFileName); - - // Delete the document from the database. - deleteFromDatabase(FILE_NAME); - } - - /** - * Stores a document object to the specified database. - * - * @param doc The source document. - */ - //ExStart - //ExId:DocumentInDB_StoreToDB - //ExSummary:Stores the document to the specified database. - public static void storeToDatabase(Document doc) throws Exception - { - // Save the document to a OutputStream object. - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - doc.save(outputStream, SaveFormat.DOC); - - // Get the filename from the document. - String fileName = new File(doc.getOriginalFileName()).getName(); - - // Create the SQL command. - String commandString = "INSERT INTO Documents (FileName, FileContent) VALUES(?, ?)"; - - // Prepare the statement to store the data into the database. - PreparedStatement statement = mConnection.prepareStatement(commandString); - - // Add the parameter value for FileName. - statement.setString(1, fileName); - - // Add the parameter value for FileContent. - statement.setBinaryStream(2, new ByteArrayInputStream(outputStream.toByteArray()), outputStream.size()); - - // Execute and commit the changes. - statement.execute(); - mConnection.commit(); - } - //ExEnd - - /** - * Retreives a document from the specified database and saves it to disk. - * - * @param fileName The name of the document file. - */ - //ExStart - //ExId:DocumentInDB_ReadFromDB - //ExSummary:Retrieves and returns the document from the specified database using the filename as a key to fetch the document. - public static Document readFromDatabase(String fileName) throws Exception - { - // Create the SQL command. - String commandString = "SELECT * FROM Documents WHERE FileName='" + fileName + "'"; - - // Retrieve the results from the database. - ResultSet resultSet = executeQuery(commandString); - - // Check there was a matching record found from the database and throw an exception if no record was found. - if(!resultSet.isBeforeFirst()) - throw new IllegalArgumentException(MessageFormat.format("Could not find any record matching the document \"{0}\" in the database.", fileName)); - - // Move to the first record. - resultSet.next(); - - // The document is stored in byte form in the FileContent column. - // Retrieve these bytes of the first matching record to a new buffer. - byte[] buffer = resultSet.getBytes("FileContent"); - - // Wrap the bytes from the buffer into a new ByteArrayInputStream object. - ByteArrayInputStream newStream = new ByteArrayInputStream(buffer); - - // Read the document from the input stream. - Document doc = new Document(newStream); - - // Return the retrieved document. - return doc; - - } - //ExEnd - - /** - * Deletes the records containing the specified document name from the database. - * - * @param fileName The name of the document file. - */ - //ExStart - //ExId:DocumentInDB_DeleteFromDB - //ExSummary:Delete the document from the database, using filename to fetch the record. - public static void deleteFromDatabase(String fileName) throws Exception - { - // Create the SQL command. - String commandString = "DELETE * FROM Documents WHERE FileName='" + fileName + "'"; - - // Execute the command. - createStatement().executeUpdate(commandString); - } - //ExEnd - - //ExStart - //ExId:DocumentInDB_DatabaseHelpers - //ExSummary:Helper methods used to connect to and execute queries on a database. - /** - * Utility function that creates a connection to the Database. - */ - public static void createConnection(String dataBasePath) throws Exception - { - // Load a DB driver that is used by the demos - Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); - - // The path to the database on the disk. - File dataBase = new File(dataBasePath); - - // Compose connection string. - String connectionString = "jdbc:odbc:DRIVER={Microsoft Access Driver (*.mdb)};" + - "DBQ=" + dataBase + ";UID=Admin"; - // Create a connection to the database. - mConnection = DriverManager.getConnection(connectionString); - } - - /** - * Executes a query on the database. - */ - protected static ResultSet executeQuery(String query) throws Exception - { - return createStatement().executeQuery(query); - } - - /** - * Creates a new database statement. - */ - public static Statement createStatement() throws Exception - { - return mConnection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); - } - //ExEnd - - /* - * A connection to the database. - */ - public static Connection mConnection; -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenBlockLevelNodes.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenBlockLevelNodes.java deleted file mode 100644 index 5085e1c8..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenBlockLevelNodes.java +++ /dev/null @@ -1,230 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.util.ArrayList; -import java.util.Collections; - - -public class ExtractContentBetweenBlockLevelNodes { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ExtractContentBetweenBlockLevelNodes.class); - - Document doc = new Document(dataDir + "TestFile.doc"); - - Paragraph startPara = (Paragraph) doc.getLastSection().getChild(NodeType.PARAGRAPH, 2, true); - Table endTable = (Table) doc.getLastSection().getChild(NodeType.TABLE, 0, true); - - // Extract the content between these nodes in the document. Include these markers in the extraction. - ArrayList extractedNodes = extractContent(startPara, endTable, true); - - // Lets reverse the array to make inserting the content back into the document easier. - Collections.reverse(extractedNodes); - - while (extractedNodes.size() > 0) { - // Insert the last node from the reversed list - endTable.getParentNode().insertAfter((Node) extractedNodes.get(0), endTable); - // Remove this node from the list after insertion. - extractedNodes.remove(0); - } - - // Save the generated document to disk. - doc.save(dataDir + "output.doc"); - - System.out.println("Content extracted between the block level nodes successfully."); - } - - - /** - * Extracts a range of nodes from a document found between specified markers and returns a copy of those nodes. Content can be extracted - * between inline nodes, block level nodes, and also special nodes such as Comment or Boomarks. Any combination of different marker types can used. - * - * @param startNode The node which defines where to start the extraction from the document. This node can be block or inline level of a body. - * @param endNode The node which defines where to stop the extraction from the document. This node can be block or inline level of body. - * @param isInclusive Should the marker nodes be included. - */ - public static ArrayList extractContent(Node startNode, Node endNode, boolean isInclusive) throws Exception { - // First check that the nodes passed to this method are valid for use. - verifyParameterNodes(startNode, endNode); - - // Create a list to store the extracted nodes. - ArrayList nodes = new ArrayList(); - - // Keep a record of the original nodes passed to this method so we can split marker nodes if needed. - Node originalStartNode = startNode; - Node originalEndNode = endNode; - - // Extract content based on block level nodes (paragraphs and tables). Traverse through parent nodes to find them. - // We will split the content of first and last nodes depending if the marker nodes are inline - while (startNode.getParentNode().getNodeType() != NodeType.BODY) - startNode = startNode.getParentNode(); - - while (endNode.getParentNode().getNodeType() != NodeType.BODY) - endNode = endNode.getParentNode(); - - boolean isExtracting = true; - boolean isStartingNode = true; - boolean isEndingNode; - // The current node we are extracting from the document. - Node currNode = startNode; - - // Begin extracting content. Process all block level nodes and specifically split the first and last nodes when needed so paragraph formatting is retained. - // Method is little more complex than a regular extractor as we need to factor in extracting using inline nodes, fields, bookmarks etc as to make it really useful. - while (isExtracting) { - // Clone the current node and its children to obtain a copy. - CompositeNode cloneNode = (CompositeNode) currNode.deepClone(true); - isEndingNode = currNode.equals(endNode); - - if (isStartingNode || isEndingNode) { - // We need to process each marker separately so pass it off to a separate method instead. - if (isStartingNode) { - processMarker(cloneNode, nodes, originalStartNode, isInclusive, isStartingNode, isEndingNode); - isStartingNode = false; - } - - // Conditional needs to be separate as the block level start and end markers maybe the same node. - if (isEndingNode) { - processMarker(cloneNode, nodes, originalEndNode, isInclusive, isStartingNode, isEndingNode); - isExtracting = false; - } - } else - // Node is not a start or end marker, simply add the copy to the list. - nodes.add(cloneNode); - - // Move to the next node and extract it. If next node is null that means the rest of the content is found in a different section. - if (currNode.getNextSibling() == null && isExtracting) { - // Move to the next section. - Section nextSection = (Section) currNode.getAncestor(NodeType.SECTION).getNextSibling(); - currNode = nextSection.getBody().getFirstChild(); - } else { - // Move to the next node in the body. - currNode = currNode.getNextSibling(); - } - } - - // Return the nodes between the node markers. - return nodes; - } - - /** - * Checks the input parameters are correct and can be used. Throws an exception if there is any problem. - */ - private static void verifyParameterNodes(Node startNode, Node endNode) throws Exception { - // The order in which these checks are done is important. - if (startNode == null) - throw new IllegalArgumentException("Start node cannot be null"); - if (endNode == null) - throw new IllegalArgumentException("End node cannot be null"); - - if (!startNode.getDocument().equals(endNode.getDocument())) - throw new IllegalArgumentException("Start node and end node must belong to the same document"); - - if (startNode.getAncestor(NodeType.BODY) == null || endNode.getAncestor(NodeType.BODY) == null) - throw new IllegalArgumentException("Start node and end node must be a child or descendant of a body"); - - // Check the end node is after the start node in the DOM tree - // First check if they are in different sections, then if they're not check their position in the body of the same section they are in. - Section startSection = (Section) startNode.getAncestor(NodeType.SECTION); - Section endSection = (Section) endNode.getAncestor(NodeType.SECTION); - - int startIndex = startSection.getParentNode().indexOf(startSection); - int endIndex = endSection.getParentNode().indexOf(endSection); - - if (startIndex == endIndex) { - if (startSection.getBody().indexOf(startNode) > endSection.getBody().indexOf(endNode)) - throw new IllegalArgumentException("The end node must be after the start node in the body"); - } else if (startIndex > endIndex) - throw new IllegalArgumentException("The section of end node must be after the section start node"); - } - - /** - * Checks if a node passed is an inline node. - */ - private static boolean isInline(Node node) throws Exception { - // Test if the node is desendant of a Paragraph or Table node and also is not a paragraph or a table a paragraph inside a comment class which is decesant of a pararaph is possible. - return ((node.getAncestor(NodeType.PARAGRAPH) != null || node.getAncestor(NodeType.TABLE) != null) && !(node.getNodeType() == NodeType.PARAGRAPH || node.getNodeType() == NodeType.TABLE)); - } - - /** - * Removes the content before or after the marker in the cloned node depending on the type of marker. - */ - private static void processMarker(CompositeNode cloneNode, ArrayList nodes, Node node, boolean isInclusive, boolean isStartMarker, boolean isEndMarker) throws Exception { - // If we are dealing with a block level node just see if it should be included and add it to the list. - if (!isInline(node)) { - // Don't add the node twice if the markers are the same node - if (!(isStartMarker && isEndMarker)) { - if (isInclusive) - nodes.add(cloneNode); - } - return; - } - - // If a marker is a FieldStart node check if it's to be included or not. - // We assume for simplicity that the FieldStart and FieldEnd appear in the same paragraph. - if (node.getNodeType() == NodeType.FIELD_START) { - // If the marker is a start node and is not be included then skip to the end of the field. - // If the marker is an end node and it is to be included then move to the end field so the field will not be removed. - if ((isStartMarker && !isInclusive) || (!isStartMarker && isInclusive)) { - while (node.getNextSibling() != null && node.getNodeType() != NodeType.FIELD_END) - node = node.getNextSibling(); - - } - } - - // If either marker is part of a comment then to include the comment itself we need to move the pointer forward to the Comment - // node found after the CommentRangeEnd node. - if (node.getNodeType() == NodeType.COMMENT_RANGE_END) { - while (node.getNextSibling() != null && node.getNodeType() != NodeType.COMMENT) - node = node.getNextSibling(); - - } - - // Find the corresponding node in our cloned node by index and return it. - // If the start and end node are the same some child nodes might already have been removed. Subtract the - // difference to get the right index. - int indexDiff = node.getParentNode().getChildNodes().getCount() - cloneNode.getChildNodes().getCount(); - - // Child node count identical. - if (indexDiff == 0) - node = cloneNode.getChildNodes().get(node.getParentNode().indexOf(node)); - else - node = cloneNode.getChildNodes().get(node.getParentNode().indexOf(node) - indexDiff); - - // Remove the nodes up to/from the marker. - boolean isSkip; - boolean isProcessing = true; - boolean isRemoving = isStartMarker; - Node nextNode = cloneNode.getFirstChild(); - - while (isProcessing && nextNode != null) { - Node currentNode = nextNode; - isSkip = false; - - if (currentNode.equals(node)) { - if (isStartMarker) { - isProcessing = false; - if (isInclusive) - isRemoving = false; - } else { - isRemoving = true; - if (isInclusive) - isSkip = true; - } - } - - nextNode = nextNode.getNextSibling(); - if (isRemoving && !isSkip) - currentNode.remove(); - } - - // After processing the composite node may become empty. If it has don't include it. - if (!(isStartMarker && isEndMarker)) { - if (cloneNode.hasChildNodes()) - nodes.add(cloneNode); - } - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenBookmarks.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenBookmarks.java deleted file mode 100644 index ee7ea3c1..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenBookmarks.java +++ /dev/null @@ -1,259 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.util.ArrayList; - - -public class ExtractContentBetweenBookmarks { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ExtractContentBetweenBookmarks.class); - - Document doc = new Document(dataDir + "TestFile.doc"); - - // Retrieve the bookmark from the document. - Bookmark bookmark = doc.getRange().getBookmarks().get("Bookmark1"); - - // We use the BookmarkStart and BookmarkEnd nodes as markers. - BookmarkStart bookmarkStart = bookmark.getBookmarkStart(); - BookmarkEnd bookmarkEnd = bookmark.getBookmarkEnd(); - - // Firstly extract the content between these nodes including the bookmark. - ArrayList extractedNodesInclusive = extractContent(bookmarkStart, bookmarkEnd, true); - Document dstDoc = generateDocument(doc, extractedNodesInclusive); - dstDoc.save(dataDir + "TestFile.BookmarkInclusive Out.doc"); - - // Secondly extract the content between these nodes this time without including the bookmark. - ArrayList extractedNodesExclusive = extractContent(bookmarkStart, bookmarkEnd, false); - dstDoc = generateDocument(doc, extractedNodesExclusive); - dstDoc.save(dataDir + "output.doc"); - - System.out.println("Content extracted between bookmarks successfully."); - } - - - /** - * Extracts a range of nodes from a document found between specified markers and returns a copy of those nodes. Content can be extracted - * between inline nodes, block level nodes, and also special nodes such as Comment or Boomarks. Any combination of different marker types can used. - * - * @param startNode The node which defines where to start the extraction from the document. This node can be block or inline level of a body. - * @param endNode The node which defines where to stop the extraction from the document. This node can be block or inline level of body. - * @param isInclusive Should the marker nodes be included. - */ - public static ArrayList extractContent(Node startNode, Node endNode, boolean isInclusive) throws Exception { - // First check that the nodes passed to this method are valid for use. - verifyParameterNodes(startNode, endNode); - - // Create a list to store the extracted nodes. - ArrayList nodes = new ArrayList(); - - // Keep a record of the original nodes passed to this method so we can split marker nodes if needed. - Node originalStartNode = startNode; - Node originalEndNode = endNode; - - // Extract content based on block level nodes (paragraphs and tables). Traverse through parent nodes to find them. - // We will split the content of first and last nodes depending if the marker nodes are inline - while (startNode.getParentNode().getNodeType() != NodeType.BODY) - startNode = startNode.getParentNode(); - - while (endNode.getParentNode().getNodeType() != NodeType.BODY) - endNode = endNode.getParentNode(); - - boolean isExtracting = true; - boolean isStartingNode = true; - boolean isEndingNode; - // The current node we are extracting from the document. - Node currNode = startNode; - - // Begin extracting content. Process all block level nodes and specifically split the first and last nodes when needed so paragraph formatting is retained. - // Method is little more complex than a regular extractor as we need to factor in extracting using inline nodes, fields, bookmarks etc as to make it really useful. - while (isExtracting) { - // Clone the current node and its children to obtain a copy. - CompositeNode cloneNode = (CompositeNode) currNode.deepClone(true); - isEndingNode = currNode.equals(endNode); - - if (isStartingNode || isEndingNode) { - // We need to process each marker separately so pass it off to a separate method instead. - if (isStartingNode) { - processMarker(cloneNode, nodes, originalStartNode, isInclusive, isStartingNode, isEndingNode); - isStartingNode = false; - } - - // Conditional needs to be separate as the block level start and end markers maybe the same node. - if (isEndingNode) { - processMarker(cloneNode, nodes, originalEndNode, isInclusive, isStartingNode, isEndingNode); - isExtracting = false; - } - } else - // Node is not a start or end marker, simply add the copy to the list. - nodes.add(cloneNode); - - // Move to the next node and extract it. If next node is null that means the rest of the content is found in a different section. - if (currNode.getNextSibling() == null && isExtracting) { - // Move to the next section. - Section nextSection = (Section) currNode.getAncestor(NodeType.SECTION).getNextSibling(); - currNode = nextSection.getBody().getFirstChild(); - } else { - // Move to the next node in the body. - currNode = currNode.getNextSibling(); - } - } - - // Return the nodes between the node markers. - return nodes; - } - - /** - * Checks the input parameters are correct and can be used. Throws an exception if there is any problem. - */ - private static void verifyParameterNodes(Node startNode, Node endNode) throws Exception { - // The order in which these checks are done is important. - if (startNode == null) - throw new IllegalArgumentException("Start node cannot be null"); - if (endNode == null) - throw new IllegalArgumentException("End node cannot be null"); - - if (!startNode.getDocument().equals(endNode.getDocument())) - throw new IllegalArgumentException("Start node and end node must belong to the same document"); - - if (startNode.getAncestor(NodeType.BODY) == null || endNode.getAncestor(NodeType.BODY) == null) - throw new IllegalArgumentException("Start node and end node must be a child or descendant of a body"); - - // Check the end node is after the start node in the DOM tree - // First check if they are in different sections, then if they're not check their position in the body of the same section they are in. - Section startSection = (Section) startNode.getAncestor(NodeType.SECTION); - Section endSection = (Section) endNode.getAncestor(NodeType.SECTION); - - int startIndex = startSection.getParentNode().indexOf(startSection); - int endIndex = endSection.getParentNode().indexOf(endSection); - - if (startIndex == endIndex) { - if (startSection.getBody().indexOf(startNode) > endSection.getBody().indexOf(endNode)) - throw new IllegalArgumentException("The end node must be after the start node in the body"); - } else if (startIndex > endIndex) - throw new IllegalArgumentException("The section of end node must be after the section start node"); - } - - /** - * Checks if a node passed is an inline node. - */ - private static boolean isInline(Node node) throws Exception { - // Test if the node is desendant of a Paragraph or Table node and also is not a paragraph or a table a paragraph inside a comment class which is decesant of a pararaph is possible. - return ((node.getAncestor(NodeType.PARAGRAPH) != null || node.getAncestor(NodeType.TABLE) != null) && !(node.getNodeType() == NodeType.PARAGRAPH || node.getNodeType() == NodeType.TABLE)); - } - - /** - * Removes the content before or after the marker in the cloned node depending on the type of marker. - */ - private static void processMarker(CompositeNode cloneNode, ArrayList nodes, Node node, boolean isInclusive, boolean isStartMarker, boolean isEndMarker) throws Exception { - // If we are dealing with a block level node just see if it should be included and add it to the list. - if (!isInline(node)) { - // Don't add the node twice if the markers are the same node - if (!(isStartMarker && isEndMarker)) { - if (isInclusive) - nodes.add(cloneNode); - } - return; - } - - // If a marker is a FieldStart node check if it's to be included or not. - // We assume for simplicity that the FieldStart and FieldEnd appear in the same paragraph. - if (node.getNodeType() == NodeType.FIELD_START) { - // If the marker is a start node and is not be included then skip to the end of the field. - // If the marker is an end node and it is to be included then move to the end field so the field will not be removed. - if ((isStartMarker && !isInclusive) || (!isStartMarker && isInclusive)) { - while (node.getNextSibling() != null && node.getNodeType() != NodeType.FIELD_END) - node = node.getNextSibling(); - - } - } - - // If either marker is part of a comment then to include the comment itself we need to move the pointer forward to the Comment - // node found after the CommentRangeEnd node. - if (node.getNodeType() == NodeType.COMMENT_RANGE_END) { - while (node.getNextSibling() != null && node.getNodeType() != NodeType.COMMENT) - node = node.getNextSibling(); - - } - - // Find the corresponding node in our cloned node by index and return it. - // If the start and end node are the same some child nodes might already have been removed. Subtract the - // difference to get the right index. - int indexDiff = node.getParentNode().getChildNodes().getCount() - cloneNode.getChildNodes().getCount(); - - // Child node count identical. - if (indexDiff == 0) - node = cloneNode.getChildNodes().get(node.getParentNode().indexOf(node)); - else - node = cloneNode.getChildNodes().get(node.getParentNode().indexOf(node) - indexDiff); - - // Remove the nodes up to/from the marker. - boolean isSkip; - boolean isProcessing = true; - boolean isRemoving = isStartMarker; - Node nextNode = cloneNode.getFirstChild(); - - while (isProcessing && nextNode != null) { - Node currentNode = nextNode; - isSkip = false; - - if (currentNode.equals(node)) { - if (isStartMarker) { - isProcessing = false; - if (isInclusive) - isRemoving = false; - } else { - isRemoving = true; - if (isInclusive) - isSkip = true; - } - } - - nextNode = nextNode.getNextSibling(); - if (isRemoving && !isSkip) - currentNode.remove(); - } - - // After processing the composite node may become empty. If it has don't include it. - if (!(isStartMarker && isEndMarker)) { - if (cloneNode.hasChildNodes()) - nodes.add(cloneNode); - } - - } - - public static Document generateDocument(Document srcDoc, ArrayList nodes) throws Exception { - // Create a blank document. - Document dstDoc = new Document(); - // Remove the first paragraph from the empty document. - dstDoc.getFirstSection().getBody().removeAllChildren(); - - // Import each node from the list into the new document. Keep the original formatting of the node. - NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - - for (Node node : (Iterable) nodes) { - Node importNode = importer.importNode(node, true); - dstDoc.getFirstSection().getBody().appendChild(importNode); - } - - // Return the generated document. - return dstDoc; - } - - public static ArrayList paragraphsByStyleName(Document doc, String styleName) throws Exception { - // Create an array to collect paragraphs of the specified style. - ArrayList paragraphsWithStyle = new ArrayList(); - // Get all paragraphs from the document. - NodeCollection paragraphs = doc.getChildNodes(NodeType.PARAGRAPH, true); - // Look through all paragraphs to find those with the specified style. - for (Paragraph paragraph : (Iterable) paragraphs) { - if (paragraph.getParagraphFormat().getStyle().getName().equals(styleName)) - paragraphsWithStyle.add(paragraph); - } - return paragraphsWithStyle; - } - -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenCommentRange.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenCommentRange.java deleted file mode 100644 index cc732396..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenCommentRange.java +++ /dev/null @@ -1,257 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.util.ArrayList; - - -public class ExtractContentBetweenCommentRange { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ExtractContentBetweenCommentRange.class); - - Document doc = new Document(dataDir + "TestFile.doc"); - - // This is a quick way of getting both comment nodes. - // Your code should have a proper method of retrieving each corresponding start and end node. - CommentRangeStart commentStart = (CommentRangeStart) doc.getChild(NodeType.COMMENT_RANGE_START, 0, true); - CommentRangeEnd commentEnd = (CommentRangeEnd) doc.getChild(NodeType.COMMENT_RANGE_END, 0, true); - - // Firstly extract the content between these nodes including the comment as well. - ArrayList extractedNodesInclusive = extractContent(commentStart, commentEnd, true); - Document dstDoc = generateDocument(doc, extractedNodesInclusive); - dstDoc.save(dataDir + "TestFile.CommentInclusive Out.doc"); - - // Secondly extract the content between these nodes without the comment. - ArrayList extractedNodesExclusive = extractContent(commentStart, commentEnd, false); - dstDoc = generateDocument(doc, extractedNodesExclusive); - dstDoc.save(dataDir + "output.doc"); - - System.out.println("Content extracted between comment range successfully."); - } - - - /** - * Extracts a range of nodes from a document found between specified markers and returns a copy of those nodes. Content can be extracted - * between inline nodes, block level nodes, and also special nodes such as Comment or Boomarks. Any combination of different marker types can used. - * - * @param startNode The node which defines where to start the extraction from the document. This node can be block or inline level of a body. - * @param endNode The node which defines where to stop the extraction from the document. This node can be block or inline level of body. - * @param isInclusive Should the marker nodes be included. - */ - public static ArrayList extractContent(Node startNode, Node endNode, boolean isInclusive) throws Exception { - // First check that the nodes passed to this method are valid for use. - verifyParameterNodes(startNode, endNode); - - // Create a list to store the extracted nodes. - ArrayList nodes = new ArrayList(); - - // Keep a record of the original nodes passed to this method so we can split marker nodes if needed. - Node originalStartNode = startNode; - Node originalEndNode = endNode; - - // Extract content based on block level nodes (paragraphs and tables). Traverse through parent nodes to find them. - // We will split the content of first and last nodes depending if the marker nodes are inline - while (startNode.getParentNode().getNodeType() != NodeType.BODY) - startNode = startNode.getParentNode(); - - while (endNode.getParentNode().getNodeType() != NodeType.BODY) - endNode = endNode.getParentNode(); - - boolean isExtracting = true; - boolean isStartingNode = true; - boolean isEndingNode; - // The current node we are extracting from the document. - Node currNode = startNode; - - // Begin extracting content. Process all block level nodes and specifically split the first and last nodes when needed so paragraph formatting is retained. - // Method is little more complex than a regular extractor as we need to factor in extracting using inline nodes, fields, bookmarks etc as to make it really useful. - while (isExtracting) { - // Clone the current node and its children to obtain a copy. - CompositeNode cloneNode = (CompositeNode) currNode.deepClone(true); - isEndingNode = currNode.equals(endNode); - - if (isStartingNode || isEndingNode) { - // We need to process each marker separately so pass it off to a separate method instead. - if (isStartingNode) { - processMarker(cloneNode, nodes, originalStartNode, isInclusive, isStartingNode, isEndingNode); - isStartingNode = false; - } - - // Conditional needs to be separate as the block level start and end markers maybe the same node. - if (isEndingNode) { - processMarker(cloneNode, nodes, originalEndNode, isInclusive, isStartingNode, isEndingNode); - isExtracting = false; - } - } else - // Node is not a start or end marker, simply add the copy to the list. - nodes.add(cloneNode); - - // Move to the next node and extract it. If next node is null that means the rest of the content is found in a different section. - if (currNode.getNextSibling() == null && isExtracting) { - // Move to the next section. - Section nextSection = (Section) currNode.getAncestor(NodeType.SECTION).getNextSibling(); - currNode = nextSection.getBody().getFirstChild(); - } else { - // Move to the next node in the body. - currNode = currNode.getNextSibling(); - } - } - - // Return the nodes between the node markers. - return nodes; - } - - /** - * Checks the input parameters are correct and can be used. Throws an exception if there is any problem. - */ - private static void verifyParameterNodes(Node startNode, Node endNode) throws Exception { - // The order in which these checks are done is important. - if (startNode == null) - throw new IllegalArgumentException("Start node cannot be null"); - if (endNode == null) - throw new IllegalArgumentException("End node cannot be null"); - - if (!startNode.getDocument().equals(endNode.getDocument())) - throw new IllegalArgumentException("Start node and end node must belong to the same document"); - - if (startNode.getAncestor(NodeType.BODY) == null || endNode.getAncestor(NodeType.BODY) == null) - throw new IllegalArgumentException("Start node and end node must be a child or descendant of a body"); - - // Check the end node is after the start node in the DOM tree - // First check if they are in different sections, then if they're not check their position in the body of the same section they are in. - Section startSection = (Section) startNode.getAncestor(NodeType.SECTION); - Section endSection = (Section) endNode.getAncestor(NodeType.SECTION); - - int startIndex = startSection.getParentNode().indexOf(startSection); - int endIndex = endSection.getParentNode().indexOf(endSection); - - if (startIndex == endIndex) { - if (startSection.getBody().indexOf(startNode) > endSection.getBody().indexOf(endNode)) - throw new IllegalArgumentException("The end node must be after the start node in the body"); - } else if (startIndex > endIndex) - throw new IllegalArgumentException("The section of end node must be after the section start node"); - } - - /** - * Checks if a node passed is an inline node. - */ - private static boolean isInline(Node node) throws Exception { - // Test if the node is desendant of a Paragraph or Table node and also is not a paragraph or a table a paragraph inside a comment class which is decesant of a pararaph is possible. - return ((node.getAncestor(NodeType.PARAGRAPH) != null || node.getAncestor(NodeType.TABLE) != null) && !(node.getNodeType() == NodeType.PARAGRAPH || node.getNodeType() == NodeType.TABLE)); - } - - /** - * Removes the content before or after the marker in the cloned node depending on the type of marker. - */ - private static void processMarker(CompositeNode cloneNode, ArrayList nodes, Node node, boolean isInclusive, boolean isStartMarker, boolean isEndMarker) throws Exception { - // If we are dealing with a block level node just see if it should be included and add it to the list. - if (!isInline(node)) { - // Don't add the node twice if the markers are the same node - if (!(isStartMarker && isEndMarker)) { - if (isInclusive) - nodes.add(cloneNode); - } - return; - } - - // If a marker is a FieldStart node check if it's to be included or not. - // We assume for simplicity that the FieldStart and FieldEnd appear in the same paragraph. - if (node.getNodeType() == NodeType.FIELD_START) { - // If the marker is a start node and is not be included then skip to the end of the field. - // If the marker is an end node and it is to be included then move to the end field so the field will not be removed. - if ((isStartMarker && !isInclusive) || (!isStartMarker && isInclusive)) { - while (node.getNextSibling() != null && node.getNodeType() != NodeType.FIELD_END) - node = node.getNextSibling(); - - } - } - - // If either marker is part of a comment then to include the comment itself we need to move the pointer forward to the Comment - // node found after the CommentRangeEnd node. - if (node.getNodeType() == NodeType.COMMENT_RANGE_END) { - while (node.getNextSibling() != null && node.getNodeType() != NodeType.COMMENT) - node = node.getNextSibling(); - - } - - // Find the corresponding node in our cloned node by index and return it. - // If the start and end node are the same some child nodes might already have been removed. Subtract the - // difference to get the right index. - int indexDiff = node.getParentNode().getChildNodes().getCount() - cloneNode.getChildNodes().getCount(); - - // Child node count identical. - if (indexDiff == 0) - node = cloneNode.getChildNodes().get(node.getParentNode().indexOf(node)); - else - node = cloneNode.getChildNodes().get(node.getParentNode().indexOf(node) - indexDiff); - - // Remove the nodes up to/from the marker. - boolean isSkip; - boolean isProcessing = true; - boolean isRemoving = isStartMarker; - Node nextNode = cloneNode.getFirstChild(); - - while (isProcessing && nextNode != null) { - Node currentNode = nextNode; - isSkip = false; - - if (currentNode.equals(node)) { - if (isStartMarker) { - isProcessing = false; - if (isInclusive) - isRemoving = false; - } else { - isRemoving = true; - if (isInclusive) - isSkip = true; - } - } - - nextNode = nextNode.getNextSibling(); - if (isRemoving && !isSkip) - currentNode.remove(); - } - - // After processing the composite node may become empty. If it has don't include it. - if (!(isStartMarker && isEndMarker)) { - if (cloneNode.hasChildNodes()) - nodes.add(cloneNode); - } - - } - - public static Document generateDocument(Document srcDoc, ArrayList nodes) throws Exception { - // Create a blank document. - Document dstDoc = new Document(); - // Remove the first paragraph from the empty document. - dstDoc.getFirstSection().getBody().removeAllChildren(); - - // Import each node from the list into the new document. Keep the original formatting of the node. - NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - - for (Node node : (Iterable) nodes) { - Node importNode = importer.importNode(node, true); - dstDoc.getFirstSection().getBody().appendChild(importNode); - } - - // Return the generated document. - return dstDoc; - } - - public static ArrayList paragraphsByStyleName(Document doc, String styleName) throws Exception { - // Create an array to collect paragraphs of the specified style. - ArrayList paragraphsWithStyle = new ArrayList(); - // Get all paragraphs from the document. - NodeCollection paragraphs = doc.getChildNodes(NodeType.PARAGRAPH, true); - // Look through all paragraphs to find those with the specified style. - for (Paragraph paragraph : (Iterable) paragraphs) { - if (paragraph.getParagraphFormat().getStyle().getName().equals(styleName)) - paragraphsWithStyle.add(paragraph); - } - return paragraphsWithStyle; - } - -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenParagraphStyles.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenParagraphStyles.java deleted file mode 100644 index 5d959c22..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenParagraphStyles.java +++ /dev/null @@ -1,257 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.util.ArrayList; - - -public class ExtractContentBetweenParagraphStyles { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ExtractContentBetweenParagraphStyles.class); - - Document doc = new Document(dataDir + "TestFile.doc"); - - // Gather a list of the paragraphs using the respective heading styles. - ArrayList parasStyleHeading1 = paragraphsByStyleName(doc, "Heading 1"); - ArrayList parasStyleHeading3 = paragraphsByStyleName(doc, "Heading 3"); - - // Use the first instance of the paragraphs with those styles. - Node startPara1 = (Node) parasStyleHeading1.get(0); - Node endPara1 = (Node) parasStyleHeading3.get(0); - - // Extract the content between these nodes in the document. Don't include these markers in the extraction. - ArrayList extractedNodes = extractContent(startPara1, endPara1, false); - - // Insert the content into a new separate document and save it to disk. - Document dstDoc = generateDocument(doc, extractedNodes); - dstDoc.save(dataDir + "output.doc"); - - System.out.println("Content extracted between the paragraph styles successfully."); - } - - - /** - * Extracts a range of nodes from a document found between specified markers and returns a copy of those nodes. Content can be extracted - * between inline nodes, block level nodes, and also special nodes such as Comment or Boomarks. Any combination of different marker types can used. - * - * @param startNode The node which defines where to start the extraction from the document. This node can be block or inline level of a body. - * @param endNode The node which defines where to stop the extraction from the document. This node can be block or inline level of body. - * @param isInclusive Should the marker nodes be included. - */ - public static ArrayList extractContent(Node startNode, Node endNode, boolean isInclusive) throws Exception { - // First check that the nodes passed to this method are valid for use. - verifyParameterNodes(startNode, endNode); - - // Create a list to store the extracted nodes. - ArrayList nodes = new ArrayList(); - - // Keep a record of the original nodes passed to this method so we can split marker nodes if needed. - Node originalStartNode = startNode; - Node originalEndNode = endNode; - - // Extract content based on block level nodes (paragraphs and tables). Traverse through parent nodes to find them. - // We will split the content of first and last nodes depending if the marker nodes are inline - while (startNode.getParentNode().getNodeType() != NodeType.BODY) - startNode = startNode.getParentNode(); - - while (endNode.getParentNode().getNodeType() != NodeType.BODY) - endNode = endNode.getParentNode(); - - boolean isExtracting = true; - boolean isStartingNode = true; - boolean isEndingNode; - // The current node we are extracting from the document. - Node currNode = startNode; - - // Begin extracting content. Process all block level nodes and specifically split the first and last nodes when needed so paragraph formatting is retained. - // Method is little more complex than a regular extractor as we need to factor in extracting using inline nodes, fields, bookmarks etc as to make it really useful. - while (isExtracting) { - // Clone the current node and its children to obtain a copy. - CompositeNode cloneNode = (CompositeNode) currNode.deepClone(true); - isEndingNode = currNode.equals(endNode); - - if (isStartingNode || isEndingNode) { - // We need to process each marker separately so pass it off to a separate method instead. - if (isStartingNode) { - processMarker(cloneNode, nodes, originalStartNode, isInclusive, isStartingNode, isEndingNode); - isStartingNode = false; - } - - // Conditional needs to be separate as the block level start and end markers maybe the same node. - if (isEndingNode) { - processMarker(cloneNode, nodes, originalEndNode, isInclusive, isStartingNode, isEndingNode); - isExtracting = false; - } - } else - // Node is not a start or end marker, simply add the copy to the list. - nodes.add(cloneNode); - - // Move to the next node and extract it. If next node is null that means the rest of the content is found in a different section. - if (currNode.getNextSibling() == null && isExtracting) { - // Move to the next section. - Section nextSection = (Section) currNode.getAncestor(NodeType.SECTION).getNextSibling(); - currNode = nextSection.getBody().getFirstChild(); - } else { - // Move to the next node in the body. - currNode = currNode.getNextSibling(); - } - } - - // Return the nodes between the node markers. - return nodes; - } - - /** - * Checks the input parameters are correct and can be used. Throws an exception if there is any problem. - */ - private static void verifyParameterNodes(Node startNode, Node endNode) throws Exception { - // The order in which these checks are done is important. - if (startNode == null) - throw new IllegalArgumentException("Start node cannot be null"); - if (endNode == null) - throw new IllegalArgumentException("End node cannot be null"); - - if (!startNode.getDocument().equals(endNode.getDocument())) - throw new IllegalArgumentException("Start node and end node must belong to the same document"); - - if (startNode.getAncestor(NodeType.BODY) == null || endNode.getAncestor(NodeType.BODY) == null) - throw new IllegalArgumentException("Start node and end node must be a child or descendant of a body"); - - // Check the end node is after the start node in the DOM tree - // First check if they are in different sections, then if they're not check their position in the body of the same section they are in. - Section startSection = (Section) startNode.getAncestor(NodeType.SECTION); - Section endSection = (Section) endNode.getAncestor(NodeType.SECTION); - - int startIndex = startSection.getParentNode().indexOf(startSection); - int endIndex = endSection.getParentNode().indexOf(endSection); - - if (startIndex == endIndex) { - if (startSection.getBody().indexOf(startNode) > endSection.getBody().indexOf(endNode)) - throw new IllegalArgumentException("The end node must be after the start node in the body"); - } else if (startIndex > endIndex) - throw new IllegalArgumentException("The section of end node must be after the section start node"); - } - - /** - * Checks if a node passed is an inline node. - */ - private static boolean isInline(Node node) throws Exception { - // Test if the node is desendant of a Paragraph or Table node and also is not a paragraph or a table a paragraph inside a comment class which is decesant of a pararaph is possible. - return ((node.getAncestor(NodeType.PARAGRAPH) != null || node.getAncestor(NodeType.TABLE) != null) && !(node.getNodeType() == NodeType.PARAGRAPH || node.getNodeType() == NodeType.TABLE)); - } - - /** - * Removes the content before or after the marker in the cloned node depending on the type of marker. - */ - private static void processMarker(CompositeNode cloneNode, ArrayList nodes, Node node, boolean isInclusive, boolean isStartMarker, boolean isEndMarker) throws Exception { - // If we are dealing with a block level node just see if it should be included and add it to the list. - if (!isInline(node)) { - // Don't add the node twice if the markers are the same node - if (!(isStartMarker && isEndMarker)) { - if (isInclusive) - nodes.add(cloneNode); - } - return; - } - - // If a marker is a FieldStart node check if it's to be included or not. - // We assume for simplicity that the FieldStart and FieldEnd appear in the same paragraph. - if (node.getNodeType() == NodeType.FIELD_START) { - // If the marker is a start node and is not be included then skip to the end of the field. - // If the marker is an end node and it is to be included then move to the end field so the field will not be removed. - if ((isStartMarker && !isInclusive) || (!isStartMarker && isInclusive)) { - while (node.getNextSibling() != null && node.getNodeType() != NodeType.FIELD_END) - node = node.getNextSibling(); - - } - } - - // If either marker is part of a comment then to include the comment itself we need to move the pointer forward to the Comment - // node found after the CommentRangeEnd node. - if (node.getNodeType() == NodeType.COMMENT_RANGE_END) { - while (node.getNextSibling() != null && node.getNodeType() != NodeType.COMMENT) - node = node.getNextSibling(); - - } - - // Find the corresponding node in our cloned node by index and return it. - // If the start and end node are the same some child nodes might already have been removed. Subtract the - // difference to get the right index. - int indexDiff = node.getParentNode().getChildNodes().getCount() - cloneNode.getChildNodes().getCount(); - - // Child node count identical. - if (indexDiff == 0) - node = cloneNode.getChildNodes().get(node.getParentNode().indexOf(node)); - else - node = cloneNode.getChildNodes().get(node.getParentNode().indexOf(node) - indexDiff); - - // Remove the nodes up to/from the marker. - boolean isSkip; - boolean isProcessing = true; - boolean isRemoving = isStartMarker; - Node nextNode = cloneNode.getFirstChild(); - - while (isProcessing && nextNode != null) { - Node currentNode = nextNode; - isSkip = false; - - if (currentNode.equals(node)) { - if (isStartMarker) { - isProcessing = false; - if (isInclusive) - isRemoving = false; - } else { - isRemoving = true; - if (isInclusive) - isSkip = true; - } - } - - nextNode = nextNode.getNextSibling(); - if (isRemoving && !isSkip) - currentNode.remove(); - } - - // After processing the composite node may become empty. If it has don't include it. - if (!(isStartMarker && isEndMarker)) { - if (cloneNode.hasChildNodes()) - nodes.add(cloneNode); - } - - } - - public static Document generateDocument(Document srcDoc, ArrayList nodes) throws Exception { - // Create a blank document. - Document dstDoc = new Document(); - // Remove the first paragraph from the empty document. - dstDoc.getFirstSection().getBody().removeAllChildren(); - - // Import each node from the list into the new document. Keep the original formatting of the node. - NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - - for (Node node : (Iterable) nodes) { - Node importNode = importer.importNode(node, true); - dstDoc.getFirstSection().getBody().appendChild(importNode); - } - - // Return the generated document. - return dstDoc; - } - - public static ArrayList paragraphsByStyleName(Document doc, String styleName) throws Exception { - // Create an array to collect paragraphs of the specified style. - ArrayList paragraphsWithStyle = new ArrayList(); - // Get all paragraphs from the document. - NodeCollection paragraphs = doc.getChildNodes(NodeType.PARAGRAPH, true); - // Look through all paragraphs to find those with the specified style. - for (Paragraph paragraph : (Iterable) paragraphs) { - if (paragraph.getParagraphFormat().getStyle().getName().equals(styleName)) - paragraphsWithStyle.add(paragraph); - } - return paragraphsWithStyle; - } - -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenParagraphs.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenParagraphs.java deleted file mode 100644 index 4344e5d7..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenParagraphs.java +++ /dev/null @@ -1,240 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.util.ArrayList; - - -public class ExtractContentBetweenParagraphs { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ExtractContentBetweenParagraphs.class); - - Document doc = new Document(dataDir + "TestFile.doc"); - - // Gather the nodes. The GetChild method uses 0-based index - Paragraph startPara = (Paragraph) doc.getFirstSection().getChild(NodeType.PARAGRAPH, 6, true); - Paragraph endPara = (Paragraph) doc.getFirstSection().getChild(NodeType.PARAGRAPH, 10, true); - // Extract the content between these nodes in the document. Include these markers in the extraction. - ArrayList extractedNodes = extractContent(startPara, endPara, true); - - // Insert the content into a new separate document and save it to disk. - Document dstDoc = generateDocument(doc, extractedNodes); - dstDoc.save(dataDir + "output.doc"); - - System.out.println("Content extracted between the paragraphs successfully."); - } - - - /** - * Extracts a range of nodes from a document found between specified markers and returns a copy of those nodes. Content can be extracted - * between inline nodes, block level nodes, and also special nodes such as Comment or Boomarks. Any combination of different marker types can used. - * - * @param startNode The node which defines where to start the extraction from the document. This node can be block or inline level of a body. - * @param endNode The node which defines where to stop the extraction from the document. This node can be block or inline level of body. - * @param isInclusive Should the marker nodes be included. - */ - - public static ArrayList extractContent(Node startNode, Node endNode, boolean isInclusive) throws Exception { - // First check that the nodes passed to this method are valid for use. - verifyParameterNodes(startNode, endNode); - - // Create a list to store the extracted nodes. - ArrayList nodes = new ArrayList(); - - // Keep a record of the original nodes passed to this method so we can split marker nodes if needed. - Node originalStartNode = startNode; - Node originalEndNode = endNode; - - // Extract content based on block level nodes (paragraphs and tables). Traverse through parent nodes to find them. - // We will split the content of first and last nodes depending if the marker nodes are inline - while (startNode.getParentNode().getNodeType() != NodeType.BODY) - startNode = startNode.getParentNode(); - - while (endNode.getParentNode().getNodeType() != NodeType.BODY) - endNode = endNode.getParentNode(); - - boolean isExtracting = true; - boolean isStartingNode = true; - boolean isEndingNode; - // The current node we are extracting from the document. - Node currNode = startNode; - - // Begin extracting content. Process all block level nodes and specifically split the first and last nodes when needed so paragraph formatting is retained. - // Method is little more complex than a regular extractor as we need to factor in extracting using inline nodes, fields, bookmarks etc as to make it really useful. - while (isExtracting) { - // Clone the current node and its children to obtain a copy. - CompositeNode cloneNode = (CompositeNode) currNode.deepClone(true); - isEndingNode = currNode.equals(endNode); - - if (isStartingNode || isEndingNode) { - // We need to process each marker separately so pass it off to a separate method instead. - if (isStartingNode) { - processMarker(cloneNode, nodes, originalStartNode, isInclusive, isStartingNode, isEndingNode); - isStartingNode = false; - } - - // Conditional needs to be separate as the block level start and end markers maybe the same node. - if (isEndingNode) { - processMarker(cloneNode, nodes, originalEndNode, isInclusive, isStartingNode, isEndingNode); - isExtracting = false; - } - } else - // Node is not a start or end marker, simply add the copy to the list. - nodes.add(cloneNode); - - // Move to the next node and extract it. If next node is null that means the rest of the content is found in a different section. - if (currNode.getNextSibling() == null && isExtracting) { - // Move to the next section. - Section nextSection = (Section) currNode.getAncestor(NodeType.SECTION).getNextSibling(); - currNode = nextSection.getBody().getFirstChild(); - } else { - // Move to the next node in the body. - currNode = currNode.getNextSibling(); - } - } - - // Return the nodes between the node markers. - return nodes; - } - - /** - * Checks the input parameters are correct and can be used. Throws an exception if there is any problem. - */ - - private static void verifyParameterNodes(Node startNode, Node endNode) throws Exception { - // The order in which these checks are done is important. - if (startNode == null) - throw new IllegalArgumentException("Start node cannot be null"); - if (endNode == null) - throw new IllegalArgumentException("End node cannot be null"); - - if (!startNode.getDocument().equals(endNode.getDocument())) - throw new IllegalArgumentException("Start node and end node must belong to the same document"); - - if (startNode.getAncestor(NodeType.BODY) == null || endNode.getAncestor(NodeType.BODY) == null) - throw new IllegalArgumentException("Start node and end node must be a child or descendant of a body"); - - // Check the end node is after the start node in the DOM tree - // First check if they are in different sections, then if they're not check their position in the body of the same section they are in. - Section startSection = (Section) startNode.getAncestor(NodeType.SECTION); - Section endSection = (Section) endNode.getAncestor(NodeType.SECTION); - - int startIndex = startSection.getParentNode().indexOf(startSection); - int endIndex = endSection.getParentNode().indexOf(endSection); - - if (startIndex == endIndex) { - if (startSection.getBody().indexOf(startNode) > endSection.getBody().indexOf(endNode)) - throw new IllegalArgumentException("The end node must be after the start node in the body"); - } else if (startIndex > endIndex) - throw new IllegalArgumentException("The section of end node must be after the section start node"); - } - - /** - * Checks if a node passed is an inline node. - */ - private static boolean isInline(Node node) throws Exception { - // Test if the node is desendant of a Paragraph or Table node and also is not a paragraph or a table a paragraph inside a comment class which is decesant of a pararaph is possible. - return ((node.getAncestor(NodeType.PARAGRAPH) != null || node.getAncestor(NodeType.TABLE) != null) && !(node.getNodeType() == NodeType.PARAGRAPH || node.getNodeType() == NodeType.TABLE)); - } - - /** - * Removes the content before or after the marker in the cloned node depending on the type of marker. - */ - private static void processMarker(CompositeNode cloneNode, ArrayList nodes, Node node, boolean isInclusive, boolean isStartMarker, boolean isEndMarker) throws Exception { - // If we are dealing with a block level node just see if it should be included and add it to the list. - if (!isInline(node)) { - // Don't add the node twice if the markers are the same node - if (!(isStartMarker && isEndMarker)) { - if (isInclusive) - nodes.add(cloneNode); - } - return; - } - - // If a marker is a FieldStart node check if it's to be included or not. - // We assume for simplicity that the FieldStart and FieldEnd appear in the same paragraph. - if (node.getNodeType() == NodeType.FIELD_START) { - // If the marker is a start node and is not be included then skip to the end of the field. - // If the marker is an end node and it is to be included then move to the end field so the field will not be removed. - if ((isStartMarker && !isInclusive) || (!isStartMarker && isInclusive)) { - while (node.getNextSibling() != null && node.getNodeType() != NodeType.FIELD_END) - node = node.getNextSibling(); - - } - } - - // If either marker is part of a comment then to include the comment itself we need to move the pointer forward to the Comment - // node found after the CommentRangeEnd node. - if (node.getNodeType() == NodeType.COMMENT_RANGE_END) { - while (node.getNextSibling() != null && node.getNodeType() != NodeType.COMMENT) - node = node.getNextSibling(); - - } - - // Find the corresponding node in our cloned node by index and return it. - // If the start and end node are the same some child nodes might already have been removed. Subtract the - // difference to get the right index. - int indexDiff = node.getParentNode().getChildNodes().getCount() - cloneNode.getChildNodes().getCount(); - - // Child node count identical. - if (indexDiff == 0) - node = cloneNode.getChildNodes().get(node.getParentNode().indexOf(node)); - else - node = cloneNode.getChildNodes().get(node.getParentNode().indexOf(node) - indexDiff); - - // Remove the nodes up to/from the marker. - boolean isSkip; - boolean isProcessing = true; - boolean isRemoving = isStartMarker; - Node nextNode = cloneNode.getFirstChild(); - - while (isProcessing && nextNode != null) { - Node currentNode = nextNode; - isSkip = false; - - if (currentNode.equals(node)) { - if (isStartMarker) { - isProcessing = false; - if (isInclusive) - isRemoving = false; - } else { - isRemoving = true; - if (isInclusive) - isSkip = true; - } - } - - nextNode = nextNode.getNextSibling(); - if (isRemoving && !isSkip) - currentNode.remove(); - } - - // After processing the composite node may become empty. If it has don't include it. - if (!(isStartMarker && isEndMarker)) { - if (cloneNode.hasChildNodes()) - nodes.add(cloneNode); - } - } - - public static Document generateDocument(Document srcDoc, ArrayList nodes) throws Exception { - - // Create a blank document. - Document dstDoc = new Document(); - // Remove the first paragraph from the empty document. - dstDoc.getFirstSection().getBody().removeAllChildren(); - - // Import each node from the list into the new document. Keep the original formatting of the node. - NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - - for (Node node : (Iterable) nodes) { - Node importNode = importer.importNode(node, true); - dstDoc.getFirstSection().getBody().appendChild(importNode); - } - - // Return the generated document. - return dstDoc; - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenRuns.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenRuns.java deleted file mode 100644 index 965a84dc..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenRuns.java +++ /dev/null @@ -1,257 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.util.ArrayList; - - -public class ExtractContentBetweenRuns { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ExtractContentBetweenRuns.class); - - Document doc = new Document(dataDir + "TestFile.doc"); - - // Retrieve a paragraph from the first section. - Paragraph para = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 7, true); - - // Use some runs for extraction. - Run startRun = para.getRuns().get(1); - Run endRun = para.getRuns().get(4); - - // Extract the content between these nodes in the document. Include these markers in the extraction. - ArrayList extractedNodes = extractContent(startRun, endRun, true); - - // Get the node from the list. There should only be one paragraph returned in the list. - Node node = (Node) extractedNodes.get(0); - // Print the text of this node to the console. - System.out.println(node.toString(SaveFormat.TEXT)); - - System.out.println("Content extracted between the runs successfully."); - } - - - /** - * Extracts a range of nodes from a document found between specified markers and returns a copy of those nodes. Content can be extracted - * between inline nodes, block level nodes, and also special nodes such as Comment or Boomarks. Any combination of different marker types can used. - * - * @param startNode The node which defines where to start the extraction from the document. This node can be block or inline level of a body. - * @param endNode The node which defines where to stop the extraction from the document. This node can be block or inline level of body. - * @param isInclusive Should the marker nodes be included. - */ - public static ArrayList extractContent(Node startNode, Node endNode, boolean isInclusive) throws Exception { - // First check that the nodes passed to this method are valid for use. - verifyParameterNodes(startNode, endNode); - - // Create a list to store the extracted nodes. - ArrayList nodes = new ArrayList(); - - // Keep a record of the original nodes passed to this method so we can split marker nodes if needed. - Node originalStartNode = startNode; - Node originalEndNode = endNode; - - // Extract content based on block level nodes (paragraphs and tables). Traverse through parent nodes to find them. - // We will split the content of first and last nodes depending if the marker nodes are inline - while (startNode.getParentNode().getNodeType() != NodeType.BODY) - startNode = startNode.getParentNode(); - - while (endNode.getParentNode().getNodeType() != NodeType.BODY) - endNode = endNode.getParentNode(); - - boolean isExtracting = true; - boolean isStartingNode = true; - boolean isEndingNode; - // The current node we are extracting from the document. - Node currNode = startNode; - - // Begin extracting content. Process all block level nodes and specifically split the first and last nodes when needed so paragraph formatting is retained. - // Method is little more complex than a regular extractor as we need to factor in extracting using inline nodes, fields, bookmarks etc as to make it really useful. - while (isExtracting) { - // Clone the current node and its children to obtain a copy. - CompositeNode cloneNode = (CompositeNode) currNode.deepClone(true); - isEndingNode = currNode.equals(endNode); - - if (isStartingNode || isEndingNode) { - // We need to process each marker separately so pass it off to a separate method instead. - if (isStartingNode) { - processMarker(cloneNode, nodes, originalStartNode, isInclusive, isStartingNode, isEndingNode); - isStartingNode = false; - } - - // Conditional needs to be separate as the block level start and end markers maybe the same node. - if (isEndingNode) { - processMarker(cloneNode, nodes, originalEndNode, isInclusive, isStartingNode, isEndingNode); - isExtracting = false; - } - } else - // Node is not a start or end marker, simply add the copy to the list. - nodes.add(cloneNode); - - // Move to the next node and extract it. If next node is null that means the rest of the content is found in a different section. - if (currNode.getNextSibling() == null && isExtracting) { - // Move to the next section. - Section nextSection = (Section) currNode.getAncestor(NodeType.SECTION).getNextSibling(); - currNode = nextSection.getBody().getFirstChild(); - } else { - // Move to the next node in the body. - currNode = currNode.getNextSibling(); - } - } - - // Return the nodes between the node markers. - return nodes; - } - - /** - * Checks the input parameters are correct and can be used. Throws an exception if there is any problem. - */ - private static void verifyParameterNodes(Node startNode, Node endNode) throws Exception { - // The order in which these checks are done is important. - if (startNode == null) - throw new IllegalArgumentException("Start node cannot be null"); - if (endNode == null) - throw new IllegalArgumentException("End node cannot be null"); - - if (!startNode.getDocument().equals(endNode.getDocument())) - throw new IllegalArgumentException("Start node and end node must belong to the same document"); - - if (startNode.getAncestor(NodeType.BODY) == null || endNode.getAncestor(NodeType.BODY) == null) - throw new IllegalArgumentException("Start node and end node must be a child or descendant of a body"); - - // Check the end node is after the start node in the DOM tree - // First check if they are in different sections, then if they're not check their position in the body of the same section they are in. - Section startSection = (Section) startNode.getAncestor(NodeType.SECTION); - Section endSection = (Section) endNode.getAncestor(NodeType.SECTION); - - int startIndex = startSection.getParentNode().indexOf(startSection); - int endIndex = endSection.getParentNode().indexOf(endSection); - - if (startIndex == endIndex) { - if (startSection.getBody().indexOf(startNode) > endSection.getBody().indexOf(endNode)) - throw new IllegalArgumentException("The end node must be after the start node in the body"); - } else if (startIndex > endIndex) - throw new IllegalArgumentException("The section of end node must be after the section start node"); - } - - /** - * Checks if a node passed is an inline node. - */ - private static boolean isInline(Node node) throws Exception { - // Test if the node is desendant of a Paragraph or Table node and also is not a paragraph or a table a paragraph inside a comment class which is decesant of a pararaph is possible. - return ((node.getAncestor(NodeType.PARAGRAPH) != null || node.getAncestor(NodeType.TABLE) != null) && !(node.getNodeType() == NodeType.PARAGRAPH || node.getNodeType() == NodeType.TABLE)); - } - - /** - * Removes the content before or after the marker in the cloned node depending on the type of marker. - */ - private static void processMarker(CompositeNode cloneNode, ArrayList nodes, Node node, boolean isInclusive, boolean isStartMarker, boolean isEndMarker) throws Exception { - // If we are dealing with a block level node just see if it should be included and add it to the list. - if (!isInline(node)) { - // Don't add the node twice if the markers are the same node - if (!(isStartMarker && isEndMarker)) { - if (isInclusive) - nodes.add(cloneNode); - } - return; - } - - // If a marker is a FieldStart node check if it's to be included or not. - // We assume for simplicity that the FieldStart and FieldEnd appear in the same paragraph. - if (node.getNodeType() == NodeType.FIELD_START) { - // If the marker is a start node and is not be included then skip to the end of the field. - // If the marker is an end node and it is to be included then move to the end field so the field will not be removed. - if ((isStartMarker && !isInclusive) || (!isStartMarker && isInclusive)) { - while (node.getNextSibling() != null && node.getNodeType() != NodeType.FIELD_END) - node = node.getNextSibling(); - - } - } - - // If either marker is part of a comment then to include the comment itself we need to move the pointer forward to the Comment - // node found after the CommentRangeEnd node. - if (node.getNodeType() == NodeType.COMMENT_RANGE_END) { - while (node.getNextSibling() != null && node.getNodeType() != NodeType.COMMENT) - node = node.getNextSibling(); - - } - - // Find the corresponding node in our cloned node by index and return it. - // If the start and end node are the same some child nodes might already have been removed. Subtract the - // difference to get the right index. - int indexDiff = node.getParentNode().getChildNodes().getCount() - cloneNode.getChildNodes().getCount(); - - // Child node count identical. - if (indexDiff == 0) - node = cloneNode.getChildNodes().get(node.getParentNode().indexOf(node)); - else - node = cloneNode.getChildNodes().get(node.getParentNode().indexOf(node) - indexDiff); - - // Remove the nodes up to/from the marker. - boolean isSkip; - boolean isProcessing = true; - boolean isRemoving = isStartMarker; - Node nextNode = cloneNode.getFirstChild(); - - while (isProcessing && nextNode != null) { - Node currentNode = nextNode; - isSkip = false; - - if (currentNode.equals(node)) { - if (isStartMarker) { - isProcessing = false; - if (isInclusive) - isRemoving = false; - } else { - isRemoving = true; - if (isInclusive) - isSkip = true; - } - } - - nextNode = nextNode.getNextSibling(); - if (isRemoving && !isSkip) - currentNode.remove(); - } - - // After processing the composite node may become empty. If it has don't include it. - if (!(isStartMarker && isEndMarker)) { - if (cloneNode.hasChildNodes()) - nodes.add(cloneNode); - } - - } - - public static Document generateDocument(Document srcDoc, ArrayList nodes) throws Exception { - // Create a blank document. - Document dstDoc = new Document(); - // Remove the first paragraph from the empty document. - dstDoc.getFirstSection().getBody().removeAllChildren(); - - // Import each node from the list into the new document. Keep the original formatting of the node. - NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - - for (Node node : (Iterable) nodes) { - Node importNode = importer.importNode(node, true); - dstDoc.getFirstSection().getBody().appendChild(importNode); - } - - // Return the generated document. - return dstDoc; - } - - public static ArrayList paragraphsByStyleName(Document doc, String styleName) throws Exception { - // Create an array to collect paragraphs of the specified style. - ArrayList paragraphsWithStyle = new ArrayList(); - // Get all paragraphs from the document. - NodeCollection paragraphs = doc.getChildNodes(NodeType.PARAGRAPH, true); - // Look through all paragraphs to find those with the specified style. - for (Paragraph paragraph : (Iterable) paragraphs) { - if (paragraph.getParagraphFormat().getStyle().getName().equals(styleName)) - paragraphsWithStyle.add(paragraph); - } - return paragraphsWithStyle; - } - -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentUsingDocumentVisitor.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentUsingDocumentVisitor.java deleted file mode 100644 index aa29fa5f..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentUsingDocumentVisitor.java +++ /dev/null @@ -1,152 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Body; -import com.aspose.words.ControlChar; -import com.aspose.words.Document; -import com.aspose.words.DocumentVisitor; -import com.aspose.words.FieldEnd; -import com.aspose.words.FieldSeparator; -import com.aspose.words.FieldStart; -import com.aspose.words.HeaderFooter; -import com.aspose.words.Paragraph; -import com.aspose.words.Run; -import com.aspose.words.VisitorAction; -import com.aspose.words.examples.Utils; - -public class ExtractContentUsingDocumentVisitor { - - public static void main(String[] args) throws Exception { - - String dataDir = Utils.getSharedDataDir(ExtractContentUsingDocumentVisitor.class) + "ExtractedSelectedContentBetweenNodes/"; - - // Open the document we want to convert. - Document doc = new Document(dataDir + "Visitor.ToText.doc"); - - // Create an object that inherits from the DocumentVisitor class. - MyDocToTxtWriter myConverter = new MyDocToTxtWriter(); - - // This is the well known Visitor pattern. Get the model to accept a visitor. - // The model will iterate through itself by calling the corresponding methods - // on the visitor object (this is called visiting). - // - // Note that every node in the object model has the Accept method so the visiting - // can be executed not only for the whole document, but for any node in the document. - doc.accept(myConverter); - - // Once the visiting is complete, we can retrieve the result of the operation, - // that in this example, has accumulated in the visitor. - System.out.println(myConverter.getText()); - } -} - -/** - * Simple implementation of saving a document in the plain text format. - * Implemented as a Visitor. - */ -class MyDocToTxtWriter extends DocumentVisitor { - - private final StringBuilder mBuilder; - private boolean mIsSkipText; - - public MyDocToTxtWriter() throws Exception { - mIsSkipText = false; - mBuilder = new StringBuilder(); - } - - /** - * Gets the plain text of the document that was accumulated by the visitor. - */ - public String getText() throws Exception { - return mBuilder.toString(); - } - - /** - * Called when a Run node is encountered in the document. - */ - public int visitRun(Run run) throws Exception { - appendText(run.getText()); - - // Let the visitor continue visiting other nodes. - return VisitorAction.CONTINUE; - } - - /** - * Called when a FieldStart node is encountered in the document. - */ - public int visitFieldStart(FieldStart fieldStart) throws Exception { - // In Microsoft Word, a field code (such as "MERGEFIELD FieldName") follows - // after a field start character. We want to skip field codes and output field - // result only, therefore we use a flag to suspend the output while inside a field code. - // - // Note this is a very simplistic implementation and will not work very well - // if you have nested fields in a document. - mIsSkipText = true; - - return VisitorAction.CONTINUE; - } - - /** - * Called when a FieldSeparator node is encountered in the document. - */ - public int visitFieldSeparator(FieldSeparator fieldSeparator) throws Exception { - // Once reached a field separator node, we enable the output because we are - // now entering the field result nodes. - mIsSkipText = false; - - return VisitorAction.CONTINUE; - } - - /** - * Called when a FieldEnd node is encountered in the document. - */ - public int visitFieldEnd(FieldEnd fieldEnd) throws Exception { - // Make sure we enable the output when reached a field end because some fields - // do not have field separator and do not have field result. - mIsSkipText = false; - - return VisitorAction.CONTINUE; - } - - /** - * Called when visiting of a Paragraph node is ended in the document. - */ - public int visitParagraphEnd(Paragraph paragraph) throws Exception { - // When outputting to plain text we output Cr+Lf characters. - appendText(ControlChar.CR_LF); - - return VisitorAction.CONTINUE; - } - - public int visitBodyStart(Body body) throws Exception { - // We can detect beginning and end of all composite nodes such as Section, Body, - // Table, Paragraph etc and provide custom handling for them. - mBuilder.append("*** Body Started ***\r\n"); - - return VisitorAction.CONTINUE; - } - - public int visitBodyEnd(Body body) throws Exception { - mBuilder.append("*** Body Ended ***\r\n"); - return VisitorAction.CONTINUE; - } - - /** - * Called when a HeaderFooter node is encountered in the document. - */ - public int visitHeaderFooterStart(HeaderFooter headerFooter) throws Exception { - // Returning this value from a visitor method causes visiting of this - // node to stop and move on to visiting the next sibling node. - // The net effect in this example is that the text of headers and footers - // is not included in the resulting output. - return VisitorAction.SKIP_THIS_NODE; - } - - /** - * Adds text to the current output. Honours the enabled/disabled output - * flag. - */ - private void appendText(String text) throws Exception { - if (!mIsSkipText) - mBuilder.append(text); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentUsingField.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentUsingField.java deleted file mode 100644 index f1e7383d..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractContentUsingField.java +++ /dev/null @@ -1,260 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.util.ArrayList; - - -public class ExtractContentUsingField { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ExtractContentUsingField.class); - - Document doc = new Document(dataDir + "TestFile.doc"); - - // Use a document builder to retrieve the field start of a merge field. - DocumentBuilder builder = new DocumentBuilder(doc); - - // Pass the first boolean parameter to get the DocumentBuilder to move to the FieldStart of the field. - // We could also get FieldStarts of a field using GetChildNode method as in the other examples. - builder.moveToMergeField("Fullname", false, false); - - // The builder cursor should be positioned at the start of the field. - FieldStart startField = (FieldStart) builder.getCurrentNode(); - Paragraph endPara = (Paragraph) doc.getFirstSection().getChild(NodeType.PARAGRAPH, 5, true); - - // Extract the content between these nodes in the document. Don't include these markers in the extraction. - ArrayList extractedNodes = extractContent(startField, endPara, false); - - // Insert the content into a new separate document and save it to disk. - Document dstDoc = generateDocument(doc, extractedNodes); - dstDoc.save(dataDir + "output.pdf"); - - System.out.println("Content extracted using fields successfully."); - } - - - /** - * Extracts a range of nodes from a document found between specified markers and returns a copy of those nodes. Content can be extracted - * between inline nodes, block level nodes, and also special nodes such as Comment or Boomarks. Any combination of different marker types can used. - * - * @param startNode The node which defines where to start the extraction from the document. This node can be block or inline level of a body. - * @param endNode The node which defines where to stop the extraction from the document. This node can be block or inline level of body. - * @param isInclusive Should the marker nodes be included. - */ - public static ArrayList extractContent(Node startNode, Node endNode, boolean isInclusive) throws Exception { - // First check that the nodes passed to this method are valid for use. - verifyParameterNodes(startNode, endNode); - - // Create a list to store the extracted nodes. - ArrayList nodes = new ArrayList(); - - // Keep a record of the original nodes passed to this method so we can split marker nodes if needed. - Node originalStartNode = startNode; - Node originalEndNode = endNode; - - // Extract content based on block level nodes (paragraphs and tables). Traverse through parent nodes to find them. - // We will split the content of first and last nodes depending if the marker nodes are inline - while (startNode.getParentNode().getNodeType() != NodeType.BODY) - startNode = startNode.getParentNode(); - - while (endNode.getParentNode().getNodeType() != NodeType.BODY) - endNode = endNode.getParentNode(); - - boolean isExtracting = true; - boolean isStartingNode = true; - boolean isEndingNode; - // The current node we are extracting from the document. - Node currNode = startNode; - - // Begin extracting content. Process all block level nodes and specifically split the first and last nodes when needed so paragraph formatting is retained. - // Method is little more complex than a regular extractor as we need to factor in extracting using inline nodes, fields, bookmarks etc as to make it really useful. - while (isExtracting) { - // Clone the current node and its children to obtain a copy. - CompositeNode cloneNode = (CompositeNode) currNode.deepClone(true); - isEndingNode = currNode.equals(endNode); - - if (isStartingNode || isEndingNode) { - // We need to process each marker separately so pass it off to a separate method instead. - if (isStartingNode) { - processMarker(cloneNode, nodes, originalStartNode, isInclusive, isStartingNode, isEndingNode); - isStartingNode = false; - } - - // Conditional needs to be separate as the block level start and end markers maybe the same node. - if (isEndingNode) { - processMarker(cloneNode, nodes, originalEndNode, isInclusive, isStartingNode, isEndingNode); - isExtracting = false; - } - } else - // Node is not a start or end marker, simply add the copy to the list. - nodes.add(cloneNode); - - // Move to the next node and extract it. If next node is null that means the rest of the content is found in a different section. - if (currNode.getNextSibling() == null && isExtracting) { - // Move to the next section. - Section nextSection = (Section) currNode.getAncestor(NodeType.SECTION).getNextSibling(); - currNode = nextSection.getBody().getFirstChild(); - } else { - // Move to the next node in the body. - currNode = currNode.getNextSibling(); - } - } - - // Return the nodes between the node markers. - return nodes; - } - - /** - * Checks the input parameters are correct and can be used. Throws an exception if there is any problem. - */ - private static void verifyParameterNodes(Node startNode, Node endNode) throws Exception { - // The order in which these checks are done is important. - if (startNode == null) - throw new IllegalArgumentException("Start node cannot be null"); - if (endNode == null) - throw new IllegalArgumentException("End node cannot be null"); - - if (!startNode.getDocument().equals(endNode.getDocument())) - throw new IllegalArgumentException("Start node and end node must belong to the same document"); - - if (startNode.getAncestor(NodeType.BODY) == null || endNode.getAncestor(NodeType.BODY) == null) - throw new IllegalArgumentException("Start node and end node must be a child or descendant of a body"); - - // Check the end node is after the start node in the DOM tree - // First check if they are in different sections, then if they're not check their position in the body of the same section they are in. - Section startSection = (Section) startNode.getAncestor(NodeType.SECTION); - Section endSection = (Section) endNode.getAncestor(NodeType.SECTION); - - int startIndex = startSection.getParentNode().indexOf(startSection); - int endIndex = endSection.getParentNode().indexOf(endSection); - - if (startIndex == endIndex) { - if (startSection.getBody().indexOf(startNode) > endSection.getBody().indexOf(endNode)) - throw new IllegalArgumentException("The end node must be after the start node in the body"); - } else if (startIndex > endIndex) - throw new IllegalArgumentException("The section of end node must be after the section start node"); - } - - /** - * Checks if a node passed is an inline node. - */ - private static boolean isInline(Node node) throws Exception { - // Test if the node is desendant of a Paragraph or Table node and also is not a paragraph or a table a paragraph inside a comment class which is decesant of a pararaph is possible. - return ((node.getAncestor(NodeType.PARAGRAPH) != null || node.getAncestor(NodeType.TABLE) != null) && !(node.getNodeType() == NodeType.PARAGRAPH || node.getNodeType() == NodeType.TABLE)); - } - - /** - * Removes the content before or after the marker in the cloned node depending on the type of marker. - */ - private static void processMarker(CompositeNode cloneNode, ArrayList nodes, Node node, boolean isInclusive, boolean isStartMarker, boolean isEndMarker) throws Exception { - // If we are dealing with a block level node just see if it should be included and add it to the list. - if (!isInline(node)) { - // Don't add the node twice if the markers are the same node - if (!(isStartMarker && isEndMarker)) { - if (isInclusive) - nodes.add(cloneNode); - } - return; - } - - // If a marker is a FieldStart node check if it's to be included or not. - // We assume for simplicity that the FieldStart and FieldEnd appear in the same paragraph. - if (node.getNodeType() == NodeType.FIELD_START) { - // If the marker is a start node and is not be included then skip to the end of the field. - // If the marker is an end node and it is to be included then move to the end field so the field will not be removed. - if ((isStartMarker && !isInclusive) || (!isStartMarker && isInclusive)) { - while (node.getNextSibling() != null && node.getNodeType() != NodeType.FIELD_END) - node = node.getNextSibling(); - - } - } - - // If either marker is part of a comment then to include the comment itself we need to move the pointer forward to the Comment - // node found after the CommentRangeEnd node. - if (node.getNodeType() == NodeType.COMMENT_RANGE_END) { - while (node.getNextSibling() != null && node.getNodeType() != NodeType.COMMENT) - node = node.getNextSibling(); - - } - - // Find the corresponding node in our cloned node by index and return it. - // If the start and end node are the same some child nodes might already have been removed. Subtract the - // difference to get the right index. - int indexDiff = node.getParentNode().getChildNodes().getCount() - cloneNode.getChildNodes().getCount(); - - // Child node count identical. - if (indexDiff == 0) - node = cloneNode.getChildNodes().get(node.getParentNode().indexOf(node)); - else - node = cloneNode.getChildNodes().get(node.getParentNode().indexOf(node) - indexDiff); - - // Remove the nodes up to/from the marker. - boolean isSkip; - boolean isProcessing = true; - boolean isRemoving = isStartMarker; - Node nextNode = cloneNode.getFirstChild(); - - while (isProcessing && nextNode != null) { - Node currentNode = nextNode; - isSkip = false; - - if (currentNode.equals(node)) { - if (isStartMarker) { - isProcessing = false; - if (isInclusive) - isRemoving = false; - } else { - isRemoving = true; - if (isInclusive) - isSkip = true; - } - } - - nextNode = nextNode.getNextSibling(); - if (isRemoving && !isSkip) - currentNode.remove(); - } - - // After processing the composite node may become empty. If it has don't include it. - if (!(isStartMarker && isEndMarker)) { - if (cloneNode.hasChildNodes()) - nodes.add(cloneNode); - } - - } - - public static Document generateDocument(Document srcDoc, ArrayList nodes) throws Exception { - // Create a blank document. - Document dstDoc = new Document(); - // Remove the first paragraph from the empty document. - dstDoc.getFirstSection().getBody().removeAllChildren(); - - // Import each node from the list into the new document. Keep the original formatting of the node. - NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - - for (Node node : (Iterable) nodes) { - Node importNode = importer.importNode(node, true); - dstDoc.getFirstSection().getBody().appendChild(importNode); - } - - // Return the generated document. - return dstDoc; - } - - public static ArrayList paragraphsByStyleName(Document doc, String styleName) throws Exception { - // Create an array to collect paragraphs of the specified style. - ArrayList paragraphsWithStyle = new ArrayList(); - // Get all paragraphs from the document. - NodeCollection paragraphs = doc.getChildNodes(NodeType.PARAGRAPH, true); - // Look through all paragraphs to find those with the specified style. - for (Paragraph paragraph : (Iterable) paragraphs) { - if (paragraph.getParagraphFormat().getStyle().getName().equals(styleName)) - paragraphsWithStyle.add(paragraph); - } - return paragraphsWithStyle; - } - -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractTextOnly.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractTextOnly.java deleted file mode 100644 index d4562ada..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ExtractTextOnly.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.SaveFormat; -import com.aspose.words.examples.Utils; - - -public class ExtractTextOnly { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ExtractTextOnly.class); - - Document doc = new Document(); - - // Use a document builder to retrieve the field start of a merge field. - DocumentBuilder builder = new DocumentBuilder(doc); - - builder.insertField("MERGEFIELD Field"); - - // GetText will retrieve all field codes and special characters - System.out.println("GetText() Result: " + doc.getText()); - - // ToString will export the node to the specified format. When converted to text it will not retrieve fields code - // or special characters, but will still contain some natural formatting characters such as paragraph markers etc. - // This is the same as "viewing" the document as if it was opened in a text editor. - System.out.println("ToString() Result: " + doc.toString(SaveFormat.TEXT)); - - } - -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/GenerateACustomBarCodeImage.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/GenerateACustomBarCodeImage.java deleted file mode 100644 index d85a7cfc..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/GenerateACustomBarCodeImage.java +++ /dev/null @@ -1,221 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import java.awt.Color; -import java.awt.image.BufferedImage; - -import com.aspose.barcode.BarCodeBuilder; -import com.aspose.barcode.CodeLocation; -import com.aspose.barcode.Symbology; -import com.aspose.words.BarcodeParameters; -import com.aspose.words.Document; -import com.aspose.words.IBarcodeGenerator; -import com.aspose.words.examples.Utils; - -public class GenerateACustomBarCodeImage { - - private static final String dataDir = Utils.getSharedDataDir(GenerateACustomBarCodeImage.class) + "Barcode/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(dataDir + "Document.docx"); - // Set custom barcode generator - doc.getFieldOptions().setBarcodeGenerator(new CustomBarcodeGenerator()); - doc.save(dataDir + "output.pdf"); - - } - - /** - * Sample of custom barcode generator implementation (with underlying - * Aspose.BarCode module) - */ - static class CustomBarcodeGenerator implements IBarcodeGenerator { - /** - * Converts barcode type from Word to Aspose.BarCode. - * - * @param inputCode - * @return - */ - private long convertBarcodeType(String inputCode) { - if (inputCode == null) { - return Integer.MIN_VALUE; - } - - String type = inputCode.toUpperCase(); - - if (type.equals("QR")) - return Symbology.QR; - if (type.equals("CODE128")) - return Symbology.Code128; - if (type.equals("CODE39")) - return Symbology.Code39Standard; - if (type.equals("EAN8")) - return Symbology.EAN8; - if (type.equals("EAN13")) - return Symbology.EAN13; - if (type.equals("UPCA")) - return Symbology.UPCA; - if (type.equals("UPCE")) - return Symbology.UPCE; - if (type.equals("ITF14")) - return Symbology.ITF14; - - return Integer.MIN_VALUE; - } - - /** - * Converts barcode image height from Word units to Aspose.BarCode units. - * - * @param heightInTwipsString - * @return - */ - private float convertSymbolHeight(String heightInTwipsString) { - // Input value is in 1/1440 inches (twips) - int heightInTwips = Integer.MIN_VALUE; - try { - heightInTwips = Integer.parseInt(heightInTwipsString); - } catch (NumberFormatException e) { - heightInTwips = Integer.MIN_VALUE; - } - - if (heightInTwips == Integer.MIN_VALUE) { - throw new RuntimeException("Error! Incorrect height - " + heightInTwipsString + "."); - } - - // Convert to mm - return (float) (heightInTwips * 25.4 / 1440); - } - - /** - * Converts barcode image color from Word to Aspose.BarCode. - * - * @param inputColor - * @return - */ - private Color convertColor(String inputColor) { - // Input should be from "0x000000" to "0xFFFFFF" - /* - * Integer color = Integer.MIN_VALUE; try { color = - * Integer.parseInt(inputColor.replace("0x", "")); } catch - * (NumberFormatException e) { color = Integer.MIN_VALUE; } - * - * if (color == Integer.MIN_VALUE) { throw new RuntimeException( - * "Error! Incorrect color - " + inputColor + "."); } - */ - - return Color.BLACK; - - // Backword conversion - - //return string.Format("0x{0,6:X6}", mControl.ForeColor.ToArgb() & 0xFFFFFF); - } - - /** - * Converts bar code scaling factor from percents to float. - * - * @param scalingFactor - * @return - */ - private float convertScalingFactor(String scalingFactor) { - boolean isParsed = false; - int percents = Integer.MIN_VALUE; - try { - percents = Integer.parseInt(scalingFactor); - } catch (NumberFormatException e) { - percents = Integer.MIN_VALUE; - } - - if (percents != Integer.MIN_VALUE) { - if (percents >= 10 && percents <= 10000) { - isParsed = true; - } - } - - if (!isParsed) { - throw new RuntimeException("Error! Incorrect scaling factor - " + scalingFactor + "."); - } - - return percents / 100.0f; - } - - /** - * Implementation of the GetBarCodeImage() method for IBarCodeGenerator - * interface. - * - * @param parameters - * @return - */ - public BufferedImage getBarcodeImage(BarcodeParameters parameters) { - if (parameters.getBarcodeType() == null || parameters.getBarcodeValue() == null) { - return null; - } - - BarCodeBuilder builder = new BarCodeBuilder(); - - builder.setSymbologyType(convertBarcodeType(parameters.getBarcodeType())); - if (builder.getSymbologyType() == Integer.MIN_VALUE) { - return null; - } - - builder.setCodeText(parameters.getBarcodeValue()); - - if (builder.getSymbologyType() == Symbology.QR) { - builder.setDisplay2DText(parameters.getBarcodeValue()); - } - - if (parameters.getForegroundColor() != null) { - builder.setForeColor(convertColor(parameters.getForegroundColor())); - } - - if (parameters.getBackgroundColor() != null) { - builder.setBackColor(convertColor(parameters.getBackgroundColor())); - } - - if (parameters.getSymbolHeight() != null) { - builder.setImageHeight(convertSymbolHeight(parameters.getSymbolHeight())); - builder.setAutoSize(false); - } - - builder.setCodeLocation(CodeLocation.None); - - if (parameters.getDisplayText()) { - builder.setCodeLocation(CodeLocation.Below); - } - - builder.getCaptionAbove().setText(""); - - final float scale = 0.4f; // Empiric scaling factor for converting Word barcode to Aspose.BarCode - float xdim = 1.0f; - - if (builder.getSymbologyType() == Symbology.QR) { - builder.setAutoSize(false); - builder.setImageWidth(builder.getImageWidth() * scale); - builder.setImageHeight(builder.getImageWidth()); - xdim = builder.getImageHeight() / 25; - builder.setyDimension(xdim); - builder.setxDimension(xdim); - } - - if (parameters.getScalingFactor() != null) { - float scalingFactor = convertScalingFactor(parameters.getScalingFactor()); - builder.setImageHeight(builder.getImageHeight() * scalingFactor); - - if (builder.getSymbologyType() == Symbology.QR) { - builder.setImageWidth(builder.getImageHeight()); - builder.setxDimension(xdim * scalingFactor); - builder.setyDimension(xdim * scalingFactor); - } - - builder.setAutoSize(false); - } - - return builder.getBarCodeImage(); - } - - /* (non-Javadoc) - * @see com.aspose.words.IBarcodeGenerator#getOldBarcodeImage(com.aspose.words.BarcodeParameters) - */ - @Override - public BufferedImage getOldBarcodeImage(BarcodeParameters arg0) throws Exception { - // TODO Auto-generated method stub - return null; - } - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/GetDocumentVariables.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/GetDocumentVariables.java deleted file mode 100644 index 709a31d5..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/GetDocumentVariables.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; -import com.aspose.words.examples.programming_documents.document.properties.AccessingDocumentProperties; - -public class GetDocumentVariables { - - public static final String dataDir = Utils.getSharedDataDir(AccessingDocumentProperties.class) + "Document/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(dataDir + "Document.doc"); - - for (java.util.Map.Entry entry : doc.getVariables()) { - String name = entry.getKey().toString(); - String value = entry.getValue().toString(); - - // Do something useful. - System.out.println("Name: " + name + ", Value: " + value); - } - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/InsertDocumentIntoAnotherDocument.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/InsertDocumentIntoAnotherDocument.java deleted file mode 100644 index a324f3d3..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/InsertDocumentIntoAnotherDocument.java +++ /dev/null @@ -1,250 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import java.io.ByteArrayInputStream; -import java.util.regex.Pattern; - -import com.aspose.words.Bookmark; -import com.aspose.words.CompositeNode; -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.FieldMergingArgs; -import com.aspose.words.IFieldMergingCallback; -import com.aspose.words.IReplacingCallback; -import com.aspose.words.ImageFieldMergingArgs; -import com.aspose.words.ImportFormatMode; -import com.aspose.words.Node; -import com.aspose.words.NodeImporter; -import com.aspose.words.NodeType; -import com.aspose.words.Paragraph; -import com.aspose.words.ReplaceAction; -import com.aspose.words.ReplacingArgs; -import com.aspose.words.Section; -import com.aspose.words.examples.Utils; - -public class InsertDocumentIntoAnotherDocument { - - public static final String dataDir = Utils.getSharedDataDir(InsertDocumentIntoAnotherDocument.class) + "InsertDocumentIntoAnother/"; - - public static void main(String[] args) throws Exception { - //Insert a Document at a Bookmark - insertADocumentAtABookmark(); - - //Insert a Document During Mail Merge - insertDocumentAtMailMerge(); - - //Insert a Document During Replace - insertDocumentAtReplace(); - } - - public static void insertADocumentAtABookmark() throws Exception { - Document mainDoc = new Document(dataDir + "InsertDocument1.doc"); - Document subDoc = new Document(dataDir + "InsertDocument2.doc"); - - Bookmark bookmark = mainDoc.getRange().getBookmarks().get("insertionPlace"); - insertDocument(bookmark.getBookmarkStart().getParentNode(), subDoc); - - mainDoc.save(dataDir + "InsertDocumentAtBookmark_out.doc"); - } - - public static void insertDocumentAtMailMerge() throws Exception { - // Open the main document. - Document mainDoc = new Document(dataDir + "InsertDocument1.doc"); - - // Add a handler to MergeField event - mainDoc.getMailMerge().setFieldMergingCallback(new InsertDocumentAtMailMergeHandler()); - - // The main document has a merge field in it called "Document_1". - // The corresponding data for this field contains fully qualified path to the document - // that should be inserted to this field. - mainDoc.getMailMerge().execute(new String[] { "Document_1" }, new String[] { dataDir + "InsertDocument2.doc" }); - - mainDoc.save(dataDir + "InsertDocumentAtMailMerge_out.doc"); - } - - public static void insertDocumentAtReplace() throws Exception { - Document mainDoc = new Document(dataDir + "InsertDocument1.doc"); - mainDoc.getRange().replace(Pattern.compile("\\[MY_DOCUMENT\\]"), new InsertDocumentAtReplaceHandler(), false); - mainDoc.save(dataDir + "InsertDocumentAtReplace_out.doc"); - } - - private static class InsertDocumentAtReplaceHandler implements IReplacingCallback { - public int replacing(ReplacingArgs e) throws Exception { - Document subDoc = new Document(dataDir + "InsertDocument2.doc"); - - // Insert a document after the paragraph, containing the match text. - Paragraph para = (Paragraph) e.getMatchNode().getParentNode(); - insertDocument(para, subDoc); - - // Remove the paragraph with the match text. - para.remove(); - - return ReplaceAction.SKIP; - } - } - - private static class InsertDocumentAtMailMergeHandler implements IFieldMergingCallback { - /** - * This handler makes special processing for the "Document_1" field. The - * field value contains the path to load the document. We load the - * document and insert it into the current merge field. - */ - public void fieldMerging(FieldMergingArgs e) throws Exception { - if ("Document_1".equals(e.getDocumentFieldName())) { - // Use document builder to navigate to the merge field with the specified name. - DocumentBuilder builder = new DocumentBuilder(e.getDocument()); - builder.moveToMergeField(e.getDocumentFieldName()); - - // The name of the document to load and insert is stored in the field value. - Document subDoc = new Document((String) e.getFieldValue()); - - // Insert the document. - insertDocument(builder.getCurrentParagraph(), subDoc); - - // The paragraph that contained the merge field might be empty now and you probably want to delete it. - if (!builder.getCurrentParagraph().hasChildNodes()) - builder.getCurrentParagraph().remove(); - - // Indicate to the mail merge engine that we have inserted what we wanted. - e.setText(null); - } - } - - public void imageFieldMerging(ImageFieldMergingArgs args) throws Exception { - // Do nothing. - } - } - - //Load a document from a BLOB database field - private class InsertDocumentAtMailMergeBlobHandler implements IFieldMergingCallback { - /** - * This handler makes special processing for the "Document_1" field. The - * field value contains the path to load the document. We load the - * document and insert it into the current merge field. - */ - public void fieldMerging(FieldMergingArgs e) throws Exception { - if ("Document_1".equals(e.getDocumentFieldName())) { - // Use document builder to navigate to the merge field with the specified name. - DocumentBuilder builder = new DocumentBuilder(e.getDocument()); - builder.moveToMergeField(e.getDocumentFieldName()); - - // Load the document from the blob field. - ByteArrayInputStream inStream = new ByteArrayInputStream((byte[]) e.getFieldValue()); - Document subDoc = new Document(inStream); - inStream.close(); - - // Insert the document. - insertDocument(builder.getCurrentParagraph(), subDoc); - - // The paragraph that contained the merge field might be empty now and you probably want to delete it. - if (!builder.getCurrentParagraph().hasChildNodes()) - builder.getCurrentParagraph().remove(); - - // Indicate to the mail merge engine that we have inserted what we wanted. - e.setText(null); - } - } - - public void imageFieldMerging(ImageFieldMergingArgs args) throws Exception { - // Do nothing. - } - } - - /** - * Inserts content of the external document after the specified node. - * Section breaks and section formatting of the inserted document are - * ignored. - * - * @param insertAfterNode - * Node in the destination document after which the content - * should be inserted. This node should be a block level node - * (paragraph or table). - * @param srcDoc - * The document to insert. - */ - public static void insertDocument(Node insertAfterNode, Document srcDoc) throws Exception { - // Make sure that the node is either a paragraph or table. - if ((insertAfterNode.getNodeType() != NodeType.PARAGRAPH) & (insertAfterNode.getNodeType() != NodeType.TABLE)) - throw new IllegalArgumentException("The destination node should be either a paragraph or table."); - - // We will be inserting into the parent of the destination paragraph. - CompositeNode dstStory = insertAfterNode.getParentNode(); - - // This object will be translating styles and lists during the import. - NodeImporter importer = new NodeImporter(srcDoc, insertAfterNode.getDocument(), ImportFormatMode.KEEP_SOURCE_FORMATTING); - - // Loop through all sections in the source document. - for (Section srcSection : srcDoc.getSections()) { - // Loop through all block level nodes (paragraphs and tables) in the body of the section. - for (Node srcNode : srcSection.getBody()) { - // Let's skip the node if it is a last empty paragraph in a section. - if (srcNode.getNodeType() == (NodeType.PARAGRAPH)) { - Paragraph para = (Paragraph) srcNode; - if (para.isEndOfSection() && !para.hasChildNodes()) - continue; - } - - // This creates a clone of the node, suitable for insertion into the destination document. - Node newNode = importer.importNode(srcNode, true); - - // Insert new node after the reference node. - dstStory.insertAfter(newNode, insertAfterNode); - insertAfterNode = newNode; - } - } - } - - /** - * Inserts content of the external document after the specified node. - * - * @param insertAfterNode - * Node in the destination document after which the content - * should be inserted. This node should be a block level node - * (paragraph or table). - * @param srcDoc - * The document to insert. - */ - public static void insertDocumentWithSectionFormatting(Node insertAfterNode, Document srcDoc) throws Exception { - // Make sure that the node is either a pargraph or table. - if ((insertAfterNode.getNodeType() != NodeType.PARAGRAPH) & (insertAfterNode.getNodeType() != NodeType.TABLE)) - throw new Exception("The destination node should be either a paragraph or table."); - - // Document to insert srcDoc into. - Document dstDoc = (Document) insertAfterNode.getDocument(); - - // To retain section formatting, split the current section into two at the marker node and then import the content from srcDoc as whole sections. - // The section of the node which the insert marker node belongs to - - Section currentSection = (Section) insertAfterNode.getAncestor(NodeType.SECTION); - - // Don't clone the content inside the section, we just want the properties of the section retained. - Section cloneSection = (Section) currentSection.deepClone(false); - - // However make sure the clone section has a body, but no empty first paragraph. - cloneSection.ensureMinimum(); - - cloneSection.getBody().getFirstParagraph().remove(); - - // Insert the cloned section into the document after the original section. - insertAfterNode.getDocument().insertAfter(cloneSection, currentSection); - - // Append all nodes after the marker node to the new section. This will split the content at the section level at - // the marker so the sections from the other document can be inserted directly. - Node currentNode = insertAfterNode.getNextSibling(); - while (currentNode != null) { - Node nextNode = currentNode.getNextSibling(); - cloneSection.getBody().appendChild(currentNode); - currentNode = nextNode; - } - - // This object will be translating styles and lists during the import. - NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.USE_DESTINATION_STYLES); - - // Loop through all sections in the source document. - for (Section srcSection : srcDoc.getSections()) { - Node newNode = importer.importNode(srcSection, true); - // Append each section to the destination document. Start by inserting it after the split section. - dstDoc.insertAfter(newNode, currentSection); - currentSection = (Section) newNode; - } - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ModifyContentControls.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ModifyContentControls.java deleted file mode 100644 index 25577da1..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ModifyContentControls.java +++ /dev/null @@ -1,40 +0,0 @@ - -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - - -public class ModifyContentControls { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ModifyContentControls.class); - - // Open the document. - Document doc = new Document(dataDir + "CheckBoxTypeContentControl.docx"); - - for (Object t : doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG, true)) { - - StructuredDocumentTag std = (StructuredDocumentTag) t; - if (std.getSdtType() == SdtType.PLAIN_TEXT) { - std.removeAllChildren(); - Paragraph para = (Paragraph) std.appendChild(new Paragraph(doc)); - Run run = new Run(doc, "new text goes here"); - para.appendChild(run); - } - if (std.getSdtType() == SdtType.DROP_DOWN_LIST) { - SdtListItem secondItem = std.getListItems().get(2); - std.getListItems().setSelectedValue(secondItem); - } - if (std.getSdtType() == SdtType.PICTURE) { - Shape shape = (Shape) std.getChild(NodeType.SHAPE, 0, true); - if (shape.hasImage()) { - shape.getImageData().setImage(dataDir + "Watermark.png"); - } - } - doc.save(dataDir + "output.doc"); - - } - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ProtectDocument.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ProtectDocument.java deleted file mode 100644 index 2a0b6f80..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/ProtectDocument.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.ProtectionType; -import com.aspose.words.examples.Utils; -import com.aspose.words.examples.programming_documents.document.properties.AccessingDocumentProperties; - -public class ProtectDocument { - - public static final String dataDir = Utils.getSharedDataDir(AccessingDocumentProperties.class) + "Document/"; - - public static void main(String[] args) throws Exception { - // Protecting a Document - protectADocument(); - - // Unprotecting a Document - unprotectADocument(); - - // Getting the Protection Type - getTheProtectionType(); - } - - public static void protectADocument() throws Exception { - Document doc = new Document(); - doc.protect(ProtectionType.ALLOW_ONLY_FORM_FIELDS, "password"); - } - - public static void unprotectADocument() throws Exception { - Document doc = new Document(); - doc.unprotect(); - } - - public static void getTheProtectionType() throws Exception { - Document doc = new Document(dataDir + "Document.doc"); - int protectionType = doc.getProtectionType(); - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/RemovePageAndSectionBreaks.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/RemovePageAndSectionBreaks.java deleted file mode 100644 index fb9e5e5c..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/RemovePageAndSectionBreaks.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -public class RemovePageAndSectionBreaks { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(RemovePageAndSectionBreaks.class); - - // Open the document. - Document doc = new Document(dataDir + "TestFile.doc"); - - // Remove the page and section breaks from the document. - // In Aspose.Words section breaks are represented as separate Section nodes in the document. - // To remove these separate sections the sections are combined. - removePageBreaks(doc); - removeSectionBreaks(doc); - - // Save the document. - doc.save(dataDir + "TestFile_out.doc"); - - System.out.println("Removed breaks from the document successfully."); - } - - /* ExSummary:Removes all page breaks from the document.*/ - private static void removePageBreaks(Document doc) throws Exception { - // Retrieve all paragraphs in the document. - NodeCollection paragraphs = doc.getChildNodes(NodeType.PARAGRAPH, true); - - // Iterate through all paragraphs - for (Paragraph para : (Iterable) paragraphs) { - // If the paragraph has a page break before set then clear it. - if (para.getParagraphFormat().getPageBreakBefore()) - para.getParagraphFormat().setPageBreakBefore(false); - - // Check all runs in the paragraph for page breaks and remove them. - for (Run run : para.getRuns()) { - if (run.getText().contains(ControlChar.PAGE_BREAK)) - run.setText(run.getText().replace(ControlChar.PAGE_BREAK, "")); - } - } - } - - /* ExSummary:Combines all sections in the document into one.*/ - private static void removeSectionBreaks(Document doc) throws Exception { - // Loop through all sections starting from the section that precedes the last one - // and moving to the first section. - for (int i = doc.getSections().getCount() - 2; i >= 0; i--) { - // Copy the content of the current section to the beginning of the last section. - doc.getLastSection().prependContent(doc.getSections().get(i)); - // Remove the copied section. - doc.getSections().get(i).remove(); - } - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/RichTextBoxContentControl.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/RichTextBoxContentControl.java deleted file mode 100644 index dfd13ced..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/RichTextBoxContentControl.java +++ /dev/null @@ -1,32 +0,0 @@ - -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.awt.*; - - -public class RichTextBoxContentControl { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(RichTextBoxContentControl.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - StructuredDocumentTag sdtRichText =new StructuredDocumentTag(doc, SdtType.RICH_TEXT, MarkupLevel.BLOCK); - - Paragraph para = new Paragraph(doc); - Run run = new Run(doc); - run.setText("Hello World"); - run.getFont().setColor(Color.MAGENTA); - para.getRuns().add(run); - sdtRichText.getChildNodes().add(para); - doc.getFirstSection().getBody().appendChild(sdtRichText); - - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/SetCurrentStateOfCheckBox.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/SetCurrentStateOfCheckBox.java deleted file mode 100644 index 3287f24c..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/SetCurrentStateOfCheckBox.java +++ /dev/null @@ -1,26 +0,0 @@ - -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - - -public class SetCurrentStateOfCheckBox { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(SetCurrentStateOfCheckBox.class); - - // Open the document. - Document doc = new Document(dataDir + "CheckBoxTypeContentControl.docx"); - DocumentBuilder builder = new DocumentBuilder(doc); - StructuredDocumentTag SdtCheckBox = (StructuredDocumentTag)doc.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true); - - //StructuredDocumentTag.Checked property gets/sets current state of the Checkbox SDT - if (SdtCheckBox.getSdtType() == SdtType.CHECKBOX) - SdtCheckBox.setChecked(true); - - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/SetViewOptions.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/SetViewOptions.java deleted file mode 100644 index 575ee40c..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/SetViewOptions.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.ViewType; -import com.aspose.words.examples.Utils; -import com.aspose.words.examples.programming_documents.document.properties.AccessingDocumentProperties; - -public class SetViewOptions { - - public static final String dataDir = Utils.getSharedDataDir(AccessingDocumentProperties.class) + "Document/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(dataDir + "Document.doc"); - doc.getViewOptions().setViewType(ViewType.PAGE_LAYOUT); - doc.getViewOptions().setZoomPercent(50); - doc.save(dataDir + "Document.SetZoom_out.doc"); - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/TrackChanges.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/TrackChanges.java deleted file mode 100644 index 8db89b96..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/TrackChanges.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; -import com.aspose.words.examples.programming_documents.document.properties.AccessingDocumentProperties; - -public class TrackChanges { - - public static final String dataDir = Utils.getSharedDataDir(AccessingDocumentProperties.class) + "Document/"; - - public static void main(String[] args) throws Exception { - - Document doc = new Document(dataDir + "Document.doc"); - - // Start tracking and make some revisions. - doc.startTrackRevisions("Author"); - doc.getFirstSection().getBody().appendParagraph("Hello world!"); - - // Revisions will now show up as normal text in the output document. - doc.acceptAllRevisions(); - - doc.save(dataDir + "Document.AcceptedRevisions_out_.doc"); - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/UseControlCharacters.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/UseControlCharacters.java deleted file mode 100644 index 328051da..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/UseControlCharacters.java +++ /dev/null @@ -1,27 +0,0 @@ - -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - - -public class UseControlCharacters { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(UseControlCharacters.class); - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - builder.write("This is First Line"); - builder.write(ControlChar.CR); - - builder.write("This is Second Line"); - builder.write(ControlChar.CR_LF); - - doc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/WriteAndFont.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/WriteAndFont.java deleted file mode 100644 index 805d7caa..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/WriteAndFont.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.aspose.words.examples.programming_documents.document; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.Font; -import com.aspose.words.Underline; - -import java.awt.*; - -public class WriteAndFont { - public static void main(String[] args) throws Exception { - - // Open the document. - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - Font font = builder.getFont(); - font.setSize(16); - font.setColor(Color.blue); - font.setBold(true); - font.setName("Algerian"); - font.setUnderline(Underline.DOUBLE); - builder.write("aspose......... aspose_words_java"); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/properties/AccessingDocumentProperties.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/properties/AccessingDocumentProperties.java deleted file mode 100644 index 232f2868..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/properties/AccessingDocumentProperties.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.aspose.words.examples.programming_documents.document.properties; - -import com.aspose.words.Document; -import com.aspose.words.DocumentProperty; -import com.aspose.words.examples.Utils; - -public class AccessingDocumentProperties { - - public static final String dataDir = Utils.getSharedDataDir(AccessingDocumentProperties.class) + "Document/"; - - public static void main(String[] args) throws Exception { - String fileName = dataDir + "Properties.doc"; - Document doc = new Document(fileName); - - System.out.println("1. Document name: " + fileName); - - System.out.println("2. Built-in Properties"); - for (DocumentProperty prop : doc.getBuiltInDocumentProperties()) - System.out.println(prop.getName() + " : " + prop.getValue()); - - System.out.println("3. Custom Properties"); - for (DocumentProperty prop : doc.getCustomDocumentProperties()) - System.out.println(prop.getName() + " : " + prop.getValue()); - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/properties/AddOrRemoveDocumentProperties.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/properties/AddOrRemoveDocumentProperties.java deleted file mode 100644 index a3f82097..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/document/properties/AddOrRemoveDocumentProperties.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.aspose.words.examples.programming_documents.document.properties; - -import java.util.Date; - -import com.aspose.words.CustomDocumentProperties; -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - -public class AddOrRemoveDocumentProperties { - - public static final String dataDir = Utils.getSharedDataDir(AccessingDocumentProperties.class) + "Document/"; - - public static void main(String[] args) throws Exception { - // Checks if a custom property with a given name exists in a document and adds few more custom document properties - addDocumentProperties(); - - // Remove a custom document property - removeDocumentProperty(); - } - - public static void addDocumentProperties() throws Exception { - Document doc = new Document(dataDir + "Properties.doc"); - - CustomDocumentProperties props = doc.getCustomDocumentProperties(); - - if (props.get("Authorized") == null) { - props.add("Authorized", true); - props.add("Authorized By", "John Smith"); - props.add("Authorized Date", new Date()); - props.add("Authorized Revision", doc.getBuiltInDocumentProperties().getRevisionNumber()); - props.add("Authorized Amount", 123.45); - } - } - - public static void removeDocumentProperty() throws Exception { - Document doc = new Document(dataDir + "Properties.doc"); - doc.getCustomDocumentProperties().remove("Authorized Date"); - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/ChangeFieldUpdateCultureSource.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/ChangeFieldUpdateCultureSource.java deleted file mode 100644 index c26191c6..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/ChangeFieldUpdateCultureSource.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2001-2014 Aspose Pty Ltd. All Rights Reserved. - * - * This file is part of Aspose.Words. The source code in this file - * is only intended as a supplement to the documentation, and is provided - * "as is", without warranty of any kind, either expressed or implied. - */ - -package com.aspose.words.examples.programming_documents.fields; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -public class ChangeFieldUpdateCultureSource -{ - public static void main(String[] args) throws Exception - { - //TODO - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ChangeFieldUpdateCultureSource.class); - - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - - builder.getFont().setLocaleId(1031); - builder.insertField("MERGEFIELD Date1 \\@ \"dddd, d MMMM yyyy\""); - builder.write(" - "); - builder.insertField("MERGEFIELD Date2 \\@ \"dddd, d MMMM yyyy\""); - // Shows how to specify where the culture used for date formatting during field update and mail merge is chosen from. - // Set the culture used during field update to the culture used by the field. - doc.getFieldOptions().setFieldUpdateCultureSource(FieldUpdateCultureSource.FIELD_CODE); -//DateTime object issue - // doc.getMailMerge().ex - // doc.getMailMerge().execute(new String[] { "Date2" }, new Object[] { new (2011, 1, 01) }); - // doc.MailMerge.Execute(new string[] { "Date2" }, new object[] { new DateTime(2011, 1, 01) }); - - doc.save(dataDir + "InsertNestedFields Out.docx"); - - - System.out.println("Nested fields inserted into the document successfully."); - } -} - - - - diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/ConvertFieldsInBody.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/ConvertFieldsInBody.java deleted file mode 100644 index 1b5cd8d3..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/ConvertFieldsInBody.java +++ /dev/null @@ -1,124 +0,0 @@ -package com.aspose.words.examples.programming_documents.fields; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.util.ArrayList; - - -public class ConvertFieldsInBody { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ConvertFieldsInBody.class); - - Document doc = new Document(dataDir + "TestFile.doc"); - - // Pass the appropriate parameters to convert PAGE fields encountered to static text only in the body of the first section. - FieldsHelper.convertFieldsToStaticText(doc.getFirstSection().getBody(), FieldType.FIELD_PAGE); - - // Save the document with fields transformed to disk. - doc.save(dataDir + "output.doc"); - - - System.out.println("Converted fields in the document body with text successfully."); - } - - private static class FieldsHelper extends DocumentVisitor { - private int mFieldDepth = 0; - private ArrayList mNodesToSkip = new ArrayList(); - private int mTargetFieldType; - - private FieldsHelper(int targetFieldType) { - mTargetFieldType = targetFieldType; - } - - public static void convertFieldsToStaticText(CompositeNode compositeNode, int targetFieldType) throws Exception { - String originalNodeText = compositeNode.toString(SaveFormat.TEXT); //ExSkip - FieldsHelper helper = new FieldsHelper(targetFieldType); - compositeNode.accept(helper); - - assert (originalNodeText.equals(compositeNode.toString(SaveFormat.TEXT))) : "Error: Text of the node converted differs from the original"; //ExSkip - for (Node node : (Iterable) compositeNode.getChildNodes(NodeType.ANY, true)) //ExSkip - assert (!(node instanceof FieldChar && ((FieldChar) node).getFieldType() == targetFieldType)) : "Error: A field node that should be removed still remains."; //ExSkip - } - - public int visitFieldStart(FieldStart fieldStart) { - // We must keep track of the starts and ends of fields incase of any nested fields. - if (fieldStart.getFieldType() == mTargetFieldType) { - mFieldDepth++; - fieldStart.remove(); - } else { - // This removes the field start if it's inside a field that is being converted. - CheckDepthAndRemoveNode(fieldStart); - } - - return VisitorAction.CONTINUE; - } - - public int visitFieldSeparator(FieldSeparator fieldSeparator) { - // When visiting a field separator we should decrease the depth level. - if (fieldSeparator.getFieldType() == mTargetFieldType) { - mFieldDepth--; - fieldSeparator.remove(); - } else { - // This removes the field separator if it's inside a field that is being converted. - CheckDepthAndRemoveNode(fieldSeparator); - } - - return VisitorAction.CONTINUE; - } - - public int visitFieldEnd(FieldEnd fieldEnd) { - if (fieldEnd.getFieldType() == mTargetFieldType) - fieldEnd.remove(); - else - CheckDepthAndRemoveNode(fieldEnd); // This removes the field end if it's inside a field that is being converted. - - return VisitorAction.CONTINUE; - } - - public int visitRun(Run run) { - // Remove the run if it is between the FieldStart and FieldSeparator of the field being converted. - CheckDepthAndRemoveNode(run); - - return VisitorAction.CONTINUE; - } - - public int visitParagraphEnd(Paragraph paragraph) { - if (mFieldDepth > 0) { - // The field code that is being converted continues onto another paragraph. We - // need to copy the remaining content from this paragraph onto the next paragraph. - Node nextParagraph = paragraph.getNextSibling(); - - // Skip ahead to the next available paragraph. - while (nextParagraph != null && nextParagraph.getNodeType() != NodeType.PARAGRAPH) - nextParagraph = nextParagraph.getNextSibling(); - - // Copy all of the nodes over. Keep a list of these nodes so we know not to remove them. - while (paragraph.hasChildNodes()) { - mNodesToSkip.add(paragraph.getLastChild()); - ((Paragraph) nextParagraph).prependChild(paragraph.getLastChild()); - } - - paragraph.remove(); - } - - return VisitorAction.CONTINUE; - } - - public int visitTableStart(Table table) { - CheckDepthAndRemoveNode(table); - - return VisitorAction.CONTINUE; - } - - /** - * Checks whether the node is inside a field or should be skipped and then removes it if necessary. - */ - private void CheckDepthAndRemoveNode(Node node) { - if (mFieldDepth > 0 && !mNodesToSkip.contains(node)) - node.remove(); - } - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/ConvertFieldsInDocument.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/ConvertFieldsInDocument.java deleted file mode 100644 index e1709386..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/ConvertFieldsInDocument.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.aspose.words.examples.programming_documents.fields; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.util.ArrayList; - - -public class ConvertFieldsInDocument { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ConvertFieldsInDocument.class); - - Document doc = new Document(dataDir + "TestFile.doc"); - - // Pass the appropriate parameters to convert all IF fields encountered in the document (including headers and footers) to static text. - FieldsHelper.convertFieldsToStaticText(doc, FieldType.FIELD_IF); - - // Save the document with fields transformed to disk. - doc.save(dataDir + "output.doc"); - - - System.out.println("Converted fields in the document with text successfully."); - } - - private static class FieldsHelper extends DocumentVisitor { - private int mFieldDepth = 0; - private ArrayList mNodesToSkip = new ArrayList(); - private int mTargetFieldType; - - private FieldsHelper(int targetFieldType) { - mTargetFieldType = targetFieldType; - } - - /** - * Converts any fields of the specified type found in the descendants of the node into static text. - * - * @param compositeNode The node in which all descendants of the specified FieldType will be converted to static text. - * @param targetFieldType The FieldType of the field to convert to static text. - */ - public static void convertFieldsToStaticText(CompositeNode compositeNode, int targetFieldType) throws Exception { - String originalNodeText = compositeNode.toString(SaveFormat.TEXT); //ExSkip - FieldsHelper helper = new FieldsHelper(targetFieldType); - compositeNode.accept(helper); - - assert (originalNodeText.equals(compositeNode.toString(SaveFormat.TEXT))) : "Error: Text of the node converted differs from the original"; //ExSkip - for (Node node : (Iterable) compositeNode.getChildNodes(NodeType.ANY, true)) //ExSkip - assert (!(node instanceof FieldChar && ((FieldChar) node).getFieldType() == targetFieldType)) : "Error: A field node that should be removed still remains."; //ExSkip - } - - public int visitFieldStart(FieldStart fieldStart) { - // We must keep track of the starts and ends of fields incase of any nested fields. - if (fieldStart.getFieldType() == mTargetFieldType) { - mFieldDepth++; - fieldStart.remove(); - } else { - // This removes the field start if it's inside a field that is being converted. - CheckDepthAndRemoveNode(fieldStart); - } - - return VisitorAction.CONTINUE; - } - - public int visitFieldSeparator(FieldSeparator fieldSeparator) { - // When visiting a field separator we should decrease the depth level. - if (fieldSeparator.getFieldType() == mTargetFieldType) { - mFieldDepth--; - fieldSeparator.remove(); - } else { - // This removes the field separator if it's inside a field that is being converted. - CheckDepthAndRemoveNode(fieldSeparator); - } - - return VisitorAction.CONTINUE; - } - - public int visitFieldEnd(FieldEnd fieldEnd) { - if (fieldEnd.getFieldType() == mTargetFieldType) - fieldEnd.remove(); - else - CheckDepthAndRemoveNode(fieldEnd); // This removes the field end if it's inside a field that is being converted. - - return VisitorAction.CONTINUE; - } - - public int visitRun(Run run) { - // Remove the run if it is between the FieldStart and FieldSeparator of the field being converted. - CheckDepthAndRemoveNode(run); - - return VisitorAction.CONTINUE; - } - - public int visitParagraphEnd(Paragraph paragraph) { - if (mFieldDepth > 0) { - // The field code that is being converted continues onto another paragraph. We - // need to copy the remaining content from this paragraph onto the next paragraph. - Node nextParagraph = paragraph.getNextSibling(); - - // Skip ahead to the next available paragraph. - while (nextParagraph != null && nextParagraph.getNodeType() != NodeType.PARAGRAPH) - nextParagraph = nextParagraph.getNextSibling(); - - // Copy all of the nodes over. Keep a list of these nodes so we know not to remove them. - while (paragraph.hasChildNodes()) { - mNodesToSkip.add(paragraph.getLastChild()); - ((Paragraph) nextParagraph).prependChild(paragraph.getLastChild()); - } - - paragraph.remove(); - } - - return VisitorAction.CONTINUE; - } - - public int visitTableStart(Table table) { - CheckDepthAndRemoveNode(table); - - return VisitorAction.CONTINUE; - } - - /** - * Checks whether the node is inside a field or should be skipped and then removes it if necessary. - */ - private void CheckDepthAndRemoveNode(Node node) { - if (mFieldDepth > 0 && !mNodesToSkip.contains(node)) - node.remove(); - } - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/ConvertFieldsInParagraph.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/ConvertFieldsInParagraph.java deleted file mode 100644 index 6e3f5dc4..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/ConvertFieldsInParagraph.java +++ /dev/null @@ -1,125 +0,0 @@ -package com.aspose.words.examples.programming_documents.fields; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.util.ArrayList; - - -public class ConvertFieldsInParagraph { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ConvertFieldsInParagraph.class); - - Document doc = new Document(dataDir + "TestFile.doc"); - - // Pass the appropriate parameters to convert all IF fields to static text that are encountered only in the last - // paragraph of the document. - FieldsHelper.convertFieldsToStaticText(doc.getFirstSection().getBody().getLastParagraph(), FieldType.FIELD_IF); - - // Save the document with fields transformed to disk. - doc.save(dataDir + "output.doc"); - - - System.out.println("Converted fields in the paragraph with text successfully."); - } - - private static class FieldsHelper extends DocumentVisitor { - private int mFieldDepth = 0; - private ArrayList mNodesToSkip = new ArrayList(); - private int mTargetFieldType; - - private FieldsHelper(int targetFieldType) { - mTargetFieldType = targetFieldType; - } - - public static void convertFieldsToStaticText(CompositeNode compositeNode, int targetFieldType) throws Exception { - String originalNodeText = compositeNode.toString(SaveFormat.TEXT); //ExSkip - FieldsHelper helper = new FieldsHelper(targetFieldType); - compositeNode.accept(helper); - - assert (originalNodeText.equals(compositeNode.toString(SaveFormat.TEXT))) : "Error: Text of the node converted differs from the original"; //ExSkip - for (Node node : (Iterable) compositeNode.getChildNodes(NodeType.ANY, true)) //ExSkip - assert (!(node instanceof FieldChar && ((FieldChar) node).getFieldType() == targetFieldType)) : "Error: A field node that should be removed still remains."; //ExSkip - } - - public int visitFieldStart(FieldStart fieldStart) { - // We must keep track of the starts and ends of fields incase of any nested fields. - if (fieldStart.getFieldType() == mTargetFieldType) { - mFieldDepth++; - fieldStart.remove(); - } else { - // This removes the field start if it's inside a field that is being converted. - CheckDepthAndRemoveNode(fieldStart); - } - - return VisitorAction.CONTINUE; - } - - public int visitFieldSeparator(FieldSeparator fieldSeparator) { - // When visiting a field separator we should decrease the depth level. - if (fieldSeparator.getFieldType() == mTargetFieldType) { - mFieldDepth--; - fieldSeparator.remove(); - } else { - // This removes the field separator if it's inside a field that is being converted. - CheckDepthAndRemoveNode(fieldSeparator); - } - - return VisitorAction.CONTINUE; - } - - public int visitFieldEnd(FieldEnd fieldEnd) { - if (fieldEnd.getFieldType() == mTargetFieldType) - fieldEnd.remove(); - else - CheckDepthAndRemoveNode(fieldEnd); // This removes the field end if it's inside a field that is being converted. - - return VisitorAction.CONTINUE; - } - - public int visitRun(Run run) { - // Remove the run if it is between the FieldStart and FieldSeparator of the field being converted. - CheckDepthAndRemoveNode(run); - - return VisitorAction.CONTINUE; - } - - public int visitParagraphEnd(Paragraph paragraph) { - if (mFieldDepth > 0) { - // The field code that is being converted continues onto another paragraph. We - // need to copy the remaining content from this paragraph onto the next paragraph. - Node nextParagraph = paragraph.getNextSibling(); - - // Skip ahead to the next available paragraph. - while (nextParagraph != null && nextParagraph.getNodeType() != NodeType.PARAGRAPH) - nextParagraph = nextParagraph.getNextSibling(); - - // Copy all of the nodes over. Keep a list of these nodes so we know not to remove them. - while (paragraph.hasChildNodes()) { - mNodesToSkip.add(paragraph.getLastChild()); - ((Paragraph) nextParagraph).prependChild(paragraph.getLastChild()); - } - - paragraph.remove(); - } - - return VisitorAction.CONTINUE; - } - - public int visitTableStart(Table table) { - CheckDepthAndRemoveNode(table); - - return VisitorAction.CONTINUE; - } - - /** - * Checks whether the node is inside a field or should be skipped and then removes it if necessary. - */ - private void CheckDepthAndRemoveNode(Node node) { - if (mFieldDepth > 0 && !mNodesToSkip.contains(node)) - node.remove(); - } - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/FieldHelper.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/FieldHelper.java deleted file mode 100644 index ddf52afe..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/FieldHelper.java +++ /dev/null @@ -1,152 +0,0 @@ - - -package com.aspose.words.examples.programming_documents.fields; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.util.ArrayList; - - -public class FieldHelper -{ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(FieldHelper.class); - - Document doc = new Document(dataDir + "TestFile.doc"); - - // Pass the appropriate parameters to convert PAGE fields encountered to static text only in the body of the first section. - FieldsHelper.convertFieldsToStaticText(doc.getFirstSection().getBody(), FieldType.FIELD_PAGE); - - // Save the document with fields transformed to disk. - doc.save(dataDir + "TestFileBody Out.doc"); - - System.out.println("Converted fields in the document body with text successfully."); - } - - - private static class FieldsHelper extends DocumentVisitor - { - /** - * Converts any fields of the specified type found in the descendants of the node into static text. - * - * @param compositeNode The node in which all descendants of the specified FieldType will be converted to static text. - * @param targetFieldType The FieldType of the field to convert to static text. - */ - public static void convertFieldsToStaticText(CompositeNode compositeNode, int targetFieldType) throws Exception - { - String originalNodeText = compositeNode.toString(SaveFormat.TEXT); //ExSkip - FieldsHelper helper = new FieldsHelper(targetFieldType); - compositeNode.accept(helper); - - assert (originalNodeText.equals(compositeNode.toString(SaveFormat.TEXT))) : "Error: Text of the node converted differs from the original"; //ExSkip - for (Node node : (Iterable)compositeNode.getChildNodes(NodeType.ANY, true)) //ExSkip - assert (!(node instanceof FieldChar && ((FieldChar)node).getFieldType() == targetFieldType)) : "Error: A field node that should be removed still remains."; //ExSkip - } - - private FieldsHelper(int targetFieldType) - { - mTargetFieldType = targetFieldType; - } - - public int visitFieldStart(FieldStart fieldStart) - { - // We must keep track of the starts and ends of fields incase of any nested fields. - if (fieldStart.getFieldType() == mTargetFieldType) - { - mFieldDepth++; - fieldStart.remove(); - } - else - { - // This removes the field start if it's inside a field that is being converted. - CheckDepthAndRemoveNode(fieldStart); - } - - return VisitorAction.CONTINUE; - } - - public int visitFieldSeparator(FieldSeparator fieldSeparator) - { - // When visiting a field separator we should decrease the depth level. - if (fieldSeparator.getFieldType() == mTargetFieldType) - { - mFieldDepth--; - fieldSeparator.remove(); - } - else - { - // This removes the field separator if it's inside a field that is being converted. - CheckDepthAndRemoveNode(fieldSeparator); - } - - return VisitorAction.CONTINUE; - } - - public int visitFieldEnd(FieldEnd fieldEnd) - { - if (fieldEnd.getFieldType() == mTargetFieldType) - fieldEnd.remove(); - else - CheckDepthAndRemoveNode(fieldEnd); // This removes the field end if it's inside a field that is being converted. - - return VisitorAction.CONTINUE; - } - - public int visitRun(Run run) - { - // Remove the run if it is between the FieldStart and FieldSeparator of the field being converted. - CheckDepthAndRemoveNode(run); - - return VisitorAction.CONTINUE; - } - - public int visitParagraphEnd(Paragraph paragraph) - { - if (mFieldDepth > 0) - { - // The field code that is being converted continues onto another paragraph. We - // need to copy the remaining content from this paragraph onto the next paragraph. - Node nextParagraph = paragraph.getNextSibling(); - - // Skip ahead to the next available paragraph. - while (nextParagraph != null && nextParagraph.getNodeType() != NodeType.PARAGRAPH) - nextParagraph = nextParagraph.getNextSibling(); - - // Copy all of the nodes over. Keep a list of these nodes so we know not to remove them. - while (paragraph.hasChildNodes()) - { - mNodesToSkip.add(paragraph.getLastChild()); - ((Paragraph)nextParagraph).prependChild(paragraph.getLastChild()); - } - - paragraph.remove(); - } - - return VisitorAction.CONTINUE; - } - - public int visitTableStart(Table table) - { - CheckDepthAndRemoveNode(table); - - return VisitorAction.CONTINUE; - } - - /** - * Checks whether the node is inside a field or should be skipped and then removes it if necessary. - */ - private void CheckDepthAndRemoveNode(Node node) - { - if (mFieldDepth > 0 && !mNodesToSkip.contains(node)) - node.remove(); - } - - private int mFieldDepth = 0; - private ArrayList mNodesToSkip = new ArrayList(); - private int mTargetFieldType; - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/FormFieldsGetByName.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/FormFieldsGetByName.java deleted file mode 100644 index 73e937a3..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/FormFieldsGetByName.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.aspose.words.examples.programming_documents.fields; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.FormField; -import com.aspose.words.FormFieldCollection; -import com.aspose.words.examples.Utils; - -public class FormFieldsGetByName { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(FormFieldsGetByName.class); - - Document doc = new Document(dataDir + "FormFields.doc"); - - DocumentBuilder builder = new DocumentBuilder(doc); - // FormFieldCollection formFields = doc.getRange().getFormFields(); - FormFieldCollection documentFormFields = doc.getRange().getFormFields(); - - FormField formField1 = documentFormFields.get(3); - FormField formField2 = documentFormFields.get("Text2"); - System.out.println("Name: " + formField2.getName()); - doc.save(dataDir + "output.docx"); - - } -} - - - - diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/FormFieldsGetFormFieldsCollection.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/FormFieldsGetFormFieldsCollection.java deleted file mode 100644 index 14e7afed..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/FormFieldsGetFormFieldsCollection.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.aspose.words.examples.programming_documents.fields; - -import com.aspose.words.Document; -import com.aspose.words.FormFieldCollection; -import com.aspose.words.examples.Utils; - -public class FormFieldsGetFormFieldsCollection { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(FormFieldsGetFormFieldsCollection.class); - - Document doc = new Document(dataDir + "FormFields.doc"); - FormFieldCollection formFields = doc.getRange().getFormFields(); - doc.save(dataDir + "output.docx"); - - } -} - - - - diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/FormFieldsWorkWithProperties.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/FormFieldsWorkWithProperties.java deleted file mode 100644 index 0bfc74c6..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/FormFieldsWorkWithProperties.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.aspose.words.examples.programming_documents.fields; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -public class FormFieldsWorkWithProperties { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(FormFieldsWorkWithProperties.class); - - Document doc = new Document(dataDir + "FormFields.doc"); - - DocumentBuilder builder = new DocumentBuilder(doc); - FormFieldCollection documentFormFields = doc.getRange().getFormFields(); - - FormField formField = doc.getRange().getFormFields().get(3); - if (formField.getType() == FieldType.FIELD_FORM_TEXT_INPUT) - - formField.setResult("Field Name :" + formField.getName()); - doc.save(dataDir + "output.docx"); - - } -} - - - - diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/GetFieldNames.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/GetFieldNames.java deleted file mode 100644 index e1d5b486..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/GetFieldNames.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.aspose.words.examples.programming_documents.fields; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - -public class GetFieldNames { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(GetFieldNames.class); - - Document doc = new Document(dataDir + "Rendering.doc"); - String[] fieldNames = doc.getMailMerge().getFieldNames(); - System.out.println("\nDocument have " + fieldNames.length + " fields."); - for (String name : fieldNames) { - System.out.println(name); - } - - - } -} - - - - diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/InsertAuthorField.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/InsertAuthorField.java deleted file mode 100644 index 06ffc580..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/InsertAuthorField.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.aspose.words.examples.programming_documents.fields; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -public class InsertAuthorField { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(InsertAuthorField.class); - - Document doc = new Document(dataDir + "in.doc"); - - // Get paragraph you want to append this merge field to - Paragraph para = (Paragraph) doc.getChildNodes(NodeType.PARAGRAPH, true).get(1); - - // We want to insert an AUTHOR field like this: - // { AUTHOR Test1 } - - // Create instance of FieldAuthor class and lets build the above field code - FieldAuthor field = (FieldAuthor) para.appendField(FieldType.FIELD_AUTHOR, false); - - // { AUTHOR Test1 } - field.setAuthorName("Test1"); - - // Finally update this AUTHOR field - field.update(); - doc.save(dataDir + "output.docx"); - - - } -} - - - - diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/InsertField.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/InsertField.java deleted file mode 100644 index 4c6bcc58..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/InsertField.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.aspose.words.examples.programming_documents.fields; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; - -public class InsertField { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(InsertField.class); - - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - builder.insertField("MERGEFIELD MyFieldName \\* MERGEFORMAT"); - - doc.save(dataDir + "output.docx"); - - - } -} - - - - diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/InsertFormFields.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/InsertFormFields.java deleted file mode 100644 index 344d825b..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/InsertFormFields.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.aspose.words.examples.programming_documents.fields; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; - -public class InsertFormFields { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(InsertFormFields.class); - - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - String[] items = {"One", "Two", "Three"}; - builder.insertComboBox("DropDown", items, 0); - doc.save(dataDir + "output.docx"); - - - } -} - - - - diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/InsertMailMergeAddressBlockFieldUsingDOM.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/InsertMailMergeAddressBlockFieldUsingDOM.java deleted file mode 100644 index 111bb4f3..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/InsertMailMergeAddressBlockFieldUsingDOM.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.aspose.words.examples.programming_documents.fields; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -public class InsertMailMergeAddressBlockFieldUsingDOM { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(InsertMailMergeAddressBlockFieldUsingDOM.class); - - Document doc = new Document(dataDir + "in.doc"); - DocumentBuilder builder = new DocumentBuilder(doc); - - // Get paragraph you want to append this merge field to - Paragraph para = (Paragraph) doc.getChildNodes(NodeType.PARAGRAPH, true).get(1); - - // Move cursor to this paragraph - builder.moveTo(para); - - // We want to insert a mail merge address block like this: - // { ADDRESSBLOCK \\c 1 \\d \\e Test2 \\f Test3 \\l \"Test 4\" } - - // Create instance of FieldAddressBlock class and lets build the above field code - FieldAddressBlock field = (FieldAddressBlock) builder.insertField(FieldType.FIELD_ADDRESS_BLOCK, false); - - // { ADDRESSBLOCK \\c 1" } - field.setIncludeCountryOrRegionName("1"); - - // { ADDRESSBLOCK \\c 1 \\d" } - field.setFormatAddressOnCountryOrRegion(true); - - // { ADDRESSBLOCK \\c 1 \\d \\e Test2 } - field.setExcludedCountryOrRegionName("Test2"); - - // { ADDRESSBLOCK \\c 1 \\d \\e Test2 \\f Test3 } - field.setNameAndAddressFormat("Test3"); - - // { ADDRESSBLOCK \\c 1 \\d \\e Test2 \\f Test3 \\l \"Test 4\" } - field.setLanguageId("Test4"); - - // Finally update this merge field - field.update(); - - doc.save(dataDir + "output.docx"); - - - } -} - - - - diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/InsertMergeFieldUsingDOM.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/InsertMergeFieldUsingDOM.java deleted file mode 100644 index cfe69fe7..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/InsertMergeFieldUsingDOM.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.aspose.words.examples.programming_documents.fields; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -public class InsertMergeFieldUsingDOM { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(InsertMergeFieldUsingDOM.class); - - Document doc = new Document(dataDir + "in.doc"); - DocumentBuilder builder = new DocumentBuilder(doc); - - // Get paragraph you want to append this merge field to - Paragraph para = (Paragraph) doc.getChildNodes(NodeType.PARAGRAPH, true).get(1); - - // Move cursor to this paragraph - builder.moveTo(para); - - // We want to insert a merge field like this: - // { " MERGEFIELD Test1 \\b Test2 \\f Test3 \\m \\v" } - - // Create instance of FieldMergeField class and lets build the above field code - FieldMergeField field = (FieldMergeField) builder.insertField(FieldType.FIELD_MERGE_FIELD, false); - - // { " MERGEFIELD Test1" } - field.setFieldName("Test1"); - - // { " MERGEFIELD Test1 \\b Test2" } - field.setTextBefore("Test2"); - - // { " MERGEFIELD Test1 \\b Test2 \\f Test3 } - field.setTextAfter("Test3"); - - // { " MERGEFIELD Test1 \\b Test2 \\f Test3 \\m" } - field.isMapped(true); - - // { " MERGEFIELD Test1 \\b Test2 \\f Test3 \\m \\v" } - field.isVerticalFormatting(true); - - // Finally update this merge field - field.update(); - - doc.save(dataDir + "output.docx"); - - - } -} - - - - diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/InsertNestedFields.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/InsertNestedFields.java deleted file mode 100644 index 95b3a80c..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/InsertNestedFields.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.aspose.words.examples.programming_documents.fields; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -public class InsertNestedFields { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(InsertNestedFields.class); - - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - // Insert few page breaks (just for testing) - for (int i = 0; i < 5; i++) - builder.insertBreak(BreakType.PAGE_BREAK); - - // Move DocumentBuilder cursor into the primary footer. - builder.moveToHeaderFooter(HeaderFooterType.FOOTER_PRIMARY); - - // We want to insert a field like this: - // { IF {PAGE} <> {NUMPAGES} "See Next Page" "Last Page" } - Field field = builder.insertField("IF "); - builder.moveTo(field.getSeparator()); - builder.insertField("PAGE"); - builder.write(" <> "); - builder.insertField("NUMPAGES"); - builder.write(" \"See Next Page\" \"Last Page\" "); - - // Finally update the outer field to recalcaluate the final value. Doing this will automatically update - // the inner fields at the same time. - field.update(); - - doc.save(dataDir + "output.docx"); - - - } -} - - - - diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/RemoveField.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/RemoveField.java deleted file mode 100644 index 7eed8138..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/RemoveField.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.aspose.words.examples.programming_documents.fields; - -import com.aspose.words.Document; -import com.aspose.words.Field; -import com.aspose.words.examples.Utils; - -public class RemoveField { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(RemoveField.class); - Document doc = new Document(dataDir + "Field.RemoveField.doc"); - - Field field = doc.getRange().getFields().get(0); - // Calling this method completely removes the field from the document. - field.remove(); - - doc.save(dataDir + "output.docx"); - - System.out.println("Field removed from the document successfully."); - } -} - - - - diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/RenameMergeFields.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/RenameMergeFields.java deleted file mode 100644 index 6a5040ca..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/RenameMergeFields.java +++ /dev/null @@ -1,115 +0,0 @@ -package com.aspose.words.examples.programming_documents.fields; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.aspose.words.Document; -import com.aspose.words.FieldStart; -import com.aspose.words.FieldType; -import com.aspose.words.Node; -import com.aspose.words.NodeCollection; -import com.aspose.words.NodeType; -import com.aspose.words.Run; -import com.aspose.words.examples.Utils; - -/** - * Shows how to rename merge fields in a Word document. - */ -public class RenameMergeFields { - - private static final String dataDir = Utils.getSharedDataDir(RenameMergeFields.class) + "Fields/"; - - /** - * Finds all merge fields in a Word document and changes their names. - */ - public static void main(String[] args) throws Exception { - // Specify your document name here. - Document doc = new Document(dataDir + "RenameMergeFields.doc"); - - // Select all field start nodes so we can find the merge fields. - NodeCollection fieldStarts = doc.getChildNodes(NodeType.FIELD_START, true); - for (FieldStart fieldStart : (Iterable) fieldStarts) { - if (fieldStart.getFieldType() == FieldType.FIELD_MERGE_FIELD) { - MergeField mergeField = new MergeField(fieldStart); - mergeField.setName(mergeField.getName() + "_Renamed"); - } - } - doc.save(dataDir + "RenameMergeFields Out.doc"); - } -} - -/** - * Represents a facade object for a merge field in a Microsoft Word document. - */ -class MergeField { - - private final Node mFieldStart; - private final Node mFieldSeparator; - private final Node mFieldEnd; - private static final Pattern G_REGEX = Pattern.compile("\\s*(MERGEFIELD\\s|)(\\s|)(\\S+)\\s+"); - - MergeField(FieldStart fieldStart) throws Exception { - if (fieldStart.equals(null)) - throw new IllegalArgumentException("fieldStart"); - if (fieldStart.getFieldType() != FieldType.FIELD_MERGE_FIELD) - throw new IllegalArgumentException("Field start type must be FieldMergeField."); - - mFieldStart = fieldStart; - - // Find the field separator node. - mFieldSeparator = fieldStart.getField().getSeparator(); - if (mFieldSeparator == null) - throw new IllegalStateException("Cannot find field separator."); - - mFieldEnd = fieldStart.getField().getEnd(); - } - - /** - * Gets or sets the name of the merge field. - */ - String getName() throws Exception { - return ((FieldStart) mFieldStart).getField().getResult().replace("«", "").replace("»", ""); - } - - void setName(String value) throws Exception { - // Merge field name is stored in the field result which is a Run - // node between field separator and field end. - Run fieldResult = (Run) mFieldSeparator.getNextSibling(); - fieldResult.setText(java.text.MessageFormat.format("«{0}»", value)); - - // But sometimes the field result can consist of more than one run, delete these runs. - removeSameParent(fieldResult.getNextSibling(), mFieldEnd); - - updateFieldCode(value); - } - - private void updateFieldCode(String fieldName) throws Exception { - // Field code is stored in a Run node between field start and field separator. - Run fieldCode = (Run) mFieldStart.getNextSibling(); - Matcher matcher = G_REGEX.matcher(((FieldStart) mFieldStart).getField().getFieldCode()); - - matcher.find(); - - String newFieldCode = java.text.MessageFormat.format(" {0}{1} ", matcher.group(1).toString(), fieldName); - fieldCode.setText(newFieldCode); - - // But sometimes the field code can consist of more than one run, delete these runs. - removeSameParent(fieldCode.getNextSibling(), mFieldSeparator); - } - - /** - * Removes nodes from start up to but not including the end node. Start and - * end are assumed to have the same parent. - */ - private static void removeSameParent(Node startNode, Node endNode) throws Exception { - if ((endNode != null) && (startNode.getParentNode() != endNode.getParentNode())) - throw new IllegalArgumentException("Start and end nodes are expected to have the same parent."); - - Node curChild = startNode; - while ((curChild != null) && (curChild != endNode)) { - Node nextChild = curChild.getNextSibling(); - curChild.remove(); - curChild = nextChild; - } - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/UpdateDocFields.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/UpdateDocFields.java deleted file mode 100644 index 1cb51a92..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/UpdateDocFields.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.aspose.words.examples.programming_documents.fields; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - -public class UpdateDocFields { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(UpdateDocFields.class); - - Document doc = new Document(dataDir + "Rendering.doc"); - - doc.updateFields(); - doc.save(dataDir + "output.docx"); - - } -} - - - - diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/UpdateFields.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/UpdateFields.java deleted file mode 100644 index 105e099e..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/fields/UpdateFields.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.aspose.words.examples.programming_documents.fields; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - -public class UpdateFields { - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(UpdateFields.class); - - Document doc = new Document(dataDir + "in.doc"); - - - // update fields - doc.updateFields(); - doc.save(dataDir + "output.docx"); - - - } -} - - - - diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/find_replace/FindAndHighlightText.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/find_replace/FindAndHighlightText.java deleted file mode 100644 index d7376564..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/find_replace/FindAndHighlightText.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.aspose.words.examples.programming_documents.find_replace; - -import java.awt.Color; -import java.util.ArrayList; -import java.util.regex.Pattern; - -import com.aspose.words.Document; -import com.aspose.words.FindReplaceOptions; -import com.aspose.words.IReplacingCallback; -import com.aspose.words.Node; -import com.aspose.words.NodeType; -import com.aspose.words.ReplaceAction; -import com.aspose.words.ReplacingArgs; -import com.aspose.words.Run; -import com.aspose.words.examples.Utils; - -public class FindAndHighlightText { - - private static final String dataDir = Utils.getSharedDataDir(FindAndHighlightText.class) + "FindAndReplace/"; - - public static void main(String[] args) throws Exception { - - Document doc = new Document(dataDir + "TestFile.doc"); - - FindReplaceOptions options = new FindReplaceOptions(); - options.ReplacingCallback = new ReplaceEvaluatorFindAndHighlight(); - - // We want the "your document" phrase to be highlighted. - Pattern regex = Pattern.compile("your document", Pattern.CASE_INSENSITIVE); - doc.getRange().replace(regex, "", options); - - // Save the output document. - doc.save(dataDir + "TestFile_out.doc"); - } -} - -class ReplaceEvaluatorFindAndHighlight implements IReplacingCallback { - /** - * This method is called by the Aspose.Words find and replace engine for - * each match. This method highlights the match string, even if it spans - * multiple runs. - */ - public int replacing(ReplacingArgs e) throws Exception { - // This is a Run node that contains either the beginning or the complete match. - Node currentNode = e.getMatchNode(); - - // The first (and may be the only) run can contain text before the match, - // in this case it is necessary to split the run. - if (e.getMatchOffset() > 0) - currentNode = splitRun((Run) currentNode, e.getMatchOffset()); - - // This array is used to store all nodes of the match for further highlighting. - ArrayList runs = new ArrayList(); - - // Find all runs that contain parts of the match string. - int remainingLength = e.getMatch().group().length(); - while ((remainingLength > 0) && (currentNode != null) && (currentNode.getText().length() <= remainingLength)) { - runs.add(currentNode); - remainingLength = remainingLength - currentNode.getText().length(); - - // Select the next Run node. - // Have to loop because there could be other nodes such as BookmarkStart etc. - do { - currentNode = currentNode.getNextSibling(); - } while ((currentNode != null) && (currentNode.getNodeType() != NodeType.RUN)); - } - - // Split the last run that contains the match if there is any text left. - if ((currentNode != null) && (remainingLength > 0)) { - splitRun((Run) currentNode, remainingLength); - runs.add(currentNode); - } - - // Now highlight all runs in the sequence. - for (Run run : (Iterable) runs) - run.getFont().setHighlightColor(Color.YELLOW); - - // Signal to the replace engine to do nothing because we have already done all what we wanted. - return ReplaceAction.SKIP; - } - - /** - * Splits text of the specified run into two runs. Inserts the new run just - * after the specified run. - */ - private static Run splitRun(Run run, int position) throws Exception { - Run afterRun = (Run) run.deepClone(true); - afterRun.setText(run.getText().substring(position)); - run.setText(run.getText().substring((0), (0) + (position))); - run.getParentNode().insertAfter(afterRun, run); - return afterRun; - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/find_replace/ReplaceTextWithField.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/find_replace/ReplaceTextWithField.java deleted file mode 100644 index bbf9549f..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/find_replace/ReplaceTextWithField.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.aspose.words.examples.programming_documents.find_replace; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.regex.Pattern; - -public class ReplaceTextWithField { - - private static final String dataDir = Utils.getSharedDataDir(ReplaceTextWithField.class) + "FindAndReplace/"; - - public static void main(String[] args) throws Exception { - - Document doc = new Document(dataDir + "Field.ReplaceTextWithFields.doc"); - - // Replace any "PlaceHolderX" instances in the document (where X is a number) with a merge field. - Pattern regex = Pattern.compile("PlaceHolder(\\d+)", Pattern.CASE_INSENSITIVE); - doc.getRange().replace(regex, new ReplaceTextWithFieldHandler("MERGEFIELD"), false); - - doc.save(dataDir + "Field.ReplaceTextWithFields Out.doc"); - - System.out.println("Text replaced with field successfully."); - } - - private static class ReplaceTextWithFieldHandler implements IReplacingCallback { - - public ReplaceTextWithFieldHandler(String name) { - mFieldName = name.toUpperCase(); - } - - public int replacing(ReplacingArgs e) throws Exception { - ArrayList runs = FindAndSplitMatchRuns(e); - - // Create DocumentBuilder which is used to insert the field. - DocumentBuilder builder = new DocumentBuilder((Document) e.getMatchNode().getDocument()); - builder.moveTo((Run) runs.get(runs.size() - 1)); - - // Insert the field into the document using the specified field type and the match text as the field name. - // If the fields you are inserting do not require this extra parameter then it can be removed from the string below. - builder.insertField(MessageFormat.format("{0} {1}", mFieldName, e.getMatch().group(0))); - - // Now remove all runs in the sequence. - for (Run run : (Iterable) runs) - run.remove(); - - // Signal to the replace engine to do nothing because we have already done all what we wanted. - return ReplaceAction.SKIP; - } - - /** - * Finds and splits the match runs and returns them in an ArrayList. - */ - public ArrayList FindAndSplitMatchRuns(ReplacingArgs e) throws Exception { - // This is a Run node that contains either the beginning or the complete match. - Node currentNode = e.getMatchNode(); - - // The first (and may be the only) run can contain text before the match, - // in this case it is necessary to split the run. - if (e.getMatchOffset() > 0) - currentNode = SplitRun((Run) currentNode, e.getMatchOffset()); - - // This array is used to store all nodes of the match for further removing. - ArrayList runs = new ArrayList(); - - // Find all runs that contain parts of the match string. - int remainingLength = e.getMatch().group().length(); - while ((remainingLength > 0) && (currentNode != null) && (currentNode.getText().length() <= remainingLength)) { - runs.add(currentNode); - remainingLength = remainingLength - currentNode.getText().length(); - - // Select the next Run node. - // Have to loop because there could be other nodes such as BookmarkStart etc. - do { - currentNode = currentNode.getNextSibling(); - } while ((currentNode != null) && (currentNode.getNodeType() != NodeType.RUN)); - } - - // Split the last run that contains the match if there is any text left. - if ((currentNode != null) && (remainingLength > 0)) { - SplitRun((Run) currentNode, remainingLength); - runs.add(currentNode); - } - - return runs; - } - - /** - * Splits text of the specified run into two runs. Inserts the new run - * just after the specified run. - */ - private Run SplitRun(Run run, int position) throws Exception { - Run afterRun = (Run) run.deepClone(true); - afterRun.setText(run.getText().substring(position)); - run.setText(run.getText().substring(0, position)); - run.getParentNode().insertAfter(afterRun, run); - return afterRun; - - } - - private String mFieldName; - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/find_replace/ReplaceWithEvaluator.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/find_replace/ReplaceWithEvaluator.java deleted file mode 100644 index da040df6..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/find_replace/ReplaceWithEvaluator.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.aspose.words.examples.programming_documents.find_replace; - -import java.util.regex.Pattern; - -import com.aspose.words.Document; -import com.aspose.words.FindReplaceOptions; -import com.aspose.words.IReplacingCallback; -import com.aspose.words.ReplaceAction; -import com.aspose.words.ReplacingArgs; -import com.aspose.words.examples.Utils; - -public class ReplaceWithEvaluator { - - private static final String dataDir = Utils.getSharedDataDir(ReplaceWithEvaluator.class) + "FindAndReplace/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(dataDir + "Range.ReplaceWithEvaluator.doc"); - - FindReplaceOptions options = new FindReplaceOptions(); - options.ReplacingCallback = new MyReplaceEvaluator(); - - doc.getRange().replace(Pattern.compile("[s|m]ad"), "", options); - doc.save(dataDir + "Range.ReplaceWithEvaluator_Out.doc"); - } -} - -class MyReplaceEvaluator implements IReplacingCallback { - private int mMatchNumber; - - /** - * This is called during a replace operation each time a match is found. - * This method appends a number to the match string and returns it as a - * replacement string. - */ - public int replacing(ReplacingArgs e) throws Exception { - e.setReplacement(e.getMatch().group() + Integer.toString(mMatchNumber)); - mMatchNumber++; - return ReplaceAction.REPLACE; - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/find_replace/ReplaceWithRegex.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/find_replace/ReplaceWithRegex.java deleted file mode 100644 index 38c6d7e4..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/find_replace/ReplaceWithRegex.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.aspose.words.examples.programming_documents.find_replace; - -import com.aspose.words.Document; -import com.aspose.words.FindReplaceOptions; -import com.aspose.words.examples.Utils; - -import java.util.regex.Pattern; - -public class ReplaceWithRegex { - - private static final String dataDir = Utils.getSharedDataDir(ReplaceWithRegex.class) + "FindAndReplace/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(dataDir + "ReplaceWithRegex.doc"); - FindReplaceOptions options = new FindReplaceOptions(); - doc.getRange().replace(Pattern.compile("[s|m]ad"), "happy", options); - doc.save(dataDir + "ReplaceWithRegex_Out.doc"); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/find_replace/ReplaceWithString.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/find_replace/ReplaceWithString.java deleted file mode 100644 index b22ef7b3..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/find_replace/ReplaceWithString.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.aspose.words.examples.programming_documents.find_replace; - -import com.aspose.words.Document; -import com.aspose.words.FindReplaceDirection; -import com.aspose.words.FindReplaceOptions; -import com.aspose.words.examples.Utils; - -public class ReplaceWithString { - - public static final String dataDir = Utils.getSharedDataDir(ReplaceWithString.class) + "FindAndReplace/"; - - public static void main(String[] args) throws Exception { - - Document doc = new Document(dataDir + "ReplaceWithString.doc"); - doc.getRange().replace("sad", "bad", new FindReplaceOptions(FindReplaceDirection.FORWARD)); - doc.save(dataDir + "ReplaceWithString_out.doc"); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/images/AddWatermarkToADocument.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/images/AddWatermarkToADocument.java deleted file mode 100644 index cf34edd7..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/images/AddWatermarkToADocument.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.aspose.words.examples.programming_documents.images; - -import java.awt.Color; - -import com.aspose.words.Document; -import com.aspose.words.HeaderFooter; -import com.aspose.words.HeaderFooterType; -import com.aspose.words.HorizontalAlignment; -import com.aspose.words.Paragraph; -import com.aspose.words.RelativeHorizontalPosition; -import com.aspose.words.RelativeVerticalPosition; -import com.aspose.words.Section; -import com.aspose.words.Shape; -import com.aspose.words.ShapeType; -import com.aspose.words.VerticalAlignment; -import com.aspose.words.WrapType; -import com.aspose.words.examples.Utils; - -public class AddWatermarkToADocument { - - private static final String dataDir = Utils.getSharedDataDir(AddWatermarkToADocument.class) + "Document/"; - - public static void main(String[] args) throws Exception { - - Document doc = new Document(dataDir + "Document.doc"); - insertWatermarkText(doc, "CONFIDENTIAL"); - doc.save(dataDir + "Document_out.doc"); - } - - /** - * Inserts a watermark into a document. - * - * @param doc - * The input document. - * @param watermarkText - * Text of the watermark. - */ - private static void insertWatermarkText(Document doc, String watermarkText) throws Exception { - // Create a watermark shape. This will be a WordArt shape. - // You are free to try other shape types as watermarks. - Shape watermark = new Shape(doc, ShapeType.TEXT_PLAIN_TEXT); - - // Set up the text of the watermark. - watermark.getTextPath().setText(watermarkText); - watermark.getTextPath().setFontFamily("Arial"); - watermark.setWidth(500); - watermark.setHeight(100); - // Text will be directed from the bottom-left to the top-right corner. - watermark.setRotation(-40); - // Remove the following two lines if you need a solid black text. - watermark.getFill().setColor(Color.GRAY); // Try LightGray to get more Word-style watermark - watermark.setStrokeColor(Color.GRAY); // Try LightGray to get more Word-style watermark - - // Place the watermark in the page center. - watermark.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE); - watermark.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE); - watermark.setWrapType(WrapType.NONE); - watermark.setVerticalAlignment(VerticalAlignment.CENTER); - watermark.setHorizontalAlignment(HorizontalAlignment.CENTER); - - // Create a new paragraph and append the watermark to this paragraph. - Paragraph watermarkPara = new Paragraph(doc); - watermarkPara.appendChild(watermark); - - // Insert the watermark into all headers of each document section. - for (Section sect : doc.getSections()) { - // There could be up to three different headers in each section, since we want - // the watermark to appear on all pages, insert into all headers. - insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_PRIMARY); - insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_FIRST); - insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_EVEN); - } - } - - private static void insertWatermarkIntoHeader(Paragraph watermarkPara, Section sect, int headerType) throws Exception { - HeaderFooter header = sect.getHeadersFooters().getByHeaderFooterType(headerType); - - if (header == null) { - // There is no header of the specified type in the current section, create it. - header = new HeaderFooter(sect.getDocument(), headerType); - sect.getHeadersFooters().add(header); - } - - // Insert a clone of the watermark into the header. - header.appendChild(watermarkPara.deepClone(true)); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/images/CompressImages.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/images/CompressImages.java deleted file mode 100644 index 912f4443..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/images/CompressImages.java +++ /dev/null @@ -1,231 +0,0 @@ - -package com.aspose.words.examples.programming_documents.images; - -import com.aspose.words.*; -import com.aspose.words.Shape; -import com.aspose.words.examples.Utils; - -import javax.imageio.IIOImage; -import javax.imageio.ImageIO; -import javax.imageio.ImageWriteParam; -import javax.imageio.ImageWriter; -import javax.imageio.stream.ImageOutputStream; -import java.awt.*; -import java.awt.geom.Point2D; -import java.awt.image.BufferedImage; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.text.MessageFormat; -import java.util.Iterator; - - -public class CompressImages -{ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(CompressImages.class); - - String srcFileName = dataDir + "Test.docx"; - - System.out.println(MessageFormat.format("Loading {0}. Size {1}.", srcFileName, getFileSize(srcFileName))); - Document doc = new Document(srcFileName); - - // 220ppi Print - said to be excellent on most printers and screens. - // 150ppi Screen - said to be good for web pages and projectors. - // 96ppi Email - said to be good for minimal document size and sharing. - final int desiredPpi = 150; - - // In Java this seems to be a good compression / quality setting. - final int jpegQuality = 90; - - // Resample images to desired ppi and save. - int count = Resampler.resample(doc, desiredPpi, jpegQuality); - - System.out.println(MessageFormat.format("Resampled {0} images.", count)); - - if (count != 1) - System.out.println("We expected to have only 1 image resampled in this test document!"); - - String dstFileName = srcFileName + ".Resampled Out.docx"; - doc.save(dstFileName); - System.out.println(MessageFormat.format("Saving {0}. Size {1}.", dstFileName, getFileSize(dstFileName))); - - // Verify that the first image was compressed by checking the new Ppi. - doc = new Document(dstFileName); - com.aspose.words.Shape shape = (com.aspose.words.Shape)doc.getChild(NodeType.SHAPE, 0, true); - double imagePpi = shape.getImageData().getImageSize().getWidthPixels() / ConvertUtil.pointToInch(shape.getSizeInPoints().getX()); - - assert (imagePpi < 150) : "Image was not resampled successfully."; - } - - public static int getFileSize(String fileName) throws Exception - { - File file = new File(fileName); - return (int)file.length(); - } -} - -class Resampler -{ - /** - * Resamples all images in the document that are greater than the specified PPI (pixels per inch) to the specified PPI - * and converts them to JPEG with the specified quality setting. - * - * @param doc The document to process. - * @param desiredPpi Desired pixels per inch. 220 high quality. 150 screen quality. 96 email quality. - * @param jpegQuality 0 - 100% JPEG quality. - */ - public static int resample(Document doc, int desiredPpi, int jpegQuality) throws Exception - { - int count = 0; - - // Convert VML shapes. - for (Shape vmlShape : (Iterable) doc.getChildNodes(NodeType.SHAPE, true, false)) - { - // It is important to use this method to correctly get the picture shape size in points even if the picture is inside a group shape. - Point2D.Float shapeSizeInPoints = vmlShape.getSizeInPoints(); - - if (resampleCore(vmlShape.getImageData(), shapeSizeInPoints, desiredPpi, jpegQuality)) - count++; - } - - // Convert DrawingML shapes. - for (com.aspose.words.Shape dmlShape : (Iterable) doc.getChildNodes(NodeType.SHAPE, true, false)) - { - // In MS Word the size of a DrawingML shape is always in points at the moment. - Point2D.Float shapeSizeInPoints = dmlShape.getSizeInPoints(); - if (resampleCore(dmlShape.getImageData(), shapeSizeInPoints, desiredPpi, jpegQuality)) - count++; - } - - return count; - } - - /** - * Resamples one VML or DrawingML image - */ - private static boolean resampleCore(ImageData imageData, Point2D.Float shapeSizeInPoints, int ppi, int jpegQuality) throws Exception - { - // The are actually several shape types that can have an image (picture, ole object, ole control), let's skip other shapes. - if (imageData == null) - return false; - - // An image can be stored in the shape or linked from somewhere else. Let's skip images that do not store bytes in the shape. - byte[] originalBytes = imageData.getImageBytes(); - if (originalBytes == null) - return false; - - // Ignore metafiles, they are vector drawings and we don't want to resample them. - int imageType = imageData.getImageType(); - if ((imageType == ImageType.WMF) || (imageType == ImageType.EMF)) - return false; - - try - { - double shapeWidthInches = ConvertUtil.pointToInch(shapeSizeInPoints.getX()); - double shapeHeightInches = ConvertUtil.pointToInch(shapeSizeInPoints.getY()); - - // Calculate the current PPI of the image. - ImageSize imageSize = imageData.getImageSize(); - double currentPpiX = imageSize.getWidthPixels() / shapeWidthInches; - double currentPpiY = imageSize.getHeightPixels() / shapeHeightInches; - - System.out.print(MessageFormat.format("Image PpiX:{0}, PpiY:{1}. ", (int) currentPpiX, (int) currentPpiY)); - - // Let's resample only if the current PPI is higher than the requested PPI (e.g. we have extra data we can get rid of). - if ((currentPpiX <= ppi) || (currentPpiY <= ppi)) - { - System.out.println("Skipping."); - return false; - } - - BufferedImage srcImage = imageData.toImage(); - - // Create a new image of such size that it will hold only the pixels required by the desired ppi. - int dstWidthPixels = (int)(shapeWidthInches * ppi); - int dstHeightPixels = (int)(shapeHeightInches * ppi); - BufferedImage dstImage = new BufferedImage(dstWidthPixels, dstHeightPixels, getResampledImageType(srcImage.getType())); - - // Drawing the source image to the new image scales it to the new size. - Graphics2D g = (Graphics2D)dstImage.getGraphics(); - try - { - // Setting any other interpolation or rendering value can increase the time taken extremely. - g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); - g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED); - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - - g.drawImage( - srcImage, - 0, 0, dstWidthPixels, dstHeightPixels, - 0, 0, srcImage.getWidth(), srcImage.getHeight(), - null); - } - finally - { - g.dispose(); - } - - - // Create JPEG encoder parameters with the quality setting. - Iterator writers = ImageIO.getImageWritersByFormatName("jpeg"); - ImageWriter writer = (ImageWriter)writers.next(); - ImageWriteParam param = writer.getDefaultWriteParam(); - param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); - param.setCompressionQuality(jpegQuality / 100.0f); - - // Save the image as JPEG to a memory stream. - ByteArrayOutputStream dstStream = new ByteArrayOutputStream(); - ImageOutputStream ios = ImageIO.createImageOutputStream(dstStream); - writer.setOutput(ios); - - IIOImage ioImage = new IIOImage(dstImage, null, null); - writer.write(null, ioImage, param); - - // This is required, otherwise not all data might be written to our stream. - ios.flush(); - // The Java documentation recommends disposing image readers and writers asap. - writer.dispose(); - - // If the image saved as JPEG is smaller than the original, store it in the shape. - System.out.println(MessageFormat.format("Original size {0}, new size {1}.", originalBytes.length, dstStream.size())); - if (dstStream.size() < originalBytes.length) - { - imageData.setImageBytes(dstStream.toByteArray()); - return true; - } - } - catch (Exception e) - { - // Catch an exception, log an error and continue if cannot process one of the images for whatever reason. - System.out.println("Error processing an image, ignoring. " + e.getMessage()); - } - - return false; - } - - private static int getResampledImageType(int srcImageType) - { - // In general, we want to preserve the image color model, but some things need to be taken care of. - switch (srcImageType) - { - case BufferedImage.TYPE_CUSTOM: - // I have seen some PNG images return TYPE_CUSTOM and creating a BufferedImage of this type fails, - // so we fallback to a more suitable value. - return BufferedImage.TYPE_INT_RGB; - case BufferedImage.TYPE_BYTE_INDEXED: - // This has some problems with colors if we use the BufferedImage ctor that accepts the color model, - // so let's just convert the bitmap to RGB color. It is enough for the sample project. - return BufferedImage.TYPE_INT_RGB; - case BufferedImage.TYPE_INT_ARGB: - case BufferedImage.TYPE_4BYTE_ABGR: - // 32bit image with alpha channel has wrong colors if it is saved to JPEG. - // JPEG doesn't support transparency so we may convert image to RGB without alpha. - return BufferedImage.TYPE_INT_RGB; - default: - // The image format should be okay. - return srcImageType; - } - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/images/ExtractImagesToFiles.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/images/ExtractImagesToFiles.java deleted file mode 100644 index 62e97553..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/images/ExtractImagesToFiles.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.aspose.words.examples.programming_documents.images; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - - -public class ExtractImagesToFiles { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ExtractImagesToFiles.class); - - Document doc = new Document(dataDir + "Image.SampleImages.doc"); - - NodeCollection shapes = (NodeCollection) doc.getChildNodes(NodeType.SHAPE, true); - int imageIndex = 0; - for (Shape shape : shapes - ) { - if (shape.hasImage()) { - String imageFileName = String.format( - "Image.ExportImages.{0}_out_{1}", imageIndex, FileFormatUtil.imageTypeToExtension(shape.getImageData().getImageType())); - shape.getImageData().save(dataDir + imageFileName); - imageIndex++; - } - } - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/images/InsertBarcodeImage.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/images/InsertBarcodeImage.java deleted file mode 100644 index 125c097e..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/images/InsertBarcodeImage.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.aspose.words.examples.programming_documents.images; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -public class InsertBarcodeImage { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(InsertBarcodeImage.class); - - Document doc = new Document(dataDir + "Image.SampleImages.doc"); - DocumentBuilder builder = new DocumentBuilder(doc); - - // The number of pages the document should have. - int numPages = 4; - // The document starts with one section, insert the barcode into this existing section. - InsertBarcodeIntoFooter(builder, doc.getFirstSection(), 1, HeaderFooterType.FOOTER_PRIMARY); - InsertBarcodeIntoFooter(builder, doc.getFirstSection(), 1, HeaderFooterType.FOOTER_PRIMARY); - - for (int i = 1; i < numPages; i++) { - // Clone the first section and add it into the end of the document. - Section cloneSection = (Section) doc.getFirstSection().deepClone(false); - // cloneSection.getPageSetup().getSectionStart() = SectionStart.NEW_PAGE; - doc.appendChild(cloneSection); - - // Insert the barcode and other information into the footer of the section. - InsertBarcodeIntoFooter(builder, cloneSection, i, HeaderFooterType.FOOTER_PRIMARY); - } - - dataDir = dataDir + "Document_out_.docx"; - // Save the document as a PDF to disk. You can also save this directly to a stream. - doc.save(dataDir); - } - - private static void InsertBarcodeIntoFooter(DocumentBuilder builder, Section section, int pageId, int footerType) { - // Move to the footer type in the specific section. - try { - builder.moveToSection(section.getDocument().indexOf(section)); - builder.moveToHeaderFooter(footerType); - - String dataDir = Utils.getDataDir(InsertBarcodeImage.class); - - // Insert the barcode, then move to the next line and insert the ID along with the page number. - // Use pageId if you need to insert a different barcode on each page. 0 = First page, 1 = Second page etc. - builder.insertImage(dataDir + "Barcode1.png"); - builder.writeln(); - builder.write("1234567890"); - builder.insertField("PAGE"); - - // Create a right aligned tab at the right margin. - double tabPos = section.getPageSetup().getPageWidth() - section.getPageSetup().getRightMargin() - section.getPageSetup().getLeftMargin(); - builder.getCurrentParagraph().getParagraphFormat().getTabStops().add(new TabStop(tabPos, TabAlignment.RIGHT, TabLeader.NONE)); - - // Move to the right hand side of the page and insert the page and page total. - builder.write(ControlChar.TAB); - builder.insertField("PAGE"); - builder.write(" of "); - builder.insertField("NUMPAGES"); - } catch (Exception x) { - - } - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/AppendDocumentManually.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/AppendDocumentManually.java deleted file mode 100644 index 43ac32aa..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/AppendDocumentManually.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.aspose.words.examples.programming_documents.joining_appending; - -import com.aspose.words.Document; -import com.aspose.words.ImportFormatMode; -import com.aspose.words.Node; -import com.aspose.words.Section; -import com.aspose.words.examples.Utils; - - -public class AppendDocumentManually { - - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(AppendDocumentManually.class); - - Document dstDoc = new Document(dataDir + "TestFile.Destination.doc"); - Document srcDoc = new Document(dataDir + "TestFile.Source.doc"); - - for (Section srcSection : srcDoc.getSections()) { - Node dstSection = dstDoc.importNode(srcSection, true, ImportFormatMode.KEEP_SOURCE_FORMATTING); - dstDoc.appendChild(dstSection); - } - - dstDoc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/BaseDocument.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/BaseDocument.java deleted file mode 100644 index 347858ed..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/BaseDocument.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.aspose.words.examples.programming_documents.joining_appending; - -import com.aspose.words.Document; -import com.aspose.words.ImportFormatMode; -import com.aspose.words.examples.Utils; - - -public class BaseDocument { - - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(BaseDocument.class); - - Document dstDoc = new Document(); - Document srcDoc = new Document(dataDir + "TestFile.Source.doc"); - - // The destination document is not actually empty which often causes a blank page to appear before the appended document - // This is due to the base document having an empty section and the new document being started on the next page. - // Remove all content from the destination document before appending. - dstDoc.removeAllChildren(); - - dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - dstDoc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFields.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFields.java deleted file mode 100644 index 57359aae..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFields.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.aspose.words.examples.programming_documents.joining_appending; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.text.MessageFormat; - - -public class ConvertNumPageFields { - - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ConvertNumPageFields.class); - - Document dstDoc = new Document(dataDir + "TestFile.Destination.doc"); - Document srcDoc = new Document(dataDir + "TestFile.Source.doc"); - - // Restart the page numbering on the start of the source document. - srcDoc.getFirstSection().getPageSetup().setRestartPageNumbering(true); - srcDoc.getFirstSection().getPageSetup().setPageStartingNumber(1); - - // Append the source document to the end of the destination document. - dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - - // After joining the documents the NUMPAGE fields will now display the total number of pages which - // is undesired behaviour. Call this method to fix them by replacing them with PAGEREF fields. - convertNumPageFieldsToPageRef(dstDoc); - - // This needs to be called in order to update the new fields with page numbers. - dstDoc.updatePageLayout(); - - dstDoc.save(dataDir + "output.doc"); - - } - - /** - * Replaces all NUMPAGES fields in the document with PAGEREF fields. The replacement field displays the total number - * of pages in the sub document instead of the total pages in the document. - * - * @param doc The combined document to process. - */ - public static void convertNumPageFieldsToPageRef(Document doc) throws Exception { - // This is the prefix for each bookmark which signals where page numbering restarts. - // The underscore "_" at the start inserts this bookmark as hidden in MS Word. - final String BOOKMARK_PREFIX = "_SubDocumentEnd"; - // Field name of the NUMPAGES field. - final String NUM_PAGES_FIELD_NAME = "NUMPAGES"; - // Field name of the PAGEREF field. - final String PAGE_REF_FIELD_NAME = "PAGEREF"; - - // Create a new DocumentBuilder which is used to insert the bookmarks and replacement fields. - DocumentBuilder builder = new DocumentBuilder(doc); - // Defines the number of page restarts that have been encountered and therefore the number of "sub" documents - // found within this document. - int subDocumentCount = 0; - - // Iterate through all sections in the document. - for (Section section : doc.getSections()) { - // This section has it's page numbering restarted so we will treat this as the start of a sub document. - // Any PAGENUM fields in this inner document must be converted to special PAGEREF fields to correct numbering. - if (section.getPageSetup().getRestartPageNumbering()) { - // Don't do anything if this is the first section in the document. This part of the code will insert the bookmark marking - // the end of the previous sub document so therefore it is not applicable for first section in the document. - if (!section.equals(doc.getFirstSection())) { - // Get the previous section and the last node within the body of that section. - Section prevSection = (Section) section.getPreviousSibling(); - Node lastNode = prevSection.getBody().getLastChild(); - - // Use the DocumentBuilder to move to this node and insert the bookmark there. - // This bookmark represents the end of the sub document. - builder.moveTo(lastNode); - builder.startBookmark(BOOKMARK_PREFIX + subDocumentCount); - builder.endBookmark(BOOKMARK_PREFIX + subDocumentCount); - - // Increase the subdocument count to insert the correct bookmarks. - subDocumentCount++; - } - } - - // The last section simply needs the ending bookmark to signal that it is the end of the current sub document. - if (section.equals(doc.getLastSection())) { - // Insert the bookmark at the end of the body of the last section. - // Don't increase the count this time as we are just marking the end of the document. - Node lastNode = doc.getLastSection().getBody().getLastChild(); - builder.moveTo(lastNode); - builder.startBookmark(BOOKMARK_PREFIX + subDocumentCount); - builder.endBookmark(BOOKMARK_PREFIX + subDocumentCount); - } - - // Iterate through each NUMPAGES field in the section and replace the field with a PAGEREF field referring to the bookmark of the current subdocument - // This bookmark is positioned at the end of the sub document but does not exist yet. It is inserted when a section with restart page numbering or the last - // section is encountered. - for (Node node : section.getChildNodes(NodeType.FIELD_START, true).toArray()) { - FieldStart fieldStart = (FieldStart) node; - - if (fieldStart.getFieldType() == FieldType.FIELD_NUM_PAGES) { - // Get the field code. - String fieldCode = getFieldCode(fieldStart); - // Since the NUMPAGES field does not take any additional parameters we can assume the remaining part of the field - // code after the fieldname are the switches. We will use these to help recreate the NUMPAGES field as a PAGEREF field. - String fieldSwitches = fieldCode.replace(NUM_PAGES_FIELD_NAME, "").trim(); - - // Inserting the new field directly at the FieldStart node of the original field will cause the new field to - // not pick up the formatting of the original field. To counter this insert the field just before the original field - Node previousNode = fieldStart.getPreviousSibling(); - - // If a previous run cannot be found then we are forced to use the FieldStart node. - if (previousNode == null) - previousNode = fieldStart; - - // Insert a PAGEREF field at the same position as the field. - builder.moveTo(previousNode); - // This will insert a new field with a code like " PAGEREF _SubDocumentEnd0 *\MERGEFORMAT ". - Field newField = builder.insertField(MessageFormat.format(" {0} {1}{2} {3} ", PAGE_REF_FIELD_NAME, BOOKMARK_PREFIX, subDocumentCount, fieldSwitches)); - - // The field will be inserted before the referenced node. Move the node before the field instead. - previousNode.getParentNode().insertBefore(previousNode, newField.getStart()); - - // Remove the original NUMPAGES field from the document. - removeField(fieldStart); - } - } - } - } - - /** - * Retrieves the field code from a field. - * - * @param fieldStart The field start of the field which to gather the field code from. - */ - private static String getFieldCode(FieldStart fieldStart) throws Exception { - StringBuilder builder = new StringBuilder(); - - for (Node node = fieldStart; node != null && node.getNodeType() != NodeType.FIELD_SEPARATOR && - node.getNodeType() != NodeType.FIELD_END; node = node.nextPreOrder(node.getDocument())) { - // Use text only of Run nodes to avoid duplication. - if (node.getNodeType() == NodeType.RUN) - builder.append(node.getText()); - } - return builder.toString(); - } - - /** - * Removes the Field from the document. - * - * @param fieldStart The field start node of the field to remove. - */ - private static void removeField(FieldStart fieldStart) throws Exception { - Node currentNode = fieldStart; - boolean isRemoving = true; - while (currentNode != null && isRemoving) { - if (currentNode.getNodeType() == NodeType.FIELD_END) - isRemoving = false; - - Node nextNode = currentNode.nextPreOrder(currentNode.getDocument()); - currentNode.remove(); - currentNode = nextNode; - } - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFieldsToPageRef.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFieldsToPageRef.java deleted file mode 100644 index 8741fc44..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFieldsToPageRef.java +++ /dev/null @@ -1,181 +0,0 @@ - -package com.aspose.words.examples.programming_documents.joining_appending; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.text.MessageFormat; - - -public class ConvertNumPageFieldsToPageRef -{ - private static String gDataDir; - - public static void main(String[] args) throws Exception - { - - - // The path to the documents directory. - gDataDir = Utils.getDataDir(ConvertNumPageFieldsToPageRef.class); - - Document dstDoc = new Document(gDataDir + "TestFile.Destination.doc"); - Document srcDoc = new Document(gDataDir + "TestFile.Source.doc"); - - // Restart the page numbering on the start of the source document. - srcDoc.getFirstSection().getPageSetup().setRestartPageNumbering(true); - srcDoc.getFirstSection().getPageSetup().setPageStartingNumber(1); - - // Append the source document to the end of the destination document. - dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - - // After joining the documents the NUMPAGE fields will now display the total number of pages which - // is undesired behaviour. Call this method to fix them by replacing them with PAGEREF fields. - convertNumPageFieldsToPageRef(dstDoc); - - // This needs to be called in order to update the new fields with page numbers. - dstDoc.updatePageLayout(); - - dstDoc.save(gDataDir + "TestFile.ConvertNumPageFields Out.doc"); - - - System.out.println("Documents appended successfully."); - } - - /** - * Replaces all NUMPAGES fields in the document with PAGEREF fields. The replacement field displays the total number - * of pages in the sub document instead of the total pages in the document. - * - * @param doc The combined document to process. - */ - - public static void convertNumPageFieldsToPageRef(Document doc) throws Exception - { - // This is the prefix for each bookmark which signals where page numbering restarts. - // The underscore "_" at the start inserts this bookmark as hidden in MS Word. - final String BOOKMARK_PREFIX = "_SubDocumentEnd"; - // Field name of the NUMPAGES field. - final String NUM_PAGES_FIELD_NAME = "NUMPAGES"; - // Field name of the PAGEREF field. - final String PAGE_REF_FIELD_NAME = "PAGEREF"; - - // Create a new DocumentBuilder which is used to insert the bookmarks and replacement fields. - DocumentBuilder builder = new DocumentBuilder(doc); - // Defines the number of page restarts that have been encountered and therefore the number of "sub" documents - // found within this document. - int subDocumentCount = 0; - - // Iterate through all sections in the document. - for (Section section : doc.getSections()) - { - // This section has it's page numbering restarted so we will treat this as the start of a sub document. - // Any PAGENUM fields in this inner document must be converted to special PAGEREF fields to correct numbering. - if (section.getPageSetup().getRestartPageNumbering()) - { - // Don't do anything if this is the first section in the document. This part of the code will insert the bookmark marking - // the end of the previous sub document so therefore it is not applicable for first section in the document. - if (!section.equals(doc.getFirstSection())) - { - // Get the previous section and the last node within the body of that section. - Section prevSection = (Section)section.getPreviousSibling(); - Node lastNode = prevSection.getBody().getLastChild(); - - // Use the DocumentBuilder to move to this node and insert the bookmark there. - // This bookmark represents the end of the sub document. - builder.moveTo(lastNode); - builder.startBookmark(BOOKMARK_PREFIX + subDocumentCount); - builder.endBookmark(BOOKMARK_PREFIX + subDocumentCount); - - // Increase the subdocument count to insert the correct bookmarks. - subDocumentCount++; - } - } - - // The last section simply needs the ending bookmark to signal that it is the end of the current sub document. - if (section.equals(doc.getLastSection())) - { - // Insert the bookmark at the end of the body of the last section. - // Don't increase the count this time as we are just marking the end of the document. - Node lastNode = doc.getLastSection().getBody().getLastChild(); - builder.moveTo(lastNode); - builder.startBookmark(BOOKMARK_PREFIX + subDocumentCount); - builder.endBookmark(BOOKMARK_PREFIX + subDocumentCount); - } - - // Iterate through each NUMPAGES field in the section and replace the field with a PAGEREF field referring to the bookmark of the current subdocument - // This bookmark is positioned at the end of the sub document but does not exist yet. It is inserted when a section with restart page numbering or the last - // section is encountered. - for (Node node : section.getChildNodes(NodeType.FIELD_START, true).toArray()) - { - FieldStart fieldStart = (FieldStart)node; - - if (fieldStart.getFieldType() == FieldType.FIELD_NUM_PAGES) - { - // Get the field code. - String fieldCode = getFieldCode(fieldStart); - // Since the NUMPAGES field does not take any additional parameters we can assume the remaining part of the field - // code after the fieldname are the switches. We will use these to help recreate the NUMPAGES field as a PAGEREF field. - String fieldSwitches = fieldCode.replace(NUM_PAGES_FIELD_NAME, "").trim(); - - // Inserting the new field directly at the FieldStart node of the original field will cause the new field to - // not pick up the formatting of the original field. To counter this insert the field just before the original field - Node previousNode = fieldStart.getPreviousSibling(); - - // If a previous run cannot be found then we are forced to use the FieldStart node. - if (previousNode == null) - previousNode = fieldStart; - - // Insert a PAGEREF field at the same position as the field. - builder.moveTo(previousNode); - // This will insert a new field with a code like " PAGEREF _SubDocumentEnd0 *\MERGEFORMAT ". - Field newField = builder.insertField(MessageFormat.format(" {0} {1}{2} {3} ", PAGE_REF_FIELD_NAME, BOOKMARK_PREFIX, subDocumentCount, fieldSwitches)); - - // The field will be inserted before the referenced node. Move the node before the field instead. - previousNode.getParentNode().insertBefore(previousNode, newField.getStart()); - - // Remove the original NUMPAGES field from the document. - removeField(fieldStart); - } - } - } - } - - - /** - * Retrieves the field code from a field. - * - * @param fieldStart The field start of the field which to gather the field code from. - */ - private static String getFieldCode(FieldStart fieldStart) throws Exception - { - StringBuilder builder = new StringBuilder(); - - for (Node node = fieldStart; node != null && node.getNodeType() != NodeType.FIELD_SEPARATOR && - node.getNodeType() != NodeType.FIELD_END; node = node.nextPreOrder(node.getDocument())) - { - // Use text only of Run nodes to avoid duplication. - if (node.getNodeType() == NodeType.RUN) - builder.append(node.getText()); - } - return builder.toString(); - } - - /** - * Removes the Field from the document. - * - * @param fieldStart The field start node of the field to remove. - */ - private static void removeField(FieldStart fieldStart) throws Exception - { - Node currentNode = fieldStart; - boolean isRemoving = true; - while (currentNode != null && isRemoving) - { - if (currentNode.getNodeType() == NodeType.FIELD_END) - isRemoving = false; - - Node nextNode = currentNode.nextPreOrder(currentNode.getDocument()); - currentNode.remove(); - currentNode = nextNode; - } - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFieldsWithPageRef.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFieldsWithPageRef.java deleted file mode 100644 index 10d605e1..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFieldsWithPageRef.java +++ /dev/null @@ -1,148 +0,0 @@ - -package com.aspose.words.examples.programming_documents.joining_appending; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.text.MessageFormat; - - -public class ConvertNumPageFieldsWithPageRef -{ - private static String gDataDir; - - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - gDataDir = Utils.getDataDir(ConvertNumPageFieldsWithPageRef.class); - - Document doc = new Document(); - // This is the prefix for each bookmark which signals where page numbering restarts. - // The underscore "_" at the start inserts this bookmark as hidden in MS Word. - final String BOOKMARK_PREFIX = "_SubDocumentEnd"; - // Field name of the NUMPAGES field. - final String NUM_PAGES_FIELD_NAME = "NUMPAGES"; - // Field name of the PAGEREF field. - final String PAGE_REF_FIELD_NAME = "PAGEREF"; - - // Create a new DocumentBuilder which is used to insert the bookmarks and replacement fields. - DocumentBuilder builder = new DocumentBuilder(doc); - // Defines the number of page restarts that have been encountered and therefore the number of "sub" documents - // Defines the number of page restarts that have been encountered and therefore the number of "sub" documents - // found within this document. - int subDocumentCount = 0; - - // Iterate through all sections in the document. - for (Section section : doc.getSections()) - { - // This section has it's page numbering restarted so we will treat this as the start of a sub document. - // Any PAGENUM fields in this inner document must be converted to special PAGEREF fields to correct numbering. - if (section.getPageSetup().getRestartPageNumbering()) - { - // Don't do anything if this is the first section in the document. This part of the code will insert the bookmark marking - // the end of the previous sub document so therefore it is not applicable for first section in the document. - if (!section.equals(doc.getFirstSection())) - { - // Get the previous section and the last node within the body of that section. - Section prevSection = (Section)section.getPreviousSibling(); - Node lastNode = prevSection.getBody().getLastChild(); - - // Use the DocumentBuilder to move to this node and insert the bookmark there. - // This bookmark represents the end of the sub document. - builder.moveTo(lastNode); - builder.startBookmark(BOOKMARK_PREFIX + subDocumentCount); - builder.endBookmark(BOOKMARK_PREFIX + subDocumentCount); - - // Increase the subdocument count to insert the correct bookmarks. - subDocumentCount++; - } - } - - // The last section simply needs the ending bookmark to signal that it is the end of the current sub document. - if (section.equals(doc.getLastSection())) - { - // Insert the bookmark at the end of the body of the last section. - // Don't increase the count this time as we are just marking the end of the document. - Node lastNode = doc.getLastSection().getBody().getLastChild(); - builder.moveTo(lastNode); - builder.startBookmark(BOOKMARK_PREFIX + subDocumentCount); - builder.endBookmark(BOOKMARK_PREFIX + subDocumentCount); - } - - // Iterate through each NUMPAGES field in the section and replace the field with a PAGEREF field referring to the bookmark of the current subdocument - // This bookmark is positioned at the end of the sub document but does not exist yet. It is inserted when a section with restart page numbering or the last - // section is encountered. - for (Node node : section.getChildNodes(NodeType.FIELD_START, true).toArray()) - { - FieldStart fieldStart = (FieldStart)node; - - if (fieldStart.getFieldType() == FieldType.FIELD_NUM_PAGES) - { - // Get the field code. - String fieldCode = getFieldCode(fieldStart); - // Since the NUMPAGES field does not take any additional parameters we can assume the remaining part of the field - // code after the fieldname are the switches. We will use these to help recreate the NUMPAGES field as a PAGEREF field. - String fieldSwitches = fieldCode.replace(NUM_PAGES_FIELD_NAME, "").trim(); - - // Inserting the new field directly at the FieldStart node of the original field will cause the new field to - // not pick up the formatting of the original field. To counter this insert the field just before the original field - Node previousNode = fieldStart.getPreviousSibling(); - - // If a previous run cannot be found then we are forced to use the FieldStart node. - if (previousNode == null) - previousNode = fieldStart; - - // Insert a PAGEREF field at the same position as the field. - builder.moveTo(previousNode); - // This will insert a new field with a code like " PAGEREF _SubDocumentEnd0 *\MERGEFORMAT ". - Field newField = builder.insertField(MessageFormat.format(" {0} {1}{2} {3} ", PAGE_REF_FIELD_NAME, BOOKMARK_PREFIX, subDocumentCount, fieldSwitches)); - - // The field will be inserted before the referenced node. Move the node before the field instead. - previousNode.getParentNode().insertBefore(previousNode, newField.getStart()); - - // Remove the original NUMPAGES field from the document. - removeField(fieldStart); - } - } - } - } - - /** - * Retrieves the field code from a field. - * - * @param fieldStart The field start of the field which to gather the field code from. - */ - private static String getFieldCode(FieldStart fieldStart) throws Exception - { - StringBuilder builder = new StringBuilder(); - - for (Node node = fieldStart; node != null && node.getNodeType() != NodeType.FIELD_SEPARATOR && - node.getNodeType() != NodeType.FIELD_END; node = node.nextPreOrder(node.getDocument())) - { - // Use text only of Run nodes to avoid duplication. - if (node.getNodeType() == NodeType.RUN) - builder.append(node.getText()); - } - return builder.toString(); - } - - /** - * Removes the Field from the document. - * - * @param fieldStart The field start node of the field to remove. - */ - private static void removeField(FieldStart fieldStart) throws Exception - { - Node currentNode = fieldStart; - boolean isRemoving = true; - while (currentNode != null && isRemoving) - { - if (currentNode.getNodeType() == NodeType.FIELD_END) - isRemoving = false; - - Node nextNode = currentNode.nextPreOrder(currentNode.getDocument()); - currentNode.remove(); - currentNode = nextNode; - } - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/DifferentPageSetup.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/DifferentPageSetup.java deleted file mode 100644 index ba92bfe1..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/DifferentPageSetup.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.aspose.words.examples.programming_documents.joining_appending; - -import com.aspose.words.Document; -import com.aspose.words.ImportFormatMode; -import com.aspose.words.SectionStart; -import com.aspose.words.examples.Utils; - - -public class DifferentPageSetup { - - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(DifferentPageSetup.class); - - Document dstDoc = new Document(dataDir + "TestFile.Destination.doc"); - Document srcDoc = new Document(dataDir + "TestFile.SourcePageSetup.doc"); - - // Set the source document to continue straight after the end of the destination document. - // If some page setup settings are different then this may not work and the source document will appear - // on a new page. - srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.CONTINUOUS); - - // To ensure this does not happen when the source document has different page setup settings make sure the - // settings are identical between the last section of the destination document. - // If there are further continuous sections that follow on in the source document then this will need to be - // repeated for those sections as well. - srcDoc.getFirstSection().getPageSetup().setPageWidth(dstDoc.getLastSection().getPageSetup().getPageWidth()); - srcDoc.getFirstSection().getPageSetup().setPageHeight(dstDoc.getLastSection().getPageSetup().getPageHeight()); - srcDoc.getFirstSection().getPageSetup().setOrientation(dstDoc.getLastSection().getPageSetup().getOrientation()); - - dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - dstDoc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/GetRemoveField.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/GetRemoveField.java deleted file mode 100644 index 97bec057..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/GetRemoveField.java +++ /dev/null @@ -1,171 +0,0 @@ - -package com.aspose.words.examples.programming_documents.joining_appending; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.text.MessageFormat; - - -public class GetRemoveField { - private static String gDataDir; - - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - gDataDir = Utils.getDataDir(GetRemoveField.class); - - Document dstDoc = new Document(gDataDir + "TestFile.Destination.doc"); - Document srcDoc = new Document(gDataDir + "TestFile.Source.doc"); - - // Restart the page numbering on the start of the source document. - srcDoc.getFirstSection().getPageSetup().setRestartPageNumbering(true); - srcDoc.getFirstSection().getPageSetup().setPageStartingNumber(1); - - // Append the source document to the end of the destination document. - dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - - // After joining the documents the NUMPAGE fields will now display the total number of pages which - // is undesired behaviour. Call this method to fix them by replacing them with PAGEREF fields. - convertNumPageFieldsToPageRef(dstDoc); - - // This needs to be called in order to update the new fields with page numbers. - dstDoc.updatePageLayout(); - - dstDoc.save(gDataDir + "TestFile.ConvertNumPageFields Out.doc"); - - - System.out.println("Documents appended successfully."); - } - - /** - * Replaces all NUMPAGES fields in the document with PAGEREF fields. The replacement field displays the total number - * of pages in the sub document instead of the total pages in the document. - * - * @param doc The combined document to process. - */ - public static void convertNumPageFieldsToPageRef(Document doc) throws Exception { - // This is the prefix for each bookmark which signals where page numbering restarts. - // The underscore "_" at the start inserts this bookmark as hidden in MS Word. - final String BOOKMARK_PREFIX = "_SubDocumentEnd"; - // Field name of the NUMPAGES field. - final String NUM_PAGES_FIELD_NAME = "NUMPAGES"; - // Field name of the PAGEREF field. - final String PAGE_REF_FIELD_NAME = "PAGEREF"; - - // Create a new DocumentBuilder which is used to insert the bookmarks and replacement fields. - DocumentBuilder builder = new DocumentBuilder(doc); - // Defines the number of page restarts that have been encountered and therefore the number of "sub" documents - // found within this document. - int subDocumentCount = 0; - - // Iterate through all sections in the document. - for (Section section : doc.getSections()) { - // This section has it's page numbering restarted so we will treat this as the start of a sub document. - // Any PAGENUM fields in this inner document must be converted to special PAGEREF fields to correct numbering. - if (section.getPageSetup().getRestartPageNumbering()) { - // Don't do anything if this is the first section in the document. This part of the code will insert the bookmark marking - // the end of the previous sub document so therefore it is not applicable for first section in the document. - if (!section.equals(doc.getFirstSection())) { - // Get the previous section and the last node within the body of that section. - Section prevSection = (Section) section.getPreviousSibling(); - Node lastNode = prevSection.getBody().getLastChild(); - - // Use the DocumentBuilder to move to this node and insert the bookmark there. - // This bookmark represents the end of the sub document. - builder.moveTo(lastNode); - builder.startBookmark(BOOKMARK_PREFIX + subDocumentCount); - builder.endBookmark(BOOKMARK_PREFIX + subDocumentCount); - - // Increase the subdocument count to insert the correct bookmarks. - subDocumentCount++; - } - } - - // The last section simply needs the ending bookmark to signal that it is the end of the current sub document. - if (section.equals(doc.getLastSection())) { - // Insert the bookmark at the end of the body of the last section. - // Don't increase the count this time as we are just marking the end of the document. - Node lastNode = doc.getLastSection().getBody().getLastChild(); - builder.moveTo(lastNode); - builder.startBookmark(BOOKMARK_PREFIX + subDocumentCount); - builder.endBookmark(BOOKMARK_PREFIX + subDocumentCount); - } - - // Iterate through each NUMPAGES field in the section and replace the field with a PAGEREF field referring to the bookmark of the current subdocument - // This bookmark is positioned at the end of the sub document but does not exist yet. It is inserted when a section with restart page numbering or the last - // section is encountered. - for (Node node : section.getChildNodes(NodeType.FIELD_START, true).toArray()) { - FieldStart fieldStart = (FieldStart) node; - - if (fieldStart.getFieldType() == FieldType.FIELD_NUM_PAGES) { - // Get the field code. - String fieldCode = getFieldCode(fieldStart); - // Since the NUMPAGES field does not take any additional parameters we can assume the remaining part of the field - // code after the fieldname are the switches. We will use these to help recreate the NUMPAGES field as a PAGEREF field. - String fieldSwitches = fieldCode.replace(NUM_PAGES_FIELD_NAME, "").trim(); - - // Inserting the new field directly at the FieldStart node of the original field will cause the new field to - // not pick up the formatting of the original field. To counter this insert the field just before the original field - Node previousNode = fieldStart.getPreviousSibling(); - - // If a previous run cannot be found then we are forced to use the FieldStart node. - if (previousNode == null) - previousNode = fieldStart; - - // Insert a PAGEREF field at the same position as the field. - builder.moveTo(previousNode); - // This will insert a new field with a code like " PAGEREF _SubDocumentEnd0 *\MERGEFORMAT ". - Field newField = builder.insertField(MessageFormat.format(" {0} {1}{2} {3} ", PAGE_REF_FIELD_NAME, BOOKMARK_PREFIX, subDocumentCount, fieldSwitches)); - - // The field will be inserted before the referenced node. Move the node before the field instead. - previousNode.getParentNode().insertBefore(previousNode, newField.getStart()); - - // Remove the original NUMPAGES field from the document. - removeField(fieldStart); - } - } - } - } - - /** - * Retrieves the field code from a field. - * - * @param fieldStart The field start of the field which to gather the field code from. - */ - - - /** - * Removes the Field from the document. - * - * @param fieldStart The field start node of the field to remove. - */ - - - private static void removeField(FieldStart fieldStart) throws Exception { - Node currentNode = fieldStart; - boolean isRemoving = true; - while (currentNode != null && isRemoving) { - if (currentNode.getNodeType() == NodeType.FIELD_END) - isRemoving = false; - - Node nextNode = currentNode.nextPreOrder(currentNode.getDocument()); - currentNode.remove(); - currentNode = nextNode; - } - } - - private static String getFieldCode(FieldStart fieldStart) throws Exception { - StringBuilder builder = new StringBuilder(); - - for (Node node = fieldStart; node != null && node.getNodeType() != NodeType.FIELD_SEPARATOR && - node.getNodeType() != NodeType.FIELD_END; node = node.nextPreOrder(node.getDocument())) { - // Use text only of Run nodes to avoid duplication. - if (node.getNodeType() == NodeType.RUN) - builder.append(node.getText()); - } - return builder.toString(); - } - - -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/JoinContinuous.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/JoinContinuous.java deleted file mode 100644 index 13d5434a..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/JoinContinuous.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.aspose.words.examples.programming_documents.joining_appending; - -import com.aspose.words.Document; -import com.aspose.words.ImportFormatMode; -import com.aspose.words.SectionStart; -import com.aspose.words.examples.Utils; - - -public class JoinContinuous { - private static String gDataDir; - - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - gDataDir = Utils.getDataDir(JoinContinuous.class); - - Document dstDoc = new Document(gDataDir + "TestFile.Destination.doc"); - Document srcDoc = new Document(gDataDir + "TestFile.Source.doc"); - - // Make the document appear straight after the destination documents content. - srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.CONTINUOUS); - - // Append the source document using the original styles found in the source document. - dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - dstDoc.save(gDataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/JoinNewPage.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/JoinNewPage.java deleted file mode 100644 index a96fec07..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/JoinNewPage.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.aspose.words.examples.programming_documents.joining_appending; - -import com.aspose.words.Document; -import com.aspose.words.ImportFormatMode; -import com.aspose.words.SectionStart; -import com.aspose.words.examples.Utils; - - -public class JoinNewPage { - - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(JoinNewPage.class); - - Document dstDoc = new Document(dataDir + "TestFile.Destination.doc"); - Document srcDoc = new Document(dataDir + "TestFile.Source.doc"); - - // Set the appended document to start on a new page. - srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.NEW_PAGE); - - // Append the source document using the original styles found in the source document. - dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - dstDoc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceFormatting.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceFormatting.java deleted file mode 100644 index fbeb88a9..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceFormatting.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.aspose.words.examples.programming_documents.joining_appending; - -import com.aspose.words.Document; -import com.aspose.words.ImportFormatMode; -import com.aspose.words.examples.Utils; - - -public class KeepSourceFormatting { - - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(KeepSourceFormatting.class); - - Document dstDoc = new Document(dataDir + "TestFile.Destination.doc"); - Document srcDoc = new Document(dataDir + "TestFile.Source.doc"); - - // Keep the formatting from the source document when appending it to the destination document. - dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - - // Save the joined document to disk. - dstDoc.save(dataDir + "output.docx"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceTogether.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceTogether.java deleted file mode 100644 index cba634d4..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceTogether.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.aspose.words.examples.programming_documents.joining_appending; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - - -public class KeepSourceTogether { - - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(KeepSourceTogether.class); - - Document dstDoc = new Document(dataDir + "TestFile.Destination.doc"); - Document srcDoc = new Document(dataDir + "TestFile.Source.doc"); - - // Set the source document to appear straight after the destination document's content. - srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.CONTINUOUS); - - // Iterate through all sections in the source document. - for (Paragraph para : (Iterable) srcDoc.getChildNodes(NodeType.PARAGRAPH, true)) { - para.getParagraphFormat().setKeepWithNext(true); - } - - dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - dstDoc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/LinkHeadersFooters.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/LinkHeadersFooters.java deleted file mode 100644 index 82172537..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/LinkHeadersFooters.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.aspose.words.examples.programming_documents.joining_appending; - -import com.aspose.words.Document; -import com.aspose.words.ImportFormatMode; -import com.aspose.words.SectionStart; -import com.aspose.words.examples.Utils; - - -public class LinkHeadersFooters { - - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(LinkHeadersFooters.class); - - Document dstDoc = new Document(dataDir + "TestFile.Destination.doc"); - Document srcDoc = new Document(dataDir + "TestFile.Source.doc"); - - // Set the appended document to appear on a new page. - srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.NEW_PAGE); - - // Link the headers and footers in the source document to the previous section. - // This will override any headers or footers already found in the source document. - srcDoc.getFirstSection().getHeadersFooters().linkToPrevious(true); - - dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - dstDoc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/ListKeepSourceFormatting.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/ListKeepSourceFormatting.java deleted file mode 100644 index 2478f584..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/ListKeepSourceFormatting.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.aspose.words.examples.programming_documents.joining_appending; - -import com.aspose.words.Document; -import com.aspose.words.ImportFormatMode; -import com.aspose.words.SectionStart; -import com.aspose.words.examples.Utils; - - -public class ListKeepSourceFormatting { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ListKeepSourceFormatting.class); - - Document dstDoc = new Document(dataDir + "TestFile.DestinationList.doc"); - Document srcDoc = new Document(dataDir + "TestFile.SourceList.doc"); - - // Append the content of the document so it flows continuously. - srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.CONTINUOUS); - - dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - dstDoc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/ListUseDestinationStyles.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/ListUseDestinationStyles.java deleted file mode 100644 index ea0815c4..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/ListUseDestinationStyles.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.aspose.words.examples.programming_documents.joining_appending; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.util.HashMap; - - -public class ListUseDestinationStyles { - - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(ListUseDestinationStyles.class); - - Document dstDoc = new Document(dataDir + "TestFile.DestinationList.doc"); - Document srcDoc = new Document(dataDir + "TestFile.SourceList.doc"); - - // Set the source document to continue straight after the end of the destination document. - srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.CONTINUOUS); - - // Keep track of the lists that are created. - HashMap newLists = new HashMap(); - - // Iterate through all paragraphs in the document. - for (Paragraph para : (Iterable) srcDoc.getChildNodes(NodeType.PARAGRAPH, true)) { - if (para.isListItem()) { - int listId = para.getListFormat().getList().getListId(); - - // Check if the destination document contains a list with this ID already. If it does then this may - // cause the two lists to run together. Create a copy of the list in the source document instead. - if (dstDoc.getLists().getListByListId(listId) != null) { - List currentList; - // A newly copied list already exists for this ID, retrieve the stored list and use it on - // the current paragraph. - if (newLists.containsKey(listId)) { - currentList = (List) newLists.get(listId); - } else { - // Add a copy of this list to the document and store it for later reference. - currentList = srcDoc.getLists().addCopy(para.getListFormat().getList()); - newLists.put(listId, currentList); - } - - // Set the list of this paragraph to the copied list. - para.getListFormat().setList(currentList); - } - } - } - - // Append the source document to end of the destination document. - dstDoc.appendDocument(srcDoc, ImportFormatMode.USE_DESTINATION_STYLES); - - // Save the combined document to disk. - dstDoc.save(dataDir + "output.docx"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/RemoveSourceHeadersFooters.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/RemoveSourceHeadersFooters.java deleted file mode 100644 index c019c7fa..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/RemoveSourceHeadersFooters.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.aspose.words.examples.programming_documents.joining_appending; - -import com.aspose.words.Document; -import com.aspose.words.ImportFormatMode; -import com.aspose.words.Section; -import com.aspose.words.examples.Utils; - - -public class RemoveSourceHeadersFooters { - - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(RemoveSourceHeadersFooters.class); - - Document dstDoc = new Document(dataDir + "TestFile.Destination.doc"); - Document srcDoc = new Document(dataDir + "TestFile.Source.doc"); - - // Remove the headers and footers from each of the sections in the source document. - for (Section section : srcDoc.getSections()) { - section.clearHeadersFooters(); - } - - // Even after the headers and footers are cleared from the source document, the "LinkToPrevious" setting - // for HeadersFooters can still be set. This will cause the headers and footers to continue from the destination - // document. This should set to false to avoid this behaviour. - srcDoc.getFirstSection().getHeadersFooters().linkToPrevious(false); - - dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - dstDoc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/RestartPageNumbering.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/RestartPageNumbering.java deleted file mode 100644 index 6888440f..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/RestartPageNumbering.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.aspose.words.examples.programming_documents.joining_appending; - -import com.aspose.words.Document; -import com.aspose.words.ImportFormatMode; -import com.aspose.words.SectionStart; -import com.aspose.words.examples.Utils; - - -public class RestartPageNumbering { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(RestartPageNumbering.class); - - Document dstDoc = new Document(dataDir + "TestFile.Destination.doc"); - Document srcDoc = new Document(dataDir + "TestFile.Source.doc"); - - // Set the appended document to appear on the next page. - srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.NEW_PAGE); - // Restart the page numbering for the document to be appended. - srcDoc.getFirstSection().getPageSetup().setRestartPageNumbering(true); - - dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - dstDoc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/SimpleAppendDocument.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/SimpleAppendDocument.java deleted file mode 100644 index c4a4c2e2..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/SimpleAppendDocument.java +++ /dev/null @@ -1,33 +0,0 @@ - -package com.aspose.words.examples.programming_documents.joining_appending; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; - - -public class SimpleAppendDocument -{ - private static String gDataDir; - - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - gDataDir = Utils.getDataDir(SimpleAppendDocument.class); - - Document dstDoc = new Document(gDataDir + "TestFile.Destination.doc"); - Document srcDoc = new Document(gDataDir + "TestFile.Source.doc"); - - dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - - dstDoc.save(gDataDir + "TestFile.SimpleAppendDocument Out.docx"); - - System.out.println("Documents appended successfully."); - } - -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/UnlinkHeadersFooters.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/UnlinkHeadersFooters.java deleted file mode 100644 index e0f0652d..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/UnlinkHeadersFooters.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.aspose.words.examples.programming_documents.joining_appending; - -import com.aspose.words.Document; -import com.aspose.words.ImportFormatMode; -import com.aspose.words.examples.Utils; - - -public class UnlinkHeadersFooters { - - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(UnlinkHeadersFooters.class); - - Document dstDoc = new Document(dataDir + "TestFile.Destination.doc"); - Document srcDoc = new Document(dataDir + "TestFile.Source.doc"); - - // Even a document with no headers or footers can still have the LinkToPrevious setting set to true. - // Unlink the headers and footers in the source document to stop this from continuing the headers and footers - // from the destination document. - srcDoc.getFirstSection().getHeadersFooters().linkToPrevious(false); - - dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - dstDoc.save(dataDir + "output.doc"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/UpdatePageLayout.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/UpdatePageLayout.java deleted file mode 100644 index 35cf302c..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/UpdatePageLayout.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.aspose.words.examples.programming_documents.joining_appending; - -import com.aspose.words.Document; -import com.aspose.words.ImportFormatMode; -import com.aspose.words.examples.Utils; - - -public class UpdatePageLayout { - - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(UpdatePageLayout.class); - - Document dstDoc = new Document(dataDir + "TestFile.Destination.doc"); - Document srcDoc = new Document(dataDir + "TestFile.Source.doc"); - - // If the destination document is rendered to PDF, image etc or UpdatePageLayout is called before the source document - // is appended then any changes made after will not be reflected in the rendered output. - dstDoc.updatePageLayout(); - - // Join the documents. - dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - - // For the changes to be updated to rendered output, UpdatePageLayout must be called again. - // If not called again the appended document will not appear in the output of the next rendering. - dstDoc.updatePageLayout(); - - // Save the joined document to PDF. - dstDoc.save(dataDir + "output.pdf"); - - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/UseDestinationStyles.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/UseDestinationStyles.java deleted file mode 100644 index 3710f549..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/joining_appending/UseDestinationStyles.java +++ /dev/null @@ -1,36 +0,0 @@ - -package com.aspose.words.examples.programming_documents.joining_appending; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; - - -public class UseDestinationStyles -{ - private static String gDataDir; - - public static void main(String[] args) throws Exception - { - - // The path to the documents directory. - gDataDir = Utils.getDataDir(UseDestinationStyles.class); - - Document dstDoc = new Document(gDataDir + "TestFile.Destination.doc"); - Document srcDoc = new Document(gDataDir + "TestFile.Source.doc"); - - // Append the source document using the styles of the destination document. - dstDoc.appendDocument(srcDoc, ImportFormatMode.USE_DESTINATION_STYLES); - - // Save the joined document to disk. - dstDoc.save(gDataDir + "TestFile.UseDestinationStyles Out.doc"); - - - System.out.println("Documents appended successfully."); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/AddSection.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/AddSection.java deleted file mode 100644 index f59c2550..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/AddSection.java +++ /dev/null @@ -1,19 +0,0 @@ - -package com.aspose.words.examples.programming_documents.sections; - -import com.aspose.words.Document; -import com.aspose.words.Section; -import com.aspose.words.examples.Utils; - -public class AddSection -{ - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(SectionsAccessByIndex.class); - Document doc = new Document(dataDir + "Document.doc"); - Section sectionToAdd = new Section(doc); - doc.getSections().add(sectionToAdd); - - System.out.println("Section added successfully to the end of the document."); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/AppendSectionContent.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/AppendSectionContent.java deleted file mode 100644 index 32902916..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/AppendSectionContent.java +++ /dev/null @@ -1,26 +0,0 @@ - -package com.aspose.words.examples.programming_documents.sections; - -import com.aspose.words.Document; -import com.aspose.words.Section; -import com.aspose.words.examples.Utils; - -public class AppendSectionContent -{ - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(SectionsAccessByIndex.class); - Document doc = new Document(dataDir + "Section.AppendContent.doc"); - // This is the section that we will append and prepend to. - Section section = doc.getSections().get(2); - - // This copies content of the 1st section and inserts it at the beginning of the specified section. - Section sectionToPrepend = doc.getSections().get(0); - section.prependContent(sectionToPrepend); - - // This copies content of the 2nd section and inserts it at the end of the specified section. - Section sectionToAppend = doc.getSections().get(1); - section.appendContent(sectionToAppend); - System.out.println("Section content appended successfully."); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/CloneSection.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/CloneSection.java deleted file mode 100644 index 79e5994c..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/CloneSection.java +++ /dev/null @@ -1,17 +0,0 @@ - -package com.aspose.words.examples.programming_documents.sections; - -import com.aspose.words.Document; -import com.aspose.words.Section; -import com.aspose.words.examples.Utils; - -public class CloneSection { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(SectionsAccessByIndex.class); - Document doc = new Document(dataDir + "Document.doc"); - Section cloneSection = doc.getSections().get(0).deepClone(); - System.out.println("0 index section clone successfully."); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/CopySection.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/CopySection.java deleted file mode 100644 index 7edfcd89..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/CopySection.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.aspose.words.examples.programming_documents.sections; - -import com.aspose.words.Document; -import com.aspose.words.Section; -import com.aspose.words.examples.Utils; - -public class CopySection { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(SectionsAccessByIndex.class); - Document srcDoc = new Document(dataDir + "Document.doc"); - Document dstDoc = new Document(); - - Section sourceSection = srcDoc.getSections().get(0); - Section newSection = (Section)dstDoc.importNode(sourceSection, true); - dstDoc.getSections().add(newSection); - - dstDoc.save(dataDir+ "output.doc"); - System.out.println("\nSection copied successfully.\nFile saved at " + dataDir); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/DeleteAllSections.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/DeleteAllSections.java deleted file mode 100644 index c8fca9e6..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/DeleteAllSections.java +++ /dev/null @@ -1,18 +0,0 @@ - -package com.aspose.words.examples.programming_documents.sections; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - -public class DeleteAllSections -{ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(DeleteAllSections.class); - Document doc = new Document(dataDir + "Document.doc"); - doc.getSections().clear(); - doc.save(dataDir +"output.doc"); - System.out.println("All sections deleted successfully form the document."); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/DeleteHeaderFooterContent.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/DeleteHeaderFooterContent.java deleted file mode 100644 index b0cd21af..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/DeleteHeaderFooterContent.java +++ /dev/null @@ -1,18 +0,0 @@ - -package com.aspose.words.examples.programming_documents.sections; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -public class DeleteHeaderFooterContent { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(SectionsAccessByIndex.class); - Document doc = new Document(dataDir + "Document.doc"); - Section section = doc.getSections().get(0); - section.clearHeadersFooters(); - - System.out.println("Header and footer content of 0 index deleted successfully."); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/DeleteSection.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/DeleteSection.java deleted file mode 100644 index 850290dd..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/DeleteSection.java +++ /dev/null @@ -1,17 +0,0 @@ - -package com.aspose.words.examples.programming_documents.sections; - -import com.aspose.words.Document; -import com.aspose.words.Section; -import com.aspose.words.examples.Utils; - -public class DeleteSection { - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(SectionsAccessByIndex.class); - Document doc = new Document(dataDir + "Document.doc"); - doc.getSections().removeAt(0); - - System.out.println("Section deleted successfully at 0 index."); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/DeleteSectionContent.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/DeleteSectionContent.java deleted file mode 100644 index 2cc19faa..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/DeleteSectionContent.java +++ /dev/null @@ -1,18 +0,0 @@ - -package com.aspose.words.examples.programming_documents.sections; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -public class DeleteSectionContent -{ - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(SectionsAccessByIndex.class); - Document doc = new Document(dataDir + "Document.doc"); - Section section = doc.getSections().get(0); - section.clearContent(); - System.out.println("Section content at 0 index deleted successfully."); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/RemoveAllSections.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/RemoveAllSections.java deleted file mode 100644 index ab28e6c3..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/RemoveAllSections.java +++ /dev/null @@ -1,17 +0,0 @@ - -package com.aspose.words.examples.programming_documents.sections; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - -public class RemoveAllSections -{ - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(SectionsAccessByIndex.class); - Document doc = new Document(dataDir + "Document.doc"); - doc.getSections().clear(); - - System.out.println("All sections removed successfully form the document."); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/SectionsAccessByIndex.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/SectionsAccessByIndex.java deleted file mode 100644 index f7db3221..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/sections/SectionsAccessByIndex.java +++ /dev/null @@ -1,23 +0,0 @@ - -package com.aspose.words.examples.programming_documents.sections; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; -import java.util.ArrayList; -public class SectionsAccessByIndex { - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(SectionsAccessByIndex.class); - Document doc = new Document(dataDir + "Document.doc"); - Section section = doc.getSections().get(0); - section.getPageSetup().setLeftMargin(90); // 3.17 cm - section.getPageSetup().setRightMargin(90); // 3.17 cm - section.getPageSetup().setTopMargin(72); // 2.54 cm - section.getPageSetup().setBottomMargin(72); // 2.54 cm - section.getPageSetup().setHeaderDistance (35.4); // 1.25 cm - section.getPageSetup().setFooterDistance (35.4); // 1.25 cm - section.getPageSetup().getTextColumns().setSpacing (35.4); // 1.25 cm - - System.out.println(section.getText()); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/styles/ExtractContentBasedOnStyles.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/styles/ExtractContentBasedOnStyles.java deleted file mode 100644 index 44754012..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/styles/ExtractContentBasedOnStyles.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.aspose.words.examples.programming_documents.styles; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; -import com.aspose.words.examples.programming_documents.tables.ApplyFormatting.ApplyBordersAndShading; -import java.util.ArrayList; - -/** - * Shows how to find paragraphs and runs formatted with a specific style. - */ -public class ExtractContentBasedOnStyles { - - private static final String dataDir = Utils.getSharedDataDir(ApplyBordersAndShading.class) + "Styles/"; - - public static void main(String[] args) throws Exception { - // Open the document. - Document doc = new Document(dataDir + "TestFile.doc"); - - // Define style names as they are specified in the Word document. - final String PARA_STYLE = "Heading 1"; - final String RUN_STYLE = "Intense Emphasis"; - - // Collect paragraphs with defined styles. - // Show the number of collected paragraphs and display the text of this paragraphs. - ArrayList paragraphs = paragraphsByStyleName(doc, PARA_STYLE); - System.out.println(java.text.MessageFormat.format("Paragraphs with \"{0}\" styles ({1}):", PARA_STYLE, paragraphs.size())); - for (Paragraph paragraph : paragraphs) - System.out.print(paragraph.toString(SaveFormat.TEXT)); - - // Collect runs with defined styles. - // Show the number of collected runs and display the text of this runs. - ArrayList runs = runsByStyleName(doc, RUN_STYLE); - System.out.println(java.text.MessageFormat.format("\nRuns with \"{0}\" styles ({1}):", RUN_STYLE, runs.size())); - for (Run run : runs) - System.out.println(run.getRange().getText()); - } - - public static ArrayList paragraphsByStyleName(Document doc, String styleName) throws Exception { - // Create an array to collect paragraphs of the specified style. - ArrayList paragraphsWithStyle = new ArrayList(); - // Get all paragraphs from the document. - NodeCollection paragraphs = doc.getChildNodes(NodeType.PARAGRAPH, true); - // Look through all paragraphs to find those with the specified style. - for (Paragraph paragraph : (Iterable) paragraphs) { - if (paragraph.getParagraphFormat().getStyle().getName().equals(styleName)) - paragraphsWithStyle.add(paragraph); - } - return paragraphsWithStyle; - } - - public static ArrayList runsByStyleName(Document doc, String styleName) throws Exception { - // Create an array to collect runs of the specified style. - ArrayList runsWithStyle = new ArrayList(); - // Get all runs from the document. - NodeCollection runs = doc.getChildNodes(NodeType.RUN, true); - // Look through all runs to find those with the specified style. - for (Run run : (Iterable) runs) { - if (run.getFont().getStyle().getName().equals(styleName)) - runsWithStyle.add(run); - } - return runsWithStyle; - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tableofcontents/FindAndInsertATCField.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tableofcontents/FindAndInsertATCField.java deleted file mode 100644 index 4a0a43a4..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tableofcontents/FindAndInsertATCField.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.aspose.words.examples.programming_documents.tableofcontents; - -import java.util.regex.Pattern; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.IReplacingCallback; -import com.aspose.words.ReplaceAction; -import com.aspose.words.ReplacingArgs; - -public class FindAndInsertATCField { - - public static void main(String[] args) throws Exception { - Document doc = new Document(); - - // Insert a TC field which displays "Chapter 1" just before the text "The Beginning" in the document. - doc.getRange().replace(Pattern.compile("The Beginning"), new InsertTCFieldHandler("Chapter 1", "\\l 1"), false); - } -} - -class InsertTCFieldHandler implements IReplacingCallback { - // Store the text and switches to be used for the TC fields. - private String mFieldText; - private String mFieldSwitches; - - /** - * The switches to use for each TC field. Can be an empty string or null. - */ - public InsertTCFieldHandler(String switches) throws Exception { - this(null, switches); - } - - /** - * The display text and the switches to use for each TC field. Display text - * Can be an empty string or null. - */ - public InsertTCFieldHandler(String text, String switches) throws Exception { - mFieldText = text; - mFieldSwitches = switches; - } - - public int replacing(ReplacingArgs args) throws Exception { - // Create a builder to insert the field. - DocumentBuilder builder = new DocumentBuilder((Document) args.getMatchNode().getDocument()); - // Move to the first node of the match. - builder.moveTo(args.getMatchNode()); - - // If the user specified text to be used in the field as display text then use that, otherwise use the - // match string as the display text. - String insertText; - - if (!(mFieldText == null || "".equals(mFieldText))) - insertText = mFieldText; - else - insertText = args.getMatch().group(); - - // Insert the TC field before this node using the specified string as the display text and user defined switches. - builder.insertField(java.text.MessageFormat.format("TC \"{0}\" {1}", insertText, mFieldSwitches)); - - // We have done what we want so skip replacement. - return ReplaceAction.SKIP; - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tableofcontents/InsertATableOfContentsField.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tableofcontents/InsertATableOfContentsField.java deleted file mode 100644 index 83d1e620..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tableofcontents/InsertATableOfContentsField.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.aspose.words.examples.programming_documents.tableofcontents; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; - -public class InsertATableOfContentsField { - - private static final String dataDir = Utils.getSharedDataDir(InsertATableOfContentsField.class) + "TableOfContents/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - // Insert a table of contents at the beginning of the document. - builder.insertTableOfContents("\\o \"1-3\" \\h \\z \\u"); - - // The newly inserted table of contents will be initially empty. - // It needs to be populated by updating the fields in the document. - - doc.updateFields(); - - doc.save(dataDir + "InsertATableOfContentsField_out.docx"); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tableofcontents/InsertATableOfContentsUsingHeadingStyles.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tableofcontents/InsertATableOfContentsUsingHeadingStyles.java deleted file mode 100644 index 93c0e569..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tableofcontents/InsertATableOfContentsUsingHeadingStyles.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.aspose.words.examples.programming_documents.tableofcontents; - -import com.aspose.words.BreakType; -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.StyleIdentifier; -import com.aspose.words.examples.Utils; - -public class InsertATableOfContentsUsingHeadingStyles { - - private static final String dataDir = Utils.getSharedDataDir(InsertATableOfContentsUsingHeadingStyles.class) + "TableOfContents/"; - - public static void main(String[] args) throws Exception { - - Document doc = new Document(); - - // Create a document builder to insert content with into document. - DocumentBuilder builder = new DocumentBuilder(doc); - - // Insert a table of contents at the beginning of the document. - builder.insertTableOfContents("\\o \"1-3\" \\h \\z \\u"); - - // Start the actual document content on the second page. - builder.insertBreak(BreakType.PAGE_BREAK); - - // Build a document with complex structure by applying different heading styles thus creating TOC entries. - builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); - - builder.writeln("Heading 1"); - - builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); - - builder.writeln("Heading 1.1"); - builder.writeln("Heading 1.2"); - - builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); - - builder.writeln("Heading 2"); - builder.writeln("Heading 3"); - - builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); - - builder.writeln("Heading 3.1"); - - builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_3); - - builder.writeln("Heading 3.1.1"); - builder.writeln("Heading 3.1.2"); - builder.writeln("Heading 3.1.3"); - - builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); - - builder.writeln("Heading 3.2"); - builder.writeln("Heading 3.3"); - - // Call the method below to update the TOC. - doc.updateFields(); - - doc.save(dataDir + "InsertATableOfContentsUsingHeadingStyles_out.docx"); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tableofcontents/InsertTCField.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tableofcontents/InsertTCField.java deleted file mode 100644 index dcbdfc5e..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tableofcontents/InsertTCField.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.aspose.words.examples.programming_documents.tableofcontents; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; - -public class InsertTCField { - - public static void main(String[] args) throws Exception { - Document doc = new Document(); - - // Create a document builder to insert content with. - DocumentBuilder builder = new DocumentBuilder(doc); - - // Insert a TC field at the current document builder position. - builder.insertField("TC \"Entry Text\" \\f t"); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tableofcontents/ModifyATableOfContents.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tableofcontents/ModifyATableOfContents.java deleted file mode 100644 index 56574703..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tableofcontents/ModifyATableOfContents.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.aspose.words.examples.programming_documents.tableofcontents; - -import com.aspose.words.Document; -import com.aspose.words.NodeType; -import com.aspose.words.Paragraph; -import com.aspose.words.StyleIdentifier; -import com.aspose.words.TabStop; -import com.aspose.words.examples.Utils; - -public class ModifyATableOfContents { - - private static final String dataDir = Utils.getSharedDataDir(ModifyATableOfContents.class) + "TableOfContents/"; - - public static void main(String[] args) throws Exception { - changeAFormattingPropertyUsedInFirstLevelTOCStyle(); - - modifyPositionOfRightTabStopInTOC(); - } - - public static void changeAFormattingPropertyUsedInFirstLevelTOCStyle() throws Exception { - Document doc = new Document(); - // Retrieve the style used for the first level of the TOC and change the formatting of the style. - doc.getStyles().getByStyleIdentifier(StyleIdentifier.TOC_1).getFont().setBold(true); - } - - public static void modifyPositionOfRightTabStopInTOC() throws Exception { - Document doc = new Document(dataDir + "Field.TableOfContents.doc"); - - // Iterate through all paragraphs in the document - for (Paragraph para : (Iterable) doc.getChildNodes(NodeType.PARAGRAPH, true)) { - // Check if this paragraph is formatted using the TOC result based styles. This is any style between TOC and TOC9. - if (para.getParagraphFormat().getStyle().getStyleIdentifier() >= StyleIdentifier.TOC_1 && para.getParagraphFormat().getStyle().getStyleIdentifier() <= StyleIdentifier.TOC_9) { - // Get the first tab used in this paragraph, this should be the tab used to align the page numbers. - TabStop tab = para.getParagraphFormat().getTabStops().get(0); - // Remove the old tab from the collection. - para.getParagraphFormat().getTabStops().removeByPosition(tab.getPosition()); - // Insert a new tab using the same properties but at a modified position. - // We could also change the separators used (dots) by passing a different Leader type - para.getParagraphFormat().getTabStops().add(tab.getPosition() - 50, tab.getAlignment(), tab.getLeader()); - } - } - - doc.save(dataDir + "Field.TableOfContentsTabStops_Out.doc"); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tableofcontents/RemoveATableOfContents.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tableofcontents/RemoveATableOfContents.java deleted file mode 100644 index d4f84691..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tableofcontents/RemoveATableOfContents.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.aspose.words.examples.programming_documents.tableofcontents; - -import java.util.ArrayList; - -import com.aspose.words.Document; -import com.aspose.words.FieldEnd; -import com.aspose.words.FieldStart; -import com.aspose.words.FieldType; -import com.aspose.words.Node; -import com.aspose.words.NodeType; -import com.aspose.words.examples.Utils; - -public class RemoveATableOfContents { - - private static final String dataDir = Utils.getSharedDataDir(RemoveATableOfContents.class) + "TableOfContents/"; - - public static void main(String[] args) throws Exception { - // Open a document which contains a TOC. - Document doc = new Document(dataDir + "Document.TableOfContents.doc"); - - // Remove the first table of contents from the document. - removeTableOfContents(doc, 0); - - // Save the output. - doc.save(dataDir + "Document.TableOfContentsRemoveToc_Out.doc"); - - } - - /** - * Removes the specified table of contents field from the document. - * - * @param doc - * The document to remove the field from. - * @param index - * The zero-based index of the TOC to remove. - */ - public static void removeTableOfContents(Document doc, int index) throws Exception { - // Store the FieldStart nodes of TOC fields in the document for quick access. - ArrayList fieldStarts = new ArrayList(); - // This is a list to store the nodes found inside the specified TOC. They will be removed - // at the end of this method. - ArrayList nodeList = new ArrayList(); - - for (FieldStart start : (Iterable) doc.getChildNodes(NodeType.FIELD_START, true)) { - if (start.getFieldType() == FieldType.FIELD_TOC) { - // Add all FieldStarts which are of type FieldTOC. - fieldStarts.add(start); - } - } - - // Ensure the TOC specified by the passed index exists. - if (index > fieldStarts.size() - 1) - throw new ArrayIndexOutOfBoundsException("TOC index is out of range"); - - boolean isRemoving = true; - // Get the FieldStart of the specified TOC. - Node currentNode = fieldStarts.get(index); - - while (isRemoving) { - // It is safer to store these nodes and delete them all at once later. - nodeList.add(currentNode); - currentNode = currentNode.nextPreOrder(doc); - - // Once we encounter a FieldEnd node of type FieldTOC then we know we are at the end - // of the current TOC and we can stop here. - if (currentNode.getNodeType() == NodeType.FIELD_END) { - FieldEnd fieldEnd = (FieldEnd) currentNode; - if (fieldEnd.getFieldType() == FieldType.FIELD_TOC) - isRemoving = false; - } - } - - // Remove all nodes found in the specified TOC. - for (Node node : nodeList) { - node.remove(); - } - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/ApplyBordersAndShading.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/ApplyBordersAndShading.java deleted file mode 100644 index 25faaa30..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/ApplyBordersAndShading.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.ApplyFormatting; - -import java.awt.Color; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.LineStyle; -import com.aspose.words.Table; -import com.aspose.words.examples.Utils; - -public class ApplyBordersAndShading { - - private static final String dataDir = Utils.getSharedDataDir(ApplyBordersAndShading.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - Table table = builder.startTable(); - builder.insertCell(); - - // Set the borders for the entire table. - table.setBorders(LineStyle.SINGLE, 2.0, Color.BLACK); - // Set the cell shading for this cell. - builder.getCellFormat().getShading().setBackgroundPatternColor(Color.RED); - builder.writeln("Cell #1"); - - builder.insertCell(); - // Specify a different cell shading for the second cell. - builder.getCellFormat().getShading().setBackgroundPatternColor(Color.GREEN); - builder.writeln("Cell #2"); - - // End this row. - builder.endRow(); - - // Clear the cell formatting from previous operations. - builder.getCellFormat().clearFormatting(); - - // Create the second row. - builder.insertCell(); - - // Create larger borders for the first cell of this row. This will be different - // compared to the borders set for the table. - builder.getCellFormat().getBorders().getLeft().setLineWidth(4.0); - builder.getCellFormat().getBorders().getRight().setLineWidth(4.0); - builder.getCellFormat().getBorders().getTop().setLineWidth(4.0); - builder.getCellFormat().getBorders().getBottom().setLineWidth(4.0); - builder.writeln("Cell #3"); - - builder.insertCell(); - // Clear the cell formatting from the previous cell. - builder.getCellFormat().clearFormatting(); - builder.writeln("Cell #4"); - - doc.save(dataDir + "Table.SetBordersAndShading Out.doc"); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/ApplyFormattingOnTheCellLevel.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/ApplyFormattingOnTheCellLevel.java deleted file mode 100644 index b94440c2..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/ApplyFormattingOnTheCellLevel.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.ApplyFormatting; - -import java.awt.Color; - -import com.aspose.words.Cell; -import com.aspose.words.Document; -import com.aspose.words.NodeType; -import com.aspose.words.Table; -import com.aspose.words.TextOrientation; -import com.aspose.words.examples.Utils; - -public class ApplyFormattingOnTheCellLevel { - - private static final String dataDir = Utils.getSharedDataDir(ApplyFormattingOnTheCellLevel.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(dataDir + "Table.Document.doc"); - Table table = (Table)doc.getChild(NodeType.TABLE, 0, true); - - // Retrieve the first cell in the table. - Cell firstCell = table.getFirstRow().getFirstCell(); - - // Modify some row level properties. - firstCell.getCellFormat().setWidth(30); // in points - firstCell.getCellFormat().setOrientation(TextOrientation.DOWNWARD); - firstCell.getCellFormat().getShading().setForegroundPatternColor(Color.GREEN); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/ApplyFormattingOnTheRowLevel.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/ApplyFormattingOnTheRowLevel.java deleted file mode 100644 index 3e95f688..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/ApplyFormattingOnTheRowLevel.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.ApplyFormatting; - -import com.aspose.words.Document; -import com.aspose.words.HeightRule; -import com.aspose.words.LineStyle; -import com.aspose.words.NodeType; -import com.aspose.words.Row; -import com.aspose.words.Table; -import com.aspose.words.examples.Utils; - -public class ApplyFormattingOnTheRowLevel { - - private static final String dataDir = Utils.getSharedDataDir(ApplyFormattingOnTheRowLevel.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(dataDir + "Table.Document.doc"); - Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); - - // Retrieve the first row in the table. - Row firstRow = table.getFirstRow(); - - // Modify some row level properties. - firstRow.getRowFormat().getBorders().setLineStyle(LineStyle.NONE); - firstRow.getRowFormat().setHeightRule(HeightRule.AUTO); - firstRow.getRowFormat().setAllowBreakAcrossPages(true); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/ApplyFormattingOnTheTableLevel.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/ApplyFormattingOnTheTableLevel.java deleted file mode 100644 index 54ecd7e2..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/ApplyFormattingOnTheTableLevel.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.ApplyFormatting; - -import java.awt.Color; - -import com.aspose.words.BorderType; -import com.aspose.words.Document; -import com.aspose.words.LineStyle; -import com.aspose.words.NodeType; -import com.aspose.words.Table; -import com.aspose.words.TableAlignment; -import com.aspose.words.TextureIndex; -import com.aspose.words.examples.Utils; - -public class ApplyFormattingOnTheTableLevel { - - private static final String dataDir = Utils.getSharedDataDir(ApplyFormattingOnTheTableLevel.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - // Apply a outline border to a table - applyOutlineBorderToATable(); - - // Build a table with all borders enabled (grid) - buildATableWithAllBordersEnabled(); - } - - public static void applyOutlineBorderToATable() throws Exception { - Document doc = new Document(dataDir + "Table.EmptyTable.doc"); - Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); - - // Align the table to the center of the page. - table.setAlignment(TableAlignment.CENTER); - - // Clear any existing borders from the table. - table.clearBorders(); - - // Set a green border around the table but not inside. - table.setBorder(BorderType.LEFT, LineStyle.SINGLE, 1.5, Color.GREEN, true); - table.setBorder(BorderType.RIGHT, LineStyle.SINGLE, 1.5, Color.GREEN, true); - table.setBorder(BorderType.TOP, LineStyle.SINGLE, 1.5, Color.GREEN, true); - table.setBorder(BorderType.BOTTOM, LineStyle.SINGLE, 1.5, Color.GREEN, true); - - // Fill the cells with a light green solid color. - table.setShading(TextureIndex.TEXTURE_SOLID, Color.GREEN, Color.GREEN); - - doc.save(dataDir + "Table.SetOutlineBorders_Out.doc"); - } - - public static void buildATableWithAllBordersEnabled() throws Exception { - Document doc = new Document(dataDir + "Table.EmptyTable.doc"); - Table table = (Table)doc.getChild(NodeType.TABLE, 0, true); - - // Clear any existing borders from the table. - table.clearBorders(); - - // Set a green border around and inside the table. - table.setBorders(LineStyle.SINGLE, 1.5, Color.GREEN); - - doc.save(dataDir + "Table.SetAllBorders Out.doc"); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/FindPreferredWidthTypeAndValueOfATableOrCell.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/FindPreferredWidthTypeAndValueOfATableOrCell.java deleted file mode 100644 index 35c26ce5..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/FindPreferredWidthTypeAndValueOfATableOrCell.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.ApplyFormatting; - -import java.awt.Color; - -import com.aspose.words.Cell; -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.PreferredWidth; -import com.aspose.words.Table; - -public class FindPreferredWidthTypeAndValueOfATableOrCell { - - public static void main(String[] args) throws Exception { - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - // Insert a table row made up of three cells which have different preferred widths. - Table table = builder.startTable(); - - // Insert an absolute sized cell. - builder.insertCell(); - builder.getCellFormat().setPreferredWidth(PreferredWidth.fromPoints(40)); - builder.getCellFormat().getShading().setBackgroundPatternColor(Color.RED); - builder.writeln("Cell at 40 points width"); - - // Insert a relative (percent) sized cell. - builder.insertCell(); - builder.getCellFormat().setPreferredWidth(PreferredWidth.fromPercent(20)); - builder.getCellFormat().getShading().setBackgroundPatternColor(Color.BLUE); - builder.writeln("Cell at 20% width"); - - // Insert a auto sized cell. - builder.insertCell(); - builder.getCellFormat().setPreferredWidth(PreferredWidth.AUTO); - builder.getCellFormat().getShading().setBackgroundPatternColor(Color.GREEN); - builder.writeln("Cell automatically sized. The size of this cell is calculated from the table preferred width."); - builder.writeln("In this case the cell will fill up the rest of the available space."); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/SpecifyAPreferredWidthOnATable.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/SpecifyAPreferredWidthOnATable.java deleted file mode 100644 index 76b17b48..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/SpecifyAPreferredWidthOnATable.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.ApplyFormatting; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.PreferredWidth; -import com.aspose.words.Table; -import com.aspose.words.examples.Utils; - -public class SpecifyAPreferredWidthOnATable { - - private static final String dataDir = Utils.getSharedDataDir(SpecifyAPreferredWidthOnATable.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - // Insert a table with a width that takes up half the page width. - Table table = builder.startTable(); - - // Insert a few cells - builder.insertCell(); - table.setPreferredWidth(PreferredWidth.fromPercent(50)); - builder.writeln("Cell #1"); - - builder.insertCell(); - builder.writeln("Cell #2"); - - builder.insertCell(); - builder.writeln("Cell #3"); - - doc.save(dataDir + "Table.PreferredWidth Out.doc"); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/SpecifyPreferredWidthOnACell.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/SpecifyPreferredWidthOnACell.java deleted file mode 100644 index 0ee58db0..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/SpecifyPreferredWidthOnACell.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.ApplyFormatting; - -import java.awt.Color; - -import com.aspose.words.Cell; -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.PreferredWidth; -import com.aspose.words.Table; -import com.aspose.words.examples.Utils; - -public class SpecifyPreferredWidthOnACell { - - private static final String dataDir = Utils.getSharedDataDir(SpecifyAPreferredWidthOnATable.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - // Insert a table row made up of three cells which have different preferred widths. - Table table = builder.startTable(); - - // Insert an absolute sized cell. - builder.insertCell(); - builder.getCellFormat().setPreferredWidth(PreferredWidth.fromPoints(40)); - builder.getCellFormat().getShading().setBackgroundPatternColor(Color.RED); - builder.writeln("Cell at 40 points width"); - - // Insert a relative (percent) sized cell. - builder.insertCell(); - builder.getCellFormat().setPreferredWidth(PreferredWidth.fromPercent(20)); - builder.getCellFormat().getShading().setBackgroundPatternColor(Color.BLUE); - builder.writeln("Cell at 20% width"); - - // Insert a auto sized cell. - builder.insertCell(); - builder.getCellFormat().setPreferredWidth(PreferredWidth.AUTO); - builder.getCellFormat().getShading().setBackgroundPatternColor(Color.GREEN); - builder.writeln("Cell automatically sized. The size of this cell is calculated from the table preferred width."); - builder.writeln("In this case the cell will fill up the rest of the available space."); - - doc.save(dataDir + "Table.PreferredWidths Out.doc"); - } - - public static void findPreferredWidthTypeAndValueOfATableOrCell(Table table) { - Cell firstCell = table.getFirstRow().getFirstCell(); - int type = firstCell.getCellFormat().getPreferredWidth().getType(); - double value = firstCell.getCellFormat().getPreferredWidth().getValue(); - } - - public static void allowAutoFit(Table table) throws Exception { - table.setAllowAutoFit(true); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/SpecifyRowHeights.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/SpecifyRowHeights.java deleted file mode 100644 index f282391d..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/SpecifyRowHeights.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.ApplyFormatting; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.HeightRule; -import com.aspose.words.RowFormat; -import com.aspose.words.Table; - -public class SpecifyRowHeights { - - public static void main(String[] args) throws Exception { - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - Table table = builder.startTable(); - builder.insertCell(); - - // Set the row formatting - RowFormat rowFormat = builder.getRowFormat(); - rowFormat.setHeight(100); - rowFormat.setHeightRule(HeightRule.EXACTLY); - // These formatting properties are set on the table and are applied to all rows in the table. - table.setLeftPadding(30); - table.setRightPadding(30); - table.setTopPadding(30); - table.setBottomPadding(30); - - builder.writeln("I'm a wonderful formatted row."); - - builder.endRow(); - builder.endTable(); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/TableStyles.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/TableStyles.java deleted file mode 100644 index 1beec149..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/TableStyles.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.ApplyFormatting; - -import java.awt.Color; - -import com.aspose.words.AutoFitBehavior; -import com.aspose.words.Cell; -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.NodeType; -import com.aspose.words.StyleIdentifier; -import com.aspose.words.Table; -import com.aspose.words.TableStyleOptions; -import com.aspose.words.examples.Utils; - -public class TableStyles { - - private static final String dataDir = Utils.getSharedDataDir(TableStyles.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - applyATableStyle(); - - expandFormattingFromStylesOnToRowsAndCells(); - } - - public static void applyATableStyle() throws Exception { - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - Table table = builder.startTable(); - // We must insert at least one row first before setting any table formatting. - builder.insertCell(); - // Set the table style used based of the unique style identifier. - // Note that not all table styles are available when saving as .doc format. - table.setStyleIdentifier(StyleIdentifier.MEDIUM_SHADING_1_ACCENT_1); - // Apply which features should be formatted by the style. - table.setStyleOptions(TableStyleOptions.FIRST_COLUMN | TableStyleOptions.ROW_BANDS | TableStyleOptions.FIRST_ROW); - table.autoFit(AutoFitBehavior.AUTO_FIT_TO_CONTENTS); - - // Continue with building the table as normal. - builder.writeln("Item"); - builder.getCellFormat().setRightPadding(40); - builder.insertCell(); - builder.writeln("Quantity (kg)"); - builder.endRow(); - - builder.insertCell(); - builder.writeln("Apples"); - builder.insertCell(); - builder.writeln("20"); - builder.endRow(); - - builder.insertCell(); - builder.writeln("Bananas"); - builder.insertCell(); - builder.writeln("40"); - builder.endRow(); - - builder.insertCell(); - builder.writeln("Carrots"); - builder.insertCell(); - builder.writeln("50"); - builder.endRow(); - - doc.save(dataDir + "DocumentBuilder.SetTableStyle Out.docx"); - } - - public static void expandFormattingFromStylesOnToRowsAndCells() throws Exception { - Document doc = new Document(dataDir + "Table.TableStyle.docx"); - - // Get the first cell of the first table in the document. - Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); - Cell firstCell = table.getFirstRow().getFirstCell(); - - // First print the color of the cell shading. This should be empty as the current shading - // is stored in the table style. - Color cellShadingBefore = firstCell.getCellFormat().getShading().getBackgroundPatternColor(); - System.out.println("Cell shading before style expansion: " + cellShadingBefore); - - // Expand table style formatting to direct formatting. - doc.expandTableStylesToDirectFormatting(); - - // Now print the cell shading after expanding table styles. A blue background pattern color - // should have been applied from the table style. - Color cellShadingAfter = firstCell.getCellFormat().getShading().getBackgroundPatternColor(); - System.out.println("Cell shading after style expansion: " + cellShadingAfter); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/ApplyAutoFitSettingsToATable.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/ApplyAutoFitSettingsToATable.java deleted file mode 100644 index bfeec76b..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/ApplyAutoFitSettingsToATable.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.ColumnsAndRows; - -import com.aspose.words.AutoFitBehavior; -import com.aspose.words.Document; -import com.aspose.words.NodeType; -import com.aspose.words.Table; -import com.aspose.words.examples.Utils; - -public class ApplyAutoFitSettingsToATable { - - private static final String dataDir = Utils.getSharedDataDir(ApplyAutoFitSettingsToATable.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - // Auto fits a table to fit the page width - autoFittingATableToWindow(); - - // Auto fits a table in the document to its contents - autoFittingATableToContents(); - - // Disabling AutoFitting on a Table and Use Fixed Column Widths - disablingAutoFittingOnATableAndUseFixedColumnWidths(); - } - - public static void autoFittingATableToWindow() throws Exception { - // Open the document - Document doc = new Document(dataDir + "TestFile.doc"); - Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); - - // Auto fit the first table to the page width. - table.autoFit(AutoFitBehavior.AUTO_FIT_TO_WINDOW); - - // Save the document to disk. - doc.save(dataDir + "TestFile.AutoFitToWindow Out.doc"); - } - - public static void autoFittingATableToContents() throws Exception { - // Open the document - Document doc = new Document(dataDir + "TestFile.doc"); - Table table = (Table)doc.getChild(NodeType.TABLE, 0, true); - - // Auto fit the table to the cell contents - table.autoFit(AutoFitBehavior.AUTO_FIT_TO_CONTENTS); - - // Save the document to disk. - doc.save(dataDir + "TestFile.AutoFitToContents Out.doc"); - } - - public static void disablingAutoFittingOnATableAndUseFixedColumnWidths() throws Exception { - // Open the document - Document doc = new Document(dataDir + "TestFile.doc"); - Table table = (Table)doc.getChild(NodeType.TABLE, 0, true); - - // Disable autofitting on this table. - table.autoFit(AutoFitBehavior.FIXED_COLUMN_WIDTHS); - - // Save the document to disk. - doc.save(dataDir + "TestFile.FixedWidth Out.doc"); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/CheckCellsMerged.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/CheckCellsMerged.java deleted file mode 100644 index 5a4f8e76..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/CheckCellsMerged.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.ColumnsAndRows; - -import com.aspose.words.Cell; -import com.aspose.words.CellMerge; -import com.aspose.words.Document; -import com.aspose.words.NodeType; -import com.aspose.words.Row; -import com.aspose.words.Table; -import com.aspose.words.examples.Utils; - -public class CheckCellsMerged { - - private static final String dataDir = Utils.getSharedDataDir(CheckCellsMerged.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(dataDir + "Table.MergedCells.doc"); - - // Retrieve the first table in the document. - Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); - - for (Row row : table.getRows()) { - for (Cell cell : row.getCells()) { - System.out.println(printCellMergeType(cell)); - } - } - } - - public static String printCellMergeType(Cell cell) { - boolean isHorizontallyMerged = cell.getCellFormat().getHorizontalMerge() != CellMerge.NONE; - boolean isVerticallyMerged = cell.getCellFormat().getVerticalMerge() != CellMerge.NONE; - String cellLocation = "R" + (cell.getParentRow().getParentTable().indexOf(cell.getParentRow()) + 1) + - ", C" + (cell.getParentRow().indexOf(cell) + 1); - - if (isHorizontallyMerged && isVerticallyMerged) - return "The cell at " + cellLocation + " is both horizontally and vertically merged"; - else if (isHorizontallyMerged) - return "The cell at " + cellLocation + " is horizontally merged."; - else if (isVerticallyMerged) - return "The cell at " + cellLocation + " is vertically merged"; - else - return "The cell at " + cellLocation + " is not merged"; - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/Column.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/Column.java deleted file mode 100644 index 6aa1ebaf..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/Column.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.ColumnsAndRows; - -import java.util.ArrayList; - -import com.aspose.words.Cell; -import com.aspose.words.Row; -import com.aspose.words.SaveFormat; -import com.aspose.words.Table; - -/** - * Represents a facade object for a column of a table in a Microsoft Word - * document. - */ -public class Column { - - private int mColumnIndex; - private Table mTable; - - private Column(Table table, int columnIndex) { - if (table == null) - throw new IllegalArgumentException("table"); - - mTable = table; - mColumnIndex = columnIndex; - } - - /** - * Returns a new column facade from the table and supplied zero-based index. - */ - public static Column fromIndex(Table table, int columnIndex) { - return new Column(table, columnIndex); - } - - /** - * Returns the cells which make up the column. - */ - public Cell[] getCells() { - ArrayList columnCells = getColumnCells(); - return columnCells.toArray(new Cell[columnCells.size()]); - } - - /** - * Returns the index of the given cell in the column. - */ - public int indexOf(Cell cell) { - return getColumnCells().indexOf(cell); - } - - /** - * Inserts a brand new column before this column into the table. - * @throws Exception - */ - public Column insertColumnBefore() throws Exception { - Cell[] columnCells = getCells(); - - if (columnCells.length == 0) - throw new IllegalArgumentException("Column must not be empty"); - - // Create a clone of this column. - for (Cell cell : columnCells) - cell.getParentRow().insertBefore(cell.deepClone(false), cell); - - // This is the new column. - Column column = new Column(columnCells[0].getParentRow().getParentTable(), mColumnIndex); - - // We want to make sure that the cells are all valid to work with (have at least one paragraph). - for (Cell cell : column.getCells()) - cell.ensureMinimum(); - - // Increase the index which this column represents since there is now one extra column infront. - mColumnIndex++; - - return column; - } - - /** - * Removes the column from the table. - */ - public void remove() { - for (Cell cell : getCells()) - cell.remove(); - } - - /** - * Returns the text of the column. - */ - public String toTxt() throws Exception { - StringBuilder builder = new StringBuilder(); - - for (Cell cell : getCells()) - builder.append(cell.toString(SaveFormat.TEXT)); - - return builder.toString(); - } - - /** - * Provides an up-to-date collection of cells which make up the column - * represented by this facade. - */ - private ArrayList getColumnCells() { - ArrayList columnCells = new ArrayList(); - - for (Row row : mTable.getRows()) { - Cell cell = row.getCells().get(mColumnIndex); - if (cell != null) - columnCells.add(cell); - } - - return columnCells; - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/FindIndexOfTableElements.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/FindIndexOfTableElements.java deleted file mode 100644 index 041b3299..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/FindIndexOfTableElements.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.ColumnsAndRows; - -import com.aspose.words.Cell; -import com.aspose.words.Document; -import com.aspose.words.NodeCollection; -import com.aspose.words.NodeType; -import com.aspose.words.Row; -import com.aspose.words.Table; -import com.aspose.words.examples.Utils; -import com.aspose.words.examples.programming_documents.tables.ExtractOrReplaceText.ExtractPlainTextFromATable; - -public class FindIndexOfTableElements { - - private static final String dataDir = Utils.getSharedDataDir(ExtractPlainTextFromATable.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(dataDir + "Table.SimpleTable.doc"); - Table table = (Table)doc.getChild(NodeType.TABLE, 0, true); - - findIndexOfTableInADocument(doc, table); - } - - public static void findIndexOfTableInADocument(Document doc, Table table) { - NodeCollection allTables = doc.getChildNodes(NodeType.TABLE, true); - int tableIndex = allTables.indexOf(table); - System.out.println("Table Index: " + tableIndex); - } - - public static void findIndexOfARowInATable(Table table, Row row) { - int rowIndex = table.indexOf(row); - System.out.println("Row Index: " + rowIndex); - } - - public static void findIndexOfACellInARow(Row row, Cell cell) { - int cellIndex = row.indexOf(cell); - System.out.println("Cell Index: " + cellIndex); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/JoinAndSplitTables.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/JoinAndSplitTables.java deleted file mode 100644 index 646f5c0d..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/JoinAndSplitTables.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.ColumnsAndRows; - -import com.aspose.words.Document; -import com.aspose.words.NodeType; -import com.aspose.words.Paragraph; -import com.aspose.words.Row; -import com.aspose.words.Table; -import com.aspose.words.examples.Utils; - -public class JoinAndSplitTables { - - private static final String dataDir = Utils.getSharedDataDir(JoinAndSplitTables.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - // Combine the rows from two tables into one - combineTwoTablesIntoOne(); - - // Split a Table into Two Separate Tables - splitATableIntoTwoSeparateTables(); - } - - public static void combineTwoTablesIntoOne() throws Exception { - // Load the document. - Document doc = new Document(dataDir + "Table.Document.doc"); - - // Get the first and second table in the document. - // The rows from the second table will be appended to the end of the first table. - Table firstTable = (Table) doc.getChild(NodeType.TABLE, 0, true); - Table secondTable = (Table) doc.getChild(NodeType.TABLE, 1, true); - - // Append all rows from the current table to the next. - // Due to the design of tables even tables with different cell count and widths can be joined into one table. - while (secondTable.hasChildNodes()) - firstTable.getRows().add(secondTable.getFirstRow()); - - // Remove the empty table container. - secondTable.remove(); - - doc.save(dataDir + "Table.CombineTables Out.doc"); - } - - public static void splitATableIntoTwoSeparateTables() throws Exception { - // Load the document. - Document doc = new Document(dataDir + "Table.SimpleTable.doc"); - - // Get the first table in the document. - Table firstTable = (Table) doc.getChild(NodeType.TABLE, 0, true); - - // We will split the table at the third row (inclusive). - Row row = firstTable.getRows().get(2); - - // Create a new container for the split table. - Table table = (Table) firstTable.deepClone(false); - - // Insert the container after the original. - firstTable.getParentNode().insertAfter(table, firstTable); - - // Add a buffer paragraph to ensure the tables stay apart. - firstTable.getParentNode().insertAfter(new Paragraph(doc), firstTable); - - Row currentRow; - - do { - currentRow = firstTable.getLastRow(); - table.prependChild(currentRow); - } while (currentRow != row); - - doc.save(dataDir + "Table.SplitTable Out.doc"); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/KeepTablesAndRowsFromBreakingAcrossPages.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/KeepTablesAndRowsFromBreakingAcrossPages.java deleted file mode 100644 index f97741c0..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/KeepTablesAndRowsFromBreakingAcrossPages.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.ColumnsAndRows; - -import com.aspose.words.Cell; -import com.aspose.words.Document; -import com.aspose.words.NodeType; -import com.aspose.words.Paragraph; -import com.aspose.words.Row; -import com.aspose.words.Table; -import com.aspose.words.examples.Utils; - -public class KeepTablesAndRowsFromBreakingAcrossPages { - - private static final String dataDir = Utils.getSharedDataDir(KeepTablesAndRowsFromBreakingAcrossPages.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - // Keeping a Row from Breaking across Pages - keepingARowFromBreakingAcrossPages(); - - // Keeping a Table from Breaking across Pages - keepingATableFromBreakingAcrossPages(); - } - - public static void keepingARowFromBreakingAcrossPages() throws Exception { - Document doc = new Document(dataDir + "Table.TableAcrossPage.doc"); - - // Retrieve the first table in the document. - Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); - - // Disable breaking across pages for all rows in the table. - for (Row row : table) { - row.getRowFormat().setAllowBreakAcrossPages(false); - } - - doc.save(dataDir + "Table.DisableBreakAcrossPages_out.doc"); - } - - @SuppressWarnings("unchecked") - public static void keepingATableFromBreakingAcrossPages() throws Exception { - Document doc = new Document(dataDir + "Table.TableAcrossPage.doc"); - // Retrieve the first table in the document. - Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); - - // To keep a table from breaking across a page we need to enable KeepWithNext - // for every paragraph in the table except for the last paragraphs in the last - // row of the table. - for (Cell cell : (Iterable) table.getChildNodes(NodeType.CELL, true)) { - // Call this method if table's cell is created on the fly - // newly created cell does not have paragraph inside - cell.ensureMinimum(); - for (Paragraph para : cell.getParagraphs()) - if (!(cell.getParentRow().isLastRow() && para.isEndOfCell())) - para.getParagraphFormat().setKeepWithNext(true); - } - - doc.save(dataDir + "Table.KeepTableTogether_out.doc"); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/MergeCellsInARange.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/MergeCellsInARange.java deleted file mode 100644 index a9b47748..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/MergeCellsInARange.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.ColumnsAndRows; - -import java.awt.Point; -import java.awt.Rectangle; - -import com.aspose.words.Cell; -import com.aspose.words.CellMerge; -import com.aspose.words.Document; -import com.aspose.words.NodeType; -import com.aspose.words.Row; -import com.aspose.words.Table; -import com.aspose.words.examples.Utils; - -public class MergeCellsInARange { - - private static final String dataDir = Utils.getSharedDataDir(MergeCellsInARange.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(dataDir + "Table.SimpleTable.doc"); - - // Retrieve the first table in the document. - Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); - - // We want to merge the range of cells found in between these two cells. - Cell cellStartRange = table.getRows().get(1).getCells().get(1); - Cell cellEndRange = table.getRows().get(2).getCells().get(2); - - // Merge all the cells between the two specified cells into one. - mergeCells(cellStartRange, cellEndRange); - - doc.save(dataDir + "Table.MergeCellsInARange Out.doc"); - } - - /** - * Merges the range of cells found between the two specified cells both - * horizontally and vertically. Can span over multiple rows. - */ - public static void mergeCells(Cell startCell, Cell endCell) { - Table parentTable = startCell.getParentRow().getParentTable(); - - // Find the row and cell indices for the start and end cell. - Point startCellPos = new Point(startCell.getParentRow().indexOf(startCell), parentTable.indexOf(startCell.getParentRow())); - Point endCellPos = new Point(endCell.getParentRow().indexOf(endCell), parentTable.indexOf(endCell.getParentRow())); - // Create the range of cells to be merged based off these indices. Inverse each index if the end cell if before the start cell. - Rectangle mergeRange = new Rectangle(Math.min(startCellPos.x, endCellPos.x), Math.min(startCellPos.y, endCellPos.y), Math.abs(endCellPos.x - startCellPos.x) + 1, - Math.abs(endCellPos.y - startCellPos.y) + 1); - - for (Row row : parentTable.getRows()) { - for (Cell cell : row.getCells()) { - Point currentPos = new Point(row.indexOf(cell), parentTable.indexOf(row)); - - // Check if the current cell is inside our merge range then merge it. - if (mergeRange.contains(currentPos)) { - if (currentPos.x == mergeRange.x) - cell.getCellFormat().setHorizontalMerge(CellMerge.FIRST); - else - cell.getCellFormat().setHorizontalMerge(CellMerge.PREVIOUS); - - if (currentPos.y == mergeRange.y) - cell.getCellFormat().setVerticalMerge(CellMerge.FIRST); - else - cell.getCellFormat().setVerticalMerge(CellMerge.PREVIOUS); - } - } - } - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/MergeCellsInATable.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/MergeCellsInATable.java deleted file mode 100644 index edd91064..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/MergeCellsInATable.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.ColumnsAndRows; - -import com.aspose.words.CellMerge; -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; - -public class MergeCellsInATable { - - public static void main(String[] args) { - - } - - public static void mergeCellsHorizontally() throws Exception { - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - builder.insertCell(); - builder.getCellFormat().setHorizontalMerge(CellMerge.FIRST); - builder.write("Text in merged cells."); - - builder.insertCell(); - // This cell is merged to the previous and should be empty. - builder.getCellFormat().setHorizontalMerge(CellMerge.PREVIOUS); - builder.endRow(); - - builder.insertCell(); - builder.getCellFormat().setHorizontalMerge(CellMerge.NONE); - builder.write("Text in one cell."); - - builder.insertCell(); - builder.write("Text in another cell."); - builder.endRow(); - builder.endTable(); - } - - public static void mergeCellsVertically() throws Exception { - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - builder.insertCell(); - builder.getCellFormat().setVerticalMerge(CellMerge.FIRST); - builder.write("Text in merged cells."); - - builder.insertCell(); - builder.getCellFormat().setVerticalMerge(CellMerge.NONE); - builder.write("Text in one cell"); - builder.endRow(); - - builder.insertCell(); - // This cell is vertically merged to the cell above and should be empty. - builder.getCellFormat().setVerticalMerge(CellMerge.PREVIOUS); - - builder.insertCell(); - builder.getCellFormat().setVerticalMerge(CellMerge.NONE); - builder.write("Text in another cell"); - builder.endRow(); - builder.endTable(); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/SpecifyRowsToRepeatOnSubsequentPagesAsHeaderRows.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/SpecifyRowsToRepeatOnSubsequentPagesAsHeaderRows.java deleted file mode 100644 index c7693319..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/SpecifyRowsToRepeatOnSubsequentPagesAsHeaderRows.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.ColumnsAndRows; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.ParagraphAlignment; -import com.aspose.words.Table; -import com.aspose.words.examples.Utils; - -public class SpecifyRowsToRepeatOnSubsequentPagesAsHeaderRows { - - private static final String dataDir = Utils.getSharedDataDir(SpecifyRowsToRepeatOnSubsequentPagesAsHeaderRows.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - Table table = builder.startTable(); - - builder.getRowFormat().setHeadingFormat(true); - builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); - builder.getCellFormat().setWidth(100); - builder.insertCell(); - builder.writeln("Heading row 1"); - builder.endRow(); - builder.insertCell(); - builder.writeln("Heading row 2"); - builder.endRow(); - - builder.getCellFormat().setWidth(50); - builder.getParagraphFormat().clearFormatting(); - - // Insert some content so the table is long enough to continue onto the next page. - for (int i = 0; i < 50; i++) { - builder.insertCell(); - builder.getRowFormat().setHeadingFormat(false); - builder.write("Column 1 Text"); - builder.insertCell(); - builder.write("Column 2 Text"); - builder.endRow(); - } - - doc.save(dataDir + "Table.HeadingRow Out.doc"); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/WorkingWithColumns.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/WorkingWithColumns.java deleted file mode 100644 index 14638495..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ColumnsAndRows/WorkingWithColumns.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.ColumnsAndRows; - -import com.aspose.words.Cell; -import com.aspose.words.Document; -import com.aspose.words.NodeType; -import com.aspose.words.Run; -import com.aspose.words.Table; -import com.aspose.words.examples.Utils; - -public class WorkingWithColumns { - - private static final String dataDir = Utils.getSharedDataDir(WorkingWithColumns.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(dataDir + "Table.Document.doc"); - Table table = (Table)doc.getChild(NodeType.TABLE, 1, true); - - // Insert a blank column into a table - insertABlankColumnIntoATable(doc, table); - - // Get the plain text of a table column - getTextOfATableColumn(table); - - //Remove a column from a table in a document - removeAColumnFromATable(); - } - - public static void insertABlankColumnIntoATable(Document doc, Table table) throws Exception { - // Get the second column in the table. - Column column = Column.fromIndex(table, 1); - - // Create a new column to the left of this column. - // This is the same as using the "Insert Column Before" command in Microsoft Word. - Column newColumn = column.insertColumnBefore(); - - // Add some text to each of the column cells. - for (Cell cell : newColumn.getCells()) { - cell.getFirstParagraph().appendChild(new Run(doc, "Column Text " + newColumn.indexOf(cell))); - } - } - - public static void getTextOfATableColumn(Table table) throws Exception { - // Get the first column in the table. - Column column = Column.fromIndex(table, 0); - - // Print the plain text of the column to the screen. - System.out.println(column.toTxt()); - } - - public static void removeAColumnFromATable() throws Exception { - Document doc = new Document(dataDir + "Table.Document.doc"); - Table table = (Table)doc.getChild(NodeType.TABLE, 1, true); - - // Get the third column from the table and remove it. - Column column = Column.fromIndex(table, 2); - column.remove(); - - doc.save(dataDir + "Table.RemoveColumn Out.doc"); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ExtractOrReplaceText/ExtractPlainTextFromATable.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ExtractOrReplaceText/ExtractPlainTextFromATable.java deleted file mode 100644 index 851f8823..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ExtractOrReplaceText/ExtractPlainTextFromATable.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.ExtractOrReplaceText; - -import com.aspose.words.Document; -import com.aspose.words.NodeType; -import com.aspose.words.Table; -import com.aspose.words.examples.Utils; - -public class ExtractPlainTextFromATable { - - private static final String dataDir = Utils.getSharedDataDir(ExtractPlainTextFromATable.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - // Print the text range of a table - printTextRangeOfATable(); - // Print the text range of row and table elements - printTextRangeOfRowAndTableElements(); - } - - public static void printTextRangeOfATable() throws Exception { - Document doc = new Document(dataDir + "Table.SimpleTable.doc"); - - // Get the first table in the document. - Table table = (Table)doc.getChild(NodeType.TABLE, 0, true); - - // The range text will include control characters such as "\a" for a cell. - // You can call ToTxt() on the desired node to find the plain text. - - // Print the plain text range of the table to the screen. - System.out.println("Contents of the table: "); - System.out.println(table.getRange().getText()); - } - - public static void printTextRangeOfRowAndTableElements() throws Exception { - Document doc = new Document(dataDir + "Table.SimpleTable.doc"); - - // Get the first table in the document. - Table table = (Table)doc.getChild(NodeType.TABLE, 0, true); - - // Print the contents of the first row to the screen. - System.out.println("\nContents of the row: "); - System.out.println(table.getFirstRow().getRange().getText()); - - // Print the contents of the last cell in the table to the screen. - System.out.println("\nContents of the cell: "); - System.out.println(table.getLastRow().getLastCell().getRange().getText()); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ExtractOrReplaceText/ReplaceText.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ExtractOrReplaceText/ReplaceText.java deleted file mode 100644 index 6b8c9d01..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/ExtractOrReplaceText/ReplaceText.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.ExtractOrReplaceText; - -import com.aspose.words.Document; -import com.aspose.words.NodeType; -import com.aspose.words.Table; -import com.aspose.words.examples.Utils; - -public class ReplaceText { - - private static final String dataDir = Utils.getSharedDataDir(ReplaceText.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(dataDir + "Table.SimpleTable.doc"); - - // Get the first table in the document. - Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); - - // Replace any instances of our string in the entire table. - table.getRange().replace("Carrots", "Eggs", true, true); - // Replace any instances of our string in the last cell of the table only. - table.getLastRow().getLastCell().getRange().replace("50", "20", true, true); - - doc.save(dataDir + "Table.ReplaceCellText Out.docx"); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/creation/BuildTableFromDataTable.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/creation/BuildTableFromDataTable.java deleted file mode 100644 index eedb0ea4..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/creation/BuildTableFromDataTable.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.creation; - -import java.sql.ResultSetMetaData; -import java.sql.Timestamp; -import java.text.SimpleDateFormat; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.Orientation; -import com.aspose.words.ParagraphAlignment; -import com.aspose.words.StyleIdentifier; -import com.aspose.words.Table; -import com.aspose.words.TableStyleOptions; -import com.aspose.words.examples.Utils; -import com.aspose.words.net.System.Data.DataTable; - -public class BuildTableFromDataTable { - - private static final String dataDir = Utils.getSharedDataDir(BuildTableFromDataTable.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - // Create a new document. - Document doc = new Document(); - - // We can position where we want the table to be inserted and also specify any extra formatting to be - // applied onto the table as well. - DocumentBuilder builder = new DocumentBuilder(doc); - - // We want to rotate the page landscape as we expect a wide table. - doc.getFirstSection().getPageSetup().setOrientation(Orientation.LANDSCAPE); - - // Retrieve the data from our data source which is stored as a DataTable. - DataTable dataTable = null; //getEmployees(databaseDir); - - // Build a table in the document from the data contained in the DataTable. - Table table = importTableFromDataTable(builder, dataTable, true); - - // We can apply a table style as a very quick way to apply formatting to the entire table. - table.setStyleIdentifier(StyleIdentifier.MEDIUM_LIST_2_ACCENT_1); - table.setStyleOptions(TableStyleOptions.FIRST_ROW | TableStyleOptions.ROW_BANDS | TableStyleOptions.LAST_COLUMN); - - // For our table we want to remove the heading for the image column. - table.getFirstRow().getLastCell().removeAllChildren(); - - doc.save(dataDir + "Table.FromDataTable_Out.docx"); - } - - /* - * Imports the content from the specified DataTable into a new Aspose.Words - * Table object. The table is inserted at the current position of the - * document builder and using the current builder's formatting if any is - * defined. - */ - public static Table importTableFromDataTable(DocumentBuilder builder, DataTable dataTable, boolean importColumnHeadings) throws Exception { - Table table = builder.startTable(); - - ResultSetMetaData metaData = dataTable.getResultSet().getMetaData(); - int numColumns = metaData.getColumnCount(); - - // Check if the names of the columns from the data source are to be included in a header row. - if (importColumnHeadings) { - // Store the original values of these properties before changing them. - boolean boldValue = builder.getFont().getBold(); - int paragraphAlignmentValue = builder.getParagraphFormat().getAlignment(); - - // Format the heading row with the appropriate properties. - builder.getFont().setBold(true); - builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); - - // Create a new row and insert the name of each column into the first row of the table. - for (int i = 1; i < numColumns + 1; i++) { - builder.insertCell(); - builder.writeln(metaData.getColumnName(i)); - } - - builder.endRow(); - - // Restore the original formatting. - builder.getFont().setBold(boldValue); - builder.getParagraphFormat().setAlignment(paragraphAlignmentValue); - } - - // Iterate through all rows and then columns of the data. - while (dataTable.getResultSet().next()) { - for (int i = 1; i < numColumns + 1; i++) { - // Insert a new cell for each object. - builder.insertCell(); - - // Retrieve the current record. - Object item = dataTable.getResultSet().getObject(metaData.getColumnName(i)); - // This is name of the data type. - String typeName = item.getClass().getSimpleName(); - - if (typeName.equals("byte[]")) { - // Assume a byte array is an image. Other data types can be added here. - builder.insertImage((byte[]) item, 50, 50); - } else if (typeName.equals("Timestamp")) { - // Define a custom format for dates and times. - builder.write(new SimpleDateFormat("MMMM d, yyyy").format((Timestamp) item)); - } else { - // By default any other item will be inserted as text. - builder.write(item.toString()); - } - } - - // After we insert all the data from the current record we can end the table row. - builder.endRow(); - } - - // We have finished inserting all the data from the DataTable, we can end the table. - builder.endTable(); - return table; - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/creation/FormattedTable.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/creation/FormattedTable.java deleted file mode 100644 index 4207d475..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/creation/FormattedTable.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.creation; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -import java.awt.*; - -public class FormattedTable { - - private static final String dataDir = Utils.getSharedDataDir(FormattedTable.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - // For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - Table table = builder.startTable(); - - // Make the header row. - builder.insertCell(); - - // Set the left indent for the table. Table wide formatting must be applied after - // at least one row is present in the table. - table.setLeftIndent(20.0); - - // Set height and define the height rule for the header row. - builder.getRowFormat().setHeight(40.0); - builder.getRowFormat().setHeightRule(HeightRule.AT_LEAST); - - // Some special features for the header row. - builder.getCellFormat().getShading().setBackgroundPatternColor(Color.GRAY); - builder.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); - builder.getFont().setSize(16); - builder.getFont().setName("Bauhaus 93"); - builder.getFont().setBold(true); - - builder.getCellFormat().setWidth(100.0); - builder.write("Header Row,\n Cell 1"); - - // We don't need to specify the width of this cell because it's inherited from the previous cell. - builder.insertCell(); - builder.write("Header Row,\n Cell 2"); - - builder.insertCell(); - builder.getCellFormat().setWidth(200.0); - builder.write("Header Row,\n Cell 3"); - builder.endRow(); - - // Set features for the other rows and cells. - builder.getCellFormat().getShading().setBackgroundPatternColor(Color.BLUE); - builder.getCellFormat().setWidth(100.0); - builder.getCellFormat().setVerticalAlignment(CellVerticalAlignment.CENTER); - - // Reset height and define a different height rule for table body - builder.getRowFormat().setHeight(30.0); - builder.getRowFormat().setHeight(HeightRule.AUTO); - builder.insertCell(); - - // Reset font formatting. - builder.getFont().setSize(12); - builder.getFont().setBold(false); - - // Build the other cells. - builder.write("Row 1, Cell 1 Content"); - builder.insertCell(); - builder.write("Row 1, Cell 2 Content"); - - builder.insertCell(); - builder.getCellFormat().setWidth(200.0); - builder.write("Row 1, Cell 3 Content"); - builder.endRow(); - - builder.insertCell(); - builder.getCellFormat().setWidth(100.0); - builder.write("Row 2, Cell 1 Content"); - - builder.insertCell(); - builder.write("Row 2, Cell 2 Content"); - - builder.insertCell(); - builder.getCellFormat().setWidth(200.0); - builder.write("Row 2, Cell 3 Content."); - builder.endRow(); - builder.endTable(); - - // Save the document to disk. - doc.save(dataDir + "DocumentBuilder_CreateFormattedTable_Out.doc"); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/creation/InsertCloneOfExistingTable.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/creation/InsertCloneOfExistingTable.java deleted file mode 100644 index daf4556f..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/creation/InsertCloneOfExistingTable.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.creation; - -import com.aspose.words.Cell; -import com.aspose.words.Document; -import com.aspose.words.NodeType; -import com.aspose.words.Paragraph; -import com.aspose.words.Row; -import com.aspose.words.Table; -import com.aspose.words.examples.Utils; - -public class InsertCloneOfExistingTable { - - private static final String dataDir = Utils.getSharedDataDir(InsertCloneOfExistingTable.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - // Make a clone of a table in the document and insert it after the original table - cloneOfATable(); - - // Remove all content from the cells of a cloned table - removeAllContentFromCellsOfAClonedTable(); - - // Make a clone of the last row of a table and append it to the table - cloneLastRowOfATable(); - } - - public static void cloneOfATable() throws Exception { - Document doc = new Document(dataDir + "Table.SimpleTable.doc"); - - // Retrieve the first table in the document. - Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); - - // Create a clone of the table. - Table tableClone = (Table) table.deepClone(true); - - // Insert the cloned table into the document after the original - table.getParentNode().insertAfter(tableClone, table); - - // Insert an empty paragraph between the two tables or else they will be combined into one - // upon save. This has to do with document validation. - table.getParentNode().insertAfter(new Paragraph(doc), table); - - doc.save(dataDir + "Table_CloneTableAndInsert_Out.doc"); - } - - public static void removeAllContentFromCellsOfAClonedTable() throws Exception { - Document doc = new Document(dataDir + "Table.SimpleTable.doc"); - - // Retrieve the first table in the document. - Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); - - // Create a clone of the table. - Table tableClone = (Table) table.deepClone(true); - - for (Cell cell : (Iterable) tableClone.getChildNodes(NodeType.CELL, true)) { - cell.removeAllChildren(); - } - - // Insert the cloned table into the document after the original - table.getParentNode().insertAfter(tableClone, table); - - // Insert an empty paragraph between the two tables or else they will be combined into one - // upon save. This has to do with document validation. - table.getParentNode().insertAfter(new Paragraph(doc), table); - - doc.save(dataDir + "RemoveAllContentFromCellsOfAClonedTable_Out.doc"); - } - - public static void cloneLastRowOfATable() throws Exception { - Document doc = new Document(dataDir + "Table.SimpleTable.doc"); - - // Retrieve the first table in the document. - Table table = (Table) doc.getChild(NodeType.TABLE, 0, true); - - // Clone the last row in the table. - Row clonedRow = (Row) table.getLastRow().deepClone(true); - - // Remove all content from the cloned row's cells. This makes the row ready for - // new content to be inserted into. - for (Cell cell : clonedRow.getCells()) - cell.removeAllChildren(); - - // Add the row to the end of the table. - table.appendChild(clonedRow); - - doc.save(dataDir + "Table.AddCloneRowToTable_Out.doc"); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/creation/InsertTableDirectlyIntoDOM.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/creation/InsertTableDirectlyIntoDOM.java deleted file mode 100644 index bdf6b494..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/creation/InsertTableDirectlyIntoDOM.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.creation; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; -import java.awt.*; - -public class InsertTableDirectlyIntoDOM { - - private static final String dataDir = Utils.getSharedDataDir(InsertTableDirectlyIntoDOM.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(); - - // We start by creating the table object. Note how we must pass the document object - // to the constructor of each node. This is because every node we create must belong - // to some document. - Table table = new Table(doc); - // Add the table to the document. - doc.getFirstSection().getBody().appendChild(table); - - // Here we could call EnsureMinimum to create the rows and cells for us. This method is used - // to ensure that the specified node is valid, in this case a valid table should have at least one - // row and one cell, therefore this method creates them for us. - - // Instead we will handle creating the row and table ourselves. This would be the best way to do this - // if we were creating a table inside an algorthim for example. - Row row = new Row(doc); - row.getRowFormat().setAllowBreakAcrossPages(true); - table.appendChild(row); - - // We can now apply any auto fit settings. - table.autoFit(AutoFitBehavior.FIXED_COLUMN_WIDTHS); - - // Create a cell and add it to the row - Cell cell = new Cell(doc); - cell.getCellFormat().getShading().setBackgroundPatternColor(Color.BLUE); - cell.getCellFormat().setWidth(80); - - // Add a paragraph to the cell as well as a new run with some text. - cell.appendChild(new Paragraph(doc)); - cell.getFirstParagraph().appendChild(new Run(doc, "Row 1, Cell 1 Text")); - - // Add the cell to the row. - row.appendChild(cell); - - // We would then repeat the process for the other cells and rows in the table. - // We can also speed things up by cloning existing cells and rows. - row.appendChild(cell.deepClone(false)); - row.getLastCell().appendChild(new Paragraph(doc)); - row.getLastCell().getFirstParagraph().appendChild(new Run(doc, "Row 1, Cell 2 Text")); - - doc.save(dataDir + "Table_InsertTableUsingNodes_Out.doc"); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/creation/InsertTableFromHtml.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/creation/InsertTableFromHtml.java deleted file mode 100644 index db32cb17..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/creation/InsertTableFromHtml.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.creation; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -public class InsertTableFromHtml { - - private static final String dataDir = Utils.getSharedDataDir(InsertTableFromHtml.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - // Insert the table from HTML. Note that AutoFitSettings does not apply to tables - // inserted from HTML. - builder.insertHtml("

          " + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "
          Row 1, Cell 1Row 1, Cell 2
          Row 2, Cell 2Row 2, Cell 2
          "); - - // Save the document to disk. - doc.save(dataDir + "DocumentBuilder_InsertTableFromHtml_Out.doc"); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/creation/NestedTable.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/creation/NestedTable.java deleted file mode 100644 index 2d6c75f7..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/creation/NestedTable.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.creation; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -public class NestedTable { - - private static final String dataDir = Utils.getSharedDataDir(NestedTable.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - // For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - // Build the outer table. - Cell cell = builder.insertCell(); - builder.writeln("Outer Table Cell 1"); - - builder.insertCell(); - builder.writeln("Outer Table Cell 2"); - - // This call is important in order to create a nested table within the first table - // Without this call the cells inserted below will be appended to the outer table.builder.endTable(); - builder.endTable(); - - // Move to the first cell of the outer table. - builder.moveTo(cell.getFirstParagraph()); - - // Build the inner table. - builder.insertCell(); - builder.writeln("Inner Table Cell 1"); - - builder.insertCell(); - builder.writeln("Inner Table Cell 2"); - - builder.endTable(); - - // Save the document to disk. - doc.save(dataDir + "DocumentBuilder_InsertNestedTable_Out.doc"); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/creation/SimpleTable.java b/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/creation/SimpleTable.java deleted file mode 100644 index 1968ffe9..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/programming_documents/tables/creation/SimpleTable.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.aspose.words.examples.programming_documents.tables.creation; - -import com.aspose.words.*; -import com.aspose.words.examples.Utils; - -public class SimpleTable { - - private static final String dataDir = Utils.getSharedDataDir(SimpleTable.class) + "Tables/"; - - public static void main(String[] args) throws Exception { - Document doc = new Document(); - DocumentBuilder builder = new DocumentBuilder(doc); - - // We call this method to start building the table. - builder.startTable(); - builder.insertCell(); - builder.write("Row 1, Cell 1 Content."); - - // Build the second cell - builder.insertCell(); - builder.write("Row 1, Cell 2 Content."); - // Call the following method to end the row and start a new row. - builder.endRow(); - - // Build the first cell of the second row. - builder.insertCell(); - builder.write("Row 2, Cell 1 Content"); - - // Build the second cell. - builder.insertCell(); - builder.write("Row 2, Cell 2 Content."); - builder.endRow(); - - // Signal that we have finished building the table. - builder.endTable(); - - // Save the document to disk. - doc.save(dataDir + "DocumentBuilder_CreateSimpleTable_Out.doc"); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/quickstart/AppendDocuments.java b/Examples/src/main/java/com/aspose/words/examples/quickstart/AppendDocuments.java deleted file mode 100644 index ef4ecfd6..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/quickstart/AppendDocuments.java +++ /dev/null @@ -1,25 +0,0 @@ - - -package com.aspose.words.examples.quickstart; - -import com.aspose.words.Document; -import com.aspose.words.ImportFormatMode; -import com.aspose.words.examples.Utils; - -public class AppendDocuments -{ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(AppendDocuments.class); - - // Load the destination and source documents from disk. - Document dstDoc = new Document(dataDir + "TestFile.Destination.doc"); - Document srcDoc = new Document(dataDir + "TestFile.Source.doc"); - // Append the source document to the destination document while keeping the original formatting of the source document. - dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING); - dstDoc.save(dataDir + "TestFile Out.docx"); - - System.out.println("Documents appended successfully."); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/quickstart/ApplyLicense.java b/Examples/src/main/java/com/aspose/words/examples/quickstart/ApplyLicense.java deleted file mode 100644 index 9dfa77ea..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/quickstart/ApplyLicense.java +++ /dev/null @@ -1,26 +0,0 @@ - - -package com.aspose.words.examples.quickstart; - -import com.aspose.words.License; - -public class ApplyLicense -{ - public static void main(String[] args) throws Exception - { - // This line attempts to set a license from several locations relative to the executable and Aspose.Words.dll. - // You can also use the additional overload to load a license from a stream, this is useful for instance when the - // license is stored as an embedded resource - try - { - License license = new License(); - license.setLicense("Aspose.Words.lic"); - System.out.println("License set successfully."); - } - catch (Exception e) - { - // We do not ship any license with this example, visit the Aspose site to obtain either a temporary or permanent license. - System.out.println("There was an error setting the license: " + e.getMessage()); - } - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/quickstart/FindAndReplace.java b/Examples/src/main/java/com/aspose/words/examples/quickstart/FindAndReplace.java deleted file mode 100644 index b7fb9c5b..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/quickstart/FindAndReplace.java +++ /dev/null @@ -1,34 +0,0 @@ - - -package com.aspose.words.examples.quickstart; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; -import com.aspose.words.examples.programming_documents.find_replace.FindAndHighlightText; - -import java.util.regex.Pattern; - -public class FindAndReplace -{ - private static final String dataDir = Utils.getSharedDataDir(FindAndReplace.class) + "FindAndReplace/"; - - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(FindAndReplace.class); - - // Open the document. - Document doc = new Document(dataDir + "ReplaceSimple.doc"); - // Check the text of the document - System.out.println("Original document text: " + doc.getRange().getText()); - Pattern regex = Pattern.compile("_CustomerName_", Pattern.CASE_INSENSITIVE); - // Replace the text in the document. - doc.getRange().replace(regex, "James Bond"); - // Check the replacement was made. - System.out.println("Document text after replace: " + doc.getRange().getText()); - // Save the modified document. - doc.save(dataDir + "ReplaceSimple Out.doc"); - - System.out.println("Text found and replaced successfully."); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/quickstart/HelloWorld.java b/Examples/src/main/java/com/aspose/words/examples/quickstart/HelloWorld.java deleted file mode 100644 index 45337122..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/quickstart/HelloWorld.java +++ /dev/null @@ -1,26 +0,0 @@ - - -package com.aspose.words.examples.quickstart; - -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.examples.Utils; - -public class HelloWorld -{ - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(HelloWorld.class); - - // Create a blank document. - Document doc = new Document(); - // DocumentBuilder provides members to easily add content to a document. - DocumentBuilder builder = new DocumentBuilder(doc); - // Write a new paragraph in the document with the text "Hello World!" - builder.writeln("Hello World!"); - // Save the document in DOCX format. The format to save as is inferred from the extension of the file name. - // Aspose.Words supports saving any document in many more formats. - doc.save(dataDir + "HelloWorld_out_.docx"); - System.out.println("New Word document created successfully."); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/quickstart/LoadAndSaveToDisk.java b/Examples/src/main/java/com/aspose/words/examples/quickstart/LoadAndSaveToDisk.java deleted file mode 100644 index e7104b1f..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/quickstart/LoadAndSaveToDisk.java +++ /dev/null @@ -1,18 +0,0 @@ - - -package com.aspose.words.examples.quickstart; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - -public class LoadAndSaveToDisk { - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = Utils.getDataDir(LoadAndSaveToDisk.class); - // Load the document from the absolute path on disk. - Document doc = new Document(dataDir + "Document.doc"); - // Save the dDocument.dococument as DOCX document."); - doc.save(dataDir + "Document Out.docx"); - System.out.println("Document loaded from disk and saved again successfully."); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/quickstart/LoadAndSaveToStream.java b/Examples/src/main/java/com/aspose/words/examples/quickstart/LoadAndSaveToStream.java deleted file mode 100644 index 12b0482a..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/quickstart/LoadAndSaveToStream.java +++ /dev/null @@ -1,36 +0,0 @@ - - -package com.aspose.words.examples.quickstart; - -import com.aspose.words.Document; -import com.aspose.words.SaveFormat; -import com.aspose.words.examples.Utils; - -import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.InputStream; - -public class LoadAndSaveToStream { - public static void main(String[] args) throws Exception { - - // The path to the documents directory. - String dataDir = Utils.getDataDir(LoadAndSaveToStream.class); - // Open the stream. Read only access is enough for Aspose.Words to load a document. - InputStream stream = new FileInputStream(dataDir + "Document.doc"); - // Load the entire document into memory. - Document doc = new Document(stream); - // You can close the stream now, it is no longer needed because the document is in memory. - stream.close(); - - // ... do something with the document - // Convert the document to a different format and save to stream. - ByteArrayOutputStream dstStream = new ByteArrayOutputStream(); - doc.save(dstStream, SaveFormat.RTF); - FileOutputStream output = new FileOutputStream(dataDir + "Document Out.rtf"); - output.write(dstStream.toByteArray()); - output.close(); - - System.out.println("Document loaded from stream and then saved successfully."); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/quickstart/SimpleMailMerge.java b/Examples/src/main/java/com/aspose/words/examples/quickstart/SimpleMailMerge.java deleted file mode 100644 index f6595d05..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/quickstart/SimpleMailMerge.java +++ /dev/null @@ -1,25 +0,0 @@ - - -package com.aspose.words.examples.quickstart; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - -public class SimpleMailMerge -{ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(SimpleMailMerge.class); - - Document doc = new Document(dataDir + "Template.doc"); - // Fill the fields in the document with user data. - doc.getMailMerge().execute( - new String[] { "FullName", "Company", "Address", "Address2", "City" }, - new Object[] { "James Bond", "MI5 Headquarters", "Milbank", "", "London" }); - // Saves the document to disk. - doc.save(dataDir + "MailMerge Result Out.docx"); - - System.out.println("Mail merge performed successfully."); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/quickstart/UpdateFields.java b/Examples/src/main/java/com/aspose/words/examples/quickstart/UpdateFields.java deleted file mode 100644 index 022490c9..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/quickstart/UpdateFields.java +++ /dev/null @@ -1,63 +0,0 @@ - - -package com.aspose.words.examples.quickstart; - -import com.aspose.words.BreakType; -import com.aspose.words.Document; -import com.aspose.words.DocumentBuilder; -import com.aspose.words.StyleIdentifier; -import com.aspose.words.examples.Utils; - -public class UpdateFields -{ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(UpdateFields.class); - - // Demonstrates how to insert fields and update them using Aspose.Words. - // First create a blank document. - Document doc = new Document(); - // Use the document builder to insert some content and fields. - DocumentBuilder builder = new DocumentBuilder(doc); - // Insert a table of contents at the beginning of the document. - builder.insertTableOfContents("\\o \"1-3\" \\h \\z \\u"); - builder.writeln(); - // Insert some other fields. - builder.write("Page: "); - builder.insertField("PAGE"); - builder.write(" of "); - builder.insertField("NUMPAGES"); - builder.writeln(); - builder.write("Date: "); - builder.insertField("DATE"); - // Start the actual document content on the second page. - builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE); - // Build a document with complex structure by applying different heading styles thus creating TOC entries. - builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); - builder.writeln("Heading 1"); - builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); - builder.writeln("Heading 1.1"); - builder.writeln("Heading 1.2"); - builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); - builder.writeln("Heading 2"); - builder.writeln("Heading 3"); - // Move to the next page. - builder.insertBreak(BreakType.PAGE_BREAK); - builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); - builder.writeln("Heading 3.1"); - builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_3); - builder.writeln("Heading 3.1.1"); - builder.writeln("Heading 3.1.2"); - builder.writeln("Heading 3.1.3"); - builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); - builder.writeln("Heading 3.2"); - builder.writeln("Heading 3.3"); - System.out.println("Updating all fields in the document."); - // Call the method below to update the TOC. - doc.updateFields(); - doc.save(dataDir + "Document Field Update Out.docx"); - - System.out.println("Fields updated in the document successfully."); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/quickstart/WorkingWithNodes.java b/Examples/src/main/java/com/aspose/words/examples/quickstart/WorkingWithNodes.java deleted file mode 100644 index 31fd745a..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/quickstart/WorkingWithNodes.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2001-2013 Aspose Pty Ltd. All Rights Reserved. - * - * This file is part of Aspose.Words. The source code in this file - * is only intended as a supplement to the documentation, and is provided - * "as is", without warranty of any kind, either expressed or implied. - */ - -package com.aspose.words.examples.quickstart; - -import com.aspose.words.Document; -import com.aspose.words.Node; -import com.aspose.words.Paragraph; -import com.aspose.words.Section; - -public class WorkingWithNodes -{ - public static void main(String[] args) throws Exception - { - // Create a new document. - Document doc = new Document(); - - // Creates and adds a paragraph node to the document. - Paragraph para = new Paragraph(doc); - - // Typed access to the last section of the document. - Section section = doc.getLastSection(); - section.getBody().appendChild(para); - - // Next print the node type of one of the nodes in the document. - int nodeType = doc.getFirstSection().getBody().getNodeType(); - - System.out.println("NodeType: " + Node.nodeTypeToString(nodeType)); - } -} - - - - diff --git a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/ControlEmbeddingOfCoreAndSystemFonts.java b/Examples/src/main/java/com/aspose/words/examples/rendering_printing/ControlEmbeddingOfCoreAndSystemFonts.java deleted file mode 100644 index c563b2dc..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/ControlEmbeddingOfCoreAndSystemFonts.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.aspose.words.examples.rendering_printing; - -import com.aspose.words.Document; -import com.aspose.words.PdfFontEmbeddingMode; -import com.aspose.words.PdfSaveOptions; -import com.aspose.words.examples.Utils; - -public class ControlEmbeddingOfCoreAndSystemFonts { - - private static final String dataDir = Utils.getSharedDataDir(ControlEmbeddingOfCoreAndSystemFonts.class) + "RenderingAndPrinting/"; - - public static void main(String[] args) throws Exception { - // Embed Core Fonts - embedCoreFonts(); - - // Embed System Fonts - embedSystemFonts(); - } - - public static void embedCoreFonts() throws Exception { - // Load the document to render. - Document doc = new Document(dataDir + "Rendering.doc"); - - // To disable embedding of core fonts and subsuite PDF type 1 fonts set UseCoreFonts to true. - PdfSaveOptions options = new PdfSaveOptions(); - options.setUseCoreFonts(true); - - // The output PDF will not be embedded with core fonts such as Arial, Times New Roman etc. - doc.save(dataDir + "Rendering.DisableEmbedWindowsFonts_Out.pdf"); - } - - public static void embedSystemFonts() throws Exception { - // Load the document to render. - Document doc = new Document(dataDir + "Rendering.doc"); - - // To subset fonts in the output PDF document, simply create new PdfSaveOptions and set EmbedFullFonts to false. - // To disable embedding standard windows font use the PdfSaveOptions and set the EmbedStandardWindowsFonts property to false. - PdfSaveOptions options = new PdfSaveOptions(); - options.setFontEmbeddingMode(PdfFontEmbeddingMode.EMBED_ALL); - - // The output PDF will be saved without embedding standard windows fonts. - doc.save(dataDir + "Rendering.DisableEmbedWindowsFonts_Out.pdf"); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/DocumentPreviewAndPrint.java b/Examples/src/main/java/com/aspose/words/examples/rendering_printing/DocumentPreviewAndPrint.java deleted file mode 100644 index f0b03ee7..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/DocumentPreviewAndPrint.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.aspose.words.examples.rendering_printing; - -import com.aspose.words.examples.Utils; -import javax.print.attribute.HashPrintRequestAttributeSet; -import javax.print.attribute.PrintRequestAttributeSet; -import javax.print.attribute.standard.PageRanges; -import java.awt.print.PrinterJob; -import com.aspose.words.*; - -public class DocumentPreviewAndPrint { - - private static final String dataDir = Utils.getSharedDataDir(DocumentPreviewAndPrint.class) + "RenderingAndPrinting/"; - - public static void main(String[] args) throws Exception { - - // Open the document. - Document doc = new Document(dataDir + "TestFile.doc"); - - PrinterJob pj = PrinterJob.getPrinterJob(); - - // Initialize the Print Dialog with the number of pages in the document. - PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet(); - attributes.add(new PageRanges(1, doc.getPageCount())); - if (!pj.printDialog(attributes)) { - return; - } - - // This object is responsible for rendering our document for use with the Java Print API. - AsposeWordsPrintDocument awPrintDoc = new AsposeWordsPrintDocument(doc); - // Pass our document as pageable to the printer job. - pj.setPageable(awPrintDoc); - - // Create an instance of the print preview dialog and pass the print dialog and our document. - - // Note that AsposeWordsPrintDocument implements both the Pageable and Printable interfaces. If the pageable constructor for PrintPreviewDialog - // is used then the formatting of each page is taken from the document. If the printable constructor is used then Page Setup dialog becomes enabled - // and the desired page setting for all pages can be chosen there instead. - PrintPreviewDialog previewDlg = new PrintPreviewDialog(awPrintDoc); - // Pass the desired page range attributes to the print preview dialog. - previewDlg.setPrinterAttributes(attributes); - - // Proceed with printing if the user accepts the print preview. - if (previewDlg.display()) - pj.print(attributes); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/EmbedFontsInAdobePDF.java b/Examples/src/main/java/com/aspose/words/examples/rendering_printing/EmbedFontsInAdobePDF.java deleted file mode 100644 index cd7c4a21..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/EmbedFontsInAdobePDF.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.aspose.words.examples.rendering_printing; - -import com.aspose.words.Document; -import com.aspose.words.PdfSaveOptions; -import com.aspose.words.examples.Utils; - -public class EmbedFontsInAdobePDF { - - private static final String dataDir = Utils.getSharedDataDir(EmbedFontsInAdobePDF.class) + "RenderingAndPrinting/"; - - public static void main(String[] args) throws Exception { - // Set Aspose.Words to embed full fonts in the output PDF document. - embedFullFontsInPDFDocument(); - - // Set Aspose.Words to embed subset fonts in the output PDF document. - embedSubsetFontsInPDFDocument(); - } - - public static void embedFullFontsInPDFDocument() throws Exception { - // Load the document to render. - Document doc = new Document(dataDir + "Rendering.doc"); - - // Aspose.Words embeds full fonts by default when EmbedFullFonts is set to true. The property below can be changed - // each time a document is rendered. - PdfSaveOptions options = new PdfSaveOptions(); - options.setEmbedFullFonts(true); - - // The output PDF will be embedded with all fonts found in the document. - doc.save(dataDir + "Rendering.EmbedFullFonts Out.pdf", options); - } - - public static void embedSubsetFontsInPDFDocument() throws Exception { - // Load the document to render. - Document doc = new Document(dataDir + "Rendering.doc"); - - // To subset fonts in the output PDF document, simply create new PdfSaveOptions and set EmbedFullFonts to false. - PdfSaveOptions options = new PdfSaveOptions(); - options.setEmbedFullFonts(false); - - // The output PDF will contain subsets of the fonts in the document. Only the glyphs used - // in the document are included in the PDF fonts. - doc.save(dataDir + "Rendering.SubsetFonts Out.pdf", options); - } - - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/HandleDocumentWarnings.java b/Examples/src/main/java/com/aspose/words/examples/rendering_printing/HandleDocumentWarnings.java deleted file mode 100644 index 0f01a1aa..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/HandleDocumentWarnings.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.aspose.words.examples.rendering_printing; - -import com.aspose.words.IWarningCallback; -import com.aspose.words.WarningInfo; -import com.aspose.words.WarningType; - -public class HandleDocumentWarnings implements IWarningCallback { - /** - * Our callback only needs to implement the "Warning" method. This method is - * called whenever there is a potential issue during document processing. - * The callback can be set to listen for warnings generated during document - * load and/or document save. - */ - public void warning(WarningInfo info) { - // We are only interested in fonts being substituted. - if (info.getWarningType() == WarningType.FONT_SUBSTITUTION) { - System.out.println("Font substitution: " + info.getDescription()); - } - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/HyphenateWords.java b/Examples/src/main/java/com/aspose/words/examples/rendering_printing/HyphenateWords.java deleted file mode 100644 index da028606..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/HyphenateWords.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.aspose.words.examples.rendering_printing; - -import java.io.FileInputStream; -import java.io.InputStream; - -import com.aspose.words.Document; -import com.aspose.words.Hyphenation; -import com.aspose.words.examples.Utils; - -public class HyphenateWords { - - private static final String dataDir = Utils.getSharedDataDir(HyphenateWords.class) + "RenderingAndPrinting/"; - - public static void main(String[] args) throws Exception { - // Load hyphenation dictionaries for a specified languages from file. - loadHyphenationDictionaryFromFile(); - - // Load a hyphenation dictionary for a specified language from a stream. - loadHyphenationDictionaryFromStream(); - } - - public static void loadHyphenationDictionaryFromFile() throws Exception { - Document doc = new Document(dataDir + "in.docx"); - - Hyphenation.registerDictionary("en-US", dataDir + "hyph_en_US.dic"); - Hyphenation.registerDictionary("de-CH", dataDir + "hyph_de_CH.dic"); - - doc.save(dataDir + "LoadHyphenationDictionaryFromFile_Out.pdf"); - - } - - public static void loadHyphenationDictionaryFromStream() throws Exception { - Document doc = new Document(dataDir + "in.docx"); - - InputStream stream = new FileInputStream(dataDir + "hyph_de_CH.dic"); - Hyphenation.registerDictionary("de-CH", stream); - - doc.save(dataDir + "LoadHyphenationDictionaryFromStream_Out.pdf"); - - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/MultipagePrintDocument.java b/Examples/src/main/java/com/aspose/words/examples/rendering_printing/MultipagePrintDocument.java deleted file mode 100644 index fe2fdd81..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/MultipagePrintDocument.java +++ /dev/null @@ -1,134 +0,0 @@ -package com.aspose.words.examples.rendering_printing; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.geom.Point2D; -import java.awt.print.PageFormat; -import java.awt.print.Printable; - -import javax.print.attribute.AttributeSet; -import javax.print.attribute.standard.PageRanges; - -import com.aspose.words.Document; - -public class MultipagePrintDocument implements Printable { - - private Document mDocument; - private int mPagesPerSheet; - private boolean mPrintPageBorders; - private AttributeSet mAttributeSet; - - public MultipagePrintDocument(Document document, int pagesPerSheet, boolean printPageBorders, AttributeSet attributes) { - if (document == null) - throw new IllegalArgumentException("document"); - - mDocument = document; - mPagesPerSheet = pagesPerSheet; - mPrintPageBorders = printPageBorders; - mAttributeSet = attributes; - } - - public int print(Graphics g, PageFormat pf, int page) { - // The page start and end indices as defined in the attribute set. - int[][] pageRanges = ((PageRanges) mAttributeSet.get(PageRanges.class)).getMembers(); - int fromPage = pageRanges[0][0] - 1; - int toPage = pageRanges[0][1] - 1; - - Dimension thumbCount = getThumbCount(mPagesPerSheet, pf); - - // Calculate the page index which is to be rendered next. - int pagesOnCurrentSheet = (int) (page * (thumbCount.getWidth() * thumbCount.getHeight())); - - // If the page index is more than the total page range then there is nothing more to render. - if (pagesOnCurrentSheet > (toPage - fromPage)) - return Printable.NO_SUCH_PAGE; - - // Calculate the size of each thumbnail placeholder in points. - Point2D.Float thumbSize = new Point2D.Float((float) (pf.getImageableWidth() / thumbCount.getWidth()), (float) (pf.getImageableHeight() / thumbCount.getHeight())); - - // Calculate the number of the first page to be printed on this sheet of paper. - int startPage = pagesOnCurrentSheet + fromPage; - - // Select the number of the last page to be printed on this sheet of paper. - int pageTo = Math.max(startPage + mPagesPerSheet - 1, toPage); - - // Loop through the selected pages from the stored current page to calculated last page. - for (int pageIndex = startPage; pageIndex <= pageTo; pageIndex++) { - // Calculate the column and row indices. - int rowIdx = (int) Math.floor((pageIndex - startPage) / thumbCount.getWidth()); - int columnIdx = (int) Math.floor((pageIndex - startPage) % thumbCount.getWidth()); - - // Define the thumbnail location in world coordinates (points in this case). - float thumbLeft = columnIdx * thumbSize.x; - float thumbTop = rowIdx * thumbSize.y; - - try { - - // Calculate the left and top starting positions. - int leftPos = (int) (thumbLeft + pf.getImageableX()); - int topPos = (int) (thumbTop + pf.getImageableY()); - - // Render the document page to the Graphics object using calculated coordinates and thumbnail placeholder size. - // The useful return value is the scale at which the page was rendered. - float scale = mDocument.renderToSize(pageIndex, (Graphics2D) g, leftPos, topPos, (int) thumbSize.x, (int) thumbSize.y); - - // Draw the page borders (the page thumbnail could be smaller than the thumbnail placeholder size). - if (mPrintPageBorders) { - // Get the real 100% size of the page in points. - Point2D.Float pageSize = mDocument.getPageInfo(pageIndex).getSizeInPoints(); - // Draw the border around the scaled page using the known scale factor. - g.setColor(Color.black); - g.drawRect(leftPos, topPos, (int) (pageSize.x * scale), (int) (pageSize.y * scale)); - - // Draw the border around the thumbnail placeholder. - g.setColor(Color.red); - g.drawRect(leftPos, topPos, (int) thumbSize.x, (int) thumbSize.y); - } - } - - catch (Exception e) { - // If there are any errors that occur during rendering then do nothing. - // This will draw a blank page if there are any errors during rendering. - } - - } - - return Printable.PAGE_EXISTS; - } - - private Dimension getThumbCount(int pagesPerSheet, PageFormat pf) { - Dimension size; - // Define the number of the columns and rows on the sheet for the Landscape-oriented paper. - switch (pagesPerSheet) { - case 16: - size = new Dimension(4, 4); - break; - case 9: - size = new Dimension(3, 3); - break; - case 8: - size = new Dimension(4, 2); - break; - case 6: - size = new Dimension(3, 2); - break; - case 4: - size = new Dimension(2, 2); - break; - case 2: - size = new Dimension(2, 1); - break; - default: - size = new Dimension(1, 1); - break; - } - // Swap the width and height if the paper is in the Portrait orientation. - if ((pf.getWidth() - pf.getImageableX()) < (pf.getHeight() - pf.getImageableY())) - return new Dimension((int) size.getHeight(), (int) size.getWidth()); - - return size; - } - -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/MultiplePagesOnSheet.java b/Examples/src/main/java/com/aspose/words/examples/rendering_printing/MultiplePagesOnSheet.java deleted file mode 100644 index 5823d596..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/MultiplePagesOnSheet.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.aspose.words.examples.rendering_printing; - -import java.awt.print.PrinterJob; - -import javax.print.attribute.HashPrintRequestAttributeSet; -import javax.print.attribute.PrintRequestAttributeSet; -import javax.print.attribute.standard.PageRanges; - -import com.aspose.words.Document; -import com.aspose.words.examples.Utils; - -public class MultiplePagesOnSheet { - - private static final String dataDir = Utils.getSharedDataDir(DocumentPreviewAndPrint.class) + "RenderingAndPrinting/"; - - public static void main(String[] args) throws Exception { - // Open the document. - Document doc = new Document(dataDir + "TestFile.doc"); - - // Create a print job to print our document with. - PrinterJob pj = PrinterJob.getPrinterJob(); - - // Initialize an attribute set with the number of pages in the document. - PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet(); - attributes.add(new PageRanges(1, doc.getPageCount())); - - // Pass the printer settings along with the other parameters to the print document. - MultipagePrintDocument awPrintDoc = new MultipagePrintDocument(doc, 4, true, attributes); - - // Pass the document to be printed using the print job. - pj.setPrintable(awPrintDoc); - - pj.print(); - } - -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/PrintPreviewDialog.form b/Examples/src/main/java/com/aspose/words/examples/rendering_printing/PrintPreviewDialog.form deleted file mode 100644 index 440ccea7..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/PrintPreviewDialog.form +++ /dev/null @@ -1,155 +0,0 @@ - -
          - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
          diff --git a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/PrintPreviewDialog.java b/Examples/src/main/java/com/aspose/words/examples/rendering_printing/PrintPreviewDialog.java deleted file mode 100644 index 4435949a..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/PrintPreviewDialog.java +++ /dev/null @@ -1,609 +0,0 @@ -/* - * Copyright 2001-2014 Aspose Pty Ltd. All Rights Reserved. - * - * This file is part of Aspose.Words. The source code in this file - * is only intended as a supplement to the documentation, and is provided - * "as is", without warranty of any kind, either expressed or implied. - */ -package com.aspose.words.examples.rendering_printing; - -import javax.print.attribute.PrintRequestAttributeSet; -import javax.print.attribute.standard.PageRanges; -import javax.swing.*; -import javax.swing.plaf.basic.BasicArrowButton; -import javax.swing.text.SimpleAttributeSet; -import javax.swing.text.StyleConstants; -import java.awt.*; -import java.awt.event.*; -import java.awt.image.BufferedImage; -import java.awt.print.PageFormat; -import java.awt.print.Pageable; -import java.awt.print.Printable; -import java.awt.print.PrinterJob; - - -public class PrintPreviewDialog extends JFrame { - /** - * The dialog components. - */ - private JButton printButton; - private JComboBox zoomComboBox; - private JProgressBar progressBar; - private JButton closeButton; - private JPanel contentPane; - private JTextPane pageNumberTextBox; - private BasicArrowButton previousPageButton; - private BasicArrowButton firstPageButton; - private BasicArrowButton lastPageButton; - private BasicArrowButton nextPageButton; - private JLabel imageLabel; - private JScrollPane documentViewer; - private JButton pageSetupButton; - - /** - * Private instance members. - */ - private Printable mPrintableDoc; - private Pageable mPageableDoc; - private boolean mIsOpened = true; - private int mPreviousZoomIndex; - private int mStartPage = 1; - private int mTotalPages = -1; - private int mCurrentPage = 1; - private int mDocumentPages = -1; - private boolean mPrintSelected = false; - private PrinterJob mPrintJob; - private PageFormat mPageFormat; - private PrintRequestAttributeSet mAttributeSet; - - /** - * Creates a new instance of PrintPreviewDialog for the given printable object. Since this object - * does not define formatting for each page the preview dialog presents a page setup option - * where the user can specify custom page settings for the document. - * - * @param printJob The print job for the given document. - * @param doc The printable document. - */ - public PrintPreviewDialog(PrinterJob printJob, Printable doc) { - mPrintableDoc = doc; - mPrintJob = printJob; - - // In Java 1.6 and above we would use the getPageFormat(PrintRequestAttributeSet) property of a - // class implementing printable to retrieve the currently specified page format. However this - // property is not available in versions below versions so we need to assume the default page instead. - $$$setupUI$$$(); - mPageFormat = mPrintJob.defaultPage(); - - init(); - } - - /** - * Creates a new instance of PrintPreviewDialog for the given pageable object. Since this object - * defines formatting for each page the page setup option on the preview dialog is disabled. - * - * @param doc The pageable document. - */ - public PrintPreviewDialog(Pageable doc) { - mPageableDoc = doc; - $$$setupUI$$$(); - mTotalPages = doc.getNumberOfPages(); - mDocumentPages = mTotalPages; - - init(); - } - - public void setPrinterAttributes(PrintRequestAttributeSet attributes) { - // Store the printer attributes for use with the page dialog. - mAttributeSet = attributes; - - // Extract the page range from the printer attributes if that property is present. - findPageRangeFromAttributes(attributes); - } - - public void init() { - // Setup the main window - setContentPane(contentPane); - pack(); - setTitle("Print preview"); - - // Center the dialog in the center of the page. - setLocationRelativeTo(null); - - // Add zoom options. - populateZoomComboBox(); - - // Pageable print classes already have page formatting applied so disable page setup button. - if (mPageableDoc != null) - pageSetupButton.setEnabled(false); - - // Make the page number centered horizontally. - SimpleAttributeSet aSet = new SimpleAttributeSet(); - StyleConstants.setFontFamily(aSet, "Arial"); - StyleConstants.setAlignment(aSet, StyleConstants.ALIGN_CENTER); - pageNumberTextBox.setParagraphAttributes(aSet, true); - - // Setup the appropriate handlers. - printButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - onPrint(); - } - }); - - pageSetupButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - onPageSetup(); - } - }); - - zoomComboBox.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - onZoomChanged(); - } - }); - - firstPageButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - onFirstPageSelected(); - } - }); - - previousPageButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - onPreviousPageSelected(); - } - }); - - lastPageButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - onLastPageSelected(); - } - }); - - nextPageButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - onNextPageSelected(); - } - }); - - closeButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - closeWindow(); - } - }); - - setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); - addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - closeWindow(); - } - }); - - contentPane.registerKeyboardAction(new ActionListener() { - public void actionPerformed(ActionEvent e) { - closeWindow(); - } - }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); - } - - /** - * Called to display the print preview dialog. - */ - public boolean display() { - // Activate the window. - setVisible(true); - - // Render the current page. - setPageToDisplay(mCurrentPage); - - // This causes the JFrame to act like modal. We want to use a JFrame in this way and not JDialog so - // we can have a taskbar icon for this window. - while (mIsOpened) { - } - - // Return whether the user pressed print or close. - return mPrintSelected; - } - - /** - * Renders the current page index of the document to image based on the current zoom factor and displays it on a JScrollPane. - */ - private int renderImageAndDisplay() { - // Set the progress bar to loading. - progressBar.setVisible(true); - progressBar.setIndeterminate(true); - BufferedImage img = null; - Graphics2D g; - - // The zoom factor currently selected. - double zoomModifier = getCurrentZoomModifier(); - - // Clear the current image. - imageLabel.setIcon(null); - - int result; - - // Find the format of the current page from either the current pageable or printable object we are printing with. - PageFormat format = mPageableDoc != null ? mPageableDoc.getPageFormat(mCurrentPage - 1) : mPageFormat; - - try { - img = new BufferedImage((int) (format.getWidth() * zoomModifier), (int) (format.getHeight() * zoomModifier), BufferedImage.TYPE_INT_RGB); - g = img.createGraphics(); - - // Fill the background white and add a black border. - g.setColor(Color.WHITE); - g.fillRect(0, 0, img.getWidth(), img.getHeight()); - g.setColor(Color.BLACK); - g.drawRect(0, 0, img.getWidth() - 1, img.getHeight() - 1); - - // Scale based on zoom factor. - g.scale(zoomModifier, zoomModifier); - - // We must re-size the image label so scrolling works properly. - imageLabel.setPreferredSize(new Dimension(img.getWidth(), img.getHeight())); - imageLabel.setMinimumSize(new Dimension(img.getWidth(), img.getHeight())); - imageLabel.setMaximumSize(new Dimension(img.getWidth(), img.getHeight())); - - // Call the pageable or printable class to render the specified page onto our image object. - if (mPageableDoc != null) - result = mPageableDoc.getPrintable(mCurrentPage - 1).print(g, format, mCurrentPage - 1); - else - result = mPrintableDoc.print(g, format, mCurrentPage - 1); - } catch (Exception e) { - // We'll end up here if there is a problem with rendering or we have gone past the valid page range. - // Display a blank page and return the result so we know we have gone past the last page. - return Printable.NO_SUCH_PAGE; - } finally { - // Hide the progress bar. - progressBar.setVisible(false); - } - - // Display the rendered page. - imageLabel.setIcon(new ImageIcon(img)); - - return result; - } - - /** - * Finds the page range selected by the user by the printer attributes. - */ - private void findPageRangeFromAttributes(PrintRequestAttributeSet attributes) { - if (attributes.containsKey(PageRanges.class)) { - int[][] pageRanges = ((PageRanges) attributes.get(PageRanges.class)).getMembers(); - - int startPage = pageRanges[0][0]; - - // If we know the number of pages in the document and the user specified value is out of range then use - // the first page instead. Otherwise the user specified value is used which is checked later on if it's - // valid or not. - if (knowsDocumentPages()) { - if (startPage > mDocumentPages) - mStartPage = 1; - else - mStartPage = startPage; - } else { - mStartPage = startPage; - } - - mCurrentPage = mStartPage; - - // If we know how many pages the document has then we need to make sure the user user specified end page - // does not go beyond this limit. Otherwise use this value which will be handled later on if it's found - // to be invalid. - if (knowsDocumentPages()) - mTotalPages = Math.min(mDocumentPages, pageRanges[0][1]); - else - mTotalPages = pageRanges[0][1]; - } - } - - /** - * Changes the current page to display. - */ - private void setPageToDisplay(int page) { - mCurrentPage = page; - updateCurrentPage(); - } - - /** - * Adds the zoom options to the combobox. - */ - private void populateZoomComboBox() { - zoomComboBox.addItem("10%"); - zoomComboBox.addItem("25%"); - zoomComboBox.addItem("50%"); - zoomComboBox.addItem("75%"); - zoomComboBox.addItem("100%"); - zoomComboBox.addItem("150%"); - zoomComboBox.addItem("200%"); - zoomComboBox.setSelectedIndex(4); - - mPreviousZoomIndex = zoomComboBox.getSelectedIndex(); - } - - /** - * Returns the zoom modifier for the given zoom level. - */ - private double getCurrentZoomModifier() { - String zoomLevel = ((String) zoomComboBox.getSelectedItem()).replace("%", ""); - - // Percent increase of the original image to make the page displayed at 100%. - double hundredPercent = 1.5; - - // Zoom level percent as a decimal. - double zoomValue = Double.parseDouble(zoomLevel) / 100; - - return hundredPercent * zoomValue; - } - - /** - * Verifies the page index based off the known valid page range and if valid calls for the new page to be rendered. - * Depending if a page range was specified by the user we may or may not know the final page number yet. If we don't then - * it is found later when each page is rendered. - */ - private void updateCurrentPage() { - // If we don't know the total pages in the document then we also won't know the final page count in the document - // until we try to render outside the valid index. Until then allow the user to move forward no matter the current - // page index. - if (knowsDocumentPages()) { - if (mCurrentPage > mTotalPages) - return; - } - - // Can't move past the first page. - if (mCurrentPage < mStartPage) - return; - - int result = renderImageAndDisplay(); - - // If the rendering of the previous page resulted in "NO_SUCH_PAGE" then - // we must have found the last page in the document. The appropriate page numbers - // needs to be updated. - if (result == Printable.NO_SUCH_PAGE) { - // If this occurs at the very start of the document preview then the intial starting page - // must be out of bounds. Default to page one instead. - if (mCurrentPage == mStartPage) { - mCurrentPage = 1; - mStartPage = 1; - } else { - mCurrentPage--; - - // If the next page document button was pressed and there's no futher pages to render then - // we must have found the end page of the document. - mTotalPages = mCurrentPage; - mDocumentPages = mCurrentPage; - } - - // Render the previous page which is the last page in the document. - renderImageAndDisplay(); - } - - pageNumberTextBox.setText(String.valueOf((mCurrentPage - mStartPage) + 1)); - - updateArrowButtons(); - } - - /** - * Enables or disables arrow buttons based off the current state of the page index. - */ - private void updateArrowButtons() { - if (mCurrentPage > mStartPage) { - firstPageButton.setEnabled(true); - previousPageButton.setEnabled(true); - } else { - firstPageButton.setEnabled(false); - previousPageButton.setEnabled(false); - } - - if (knowsDocumentPages()) { - if (mCurrentPage == mTotalPages) { - nextPageButton.setEnabled(false); - lastPageButton.setEnabled(false); - } else { - nextPageButton.setEnabled(true); - lastPageButton.setEnabled(true); - } - } else { - // If we don't know how many pages are in the specified document then we cannot skip to the last page. - lastPageButton.setEnabled(false); - - if (mCurrentPage == mTotalPages) - nextPageButton.setEnabled(false); - else - nextPageButton.setEnabled(true); - } - } - - /** - * Returns true if the last page number of the document is known. - */ - private boolean knowsDocumentPages() { - return mDocumentPages > 0; - } - - /** - * Called when user presses the cross on the window or the escape key to close the program. - */ - private void closeWindow() { - setVisible(false); - mIsOpened = false; - dispose(); - } - - /** - * Called when the user press the Page Setup button. A screen is displayed which allows - * the user to change the page setting of the document before printing. - */ - private void onPageSetup() { - // Retrieve the new page format from either the attributes if specified otherwise the previous page formatting. - if (mAttributeSet != null) - mPageFormat = mPrintJob.pageDialog(mAttributeSet); - else - mPageFormat = mPrintJob.pageDialog(mPageFormat); - - // Print using the new page format. - mPrintJob.setPrintable(mPrintableDoc, mPageFormat); - - // Update the preview of the new settings. - updateCurrentPage(); - } - - - /** - * Called when the user presses the print button. Returns true to specify that printing was accepted - * and closes the window. - */ - private void onPrint() { - mPrintSelected = true; - closeWindow(); - } - - /** - * Re-renders the document page if the zoom level has been changed. - */ - private void onZoomChanged() { - if (mPreviousZoomIndex != zoomComboBox.getSelectedIndex()) { - mPreviousZoomIndex = zoomComboBox.getSelectedIndex(); - renderImageAndDisplay(); - } - } - - /** - * Called when the first page button is selected. Displays the first page. - */ - private void onFirstPageSelected() { - setPageToDisplay(mStartPage); - } - - /** - * Called when the next page button is selected. Displays the next page. - */ - private void onNextPageSelected() { - setPageToDisplay(mCurrentPage + 1); - } - - /** - * Called when the last page button is selected. Displays the last page. - */ - private void onLastPageSelected() { - setPageToDisplay(mTotalPages); - } - - /** - * Called when the previous page button is selected. Displays the previous page. - */ - private void onPreviousPageSelected() { - setPageToDisplay(mCurrentPage - 1); - } - - /** - * Creates the custom arrow buttons. - */ - private void createUIComponents() { - previousPageButton = new BasicArrowButton(BasicArrowButton.WEST); - nextPageButton = new BasicArrowButton(BasicArrowButton.EAST); - - firstPageButton = new DoubleArrowButton(BasicArrowButton.WEST); - lastPageButton = new DoubleArrowButton(BasicArrowButton.EAST); - } - - /** - * Method generated by IntelliJ IDEA GUI Designer - * >>> IMPORTANT!! <<< - * DO NOT edit this method OR call it in your code! - * - * @noinspection ALL - */ - private void $$$setupUI$$$() { - createUIComponents(); - contentPane = new JPanel(); - contentPane.setLayout(new BorderLayout(0, 0)); - contentPane.setMaximumSize(new Dimension(1000, 700)); - contentPane.setMinimumSize(new Dimension(1000, 700)); - contentPane.setPreferredSize(new Dimension(1000, 700)); - contentPane.setRequestFocusEnabled(true); - final JToolBar toolBar1 = new JToolBar(); - contentPane.add(toolBar1, BorderLayout.NORTH); - printButton = new JButton(); - printButton.setMargin(new Insets(2, 14, 2, 14)); - printButton.setText("Print"); - toolBar1.add(printButton); - final JToolBar.Separator toolBar$Separator1 = new JToolBar.Separator(); - toolBar1.add(toolBar$Separator1); - pageSetupButton = new JButton(); - pageSetupButton.setText("Page Setup"); - toolBar1.add(pageSetupButton); - final JToolBar.Separator toolBar$Separator2 = new JToolBar.Separator(); - toolBar1.add(toolBar$Separator2); - zoomComboBox = new JComboBox(); - zoomComboBox.setBackground(new Color(-1)); - zoomComboBox.setMaximumSize(new Dimension(130, 30)); - zoomComboBox.setMinimumSize(new Dimension(130, 23)); - zoomComboBox.setRequestFocusEnabled(false); - toolBar1.add(zoomComboBox); - final JToolBar.Separator toolBar$Separator3 = new JToolBar.Separator(); - toolBar1.add(toolBar$Separator3); - final JPanel panel1 = new JPanel(); - panel1.setLayout(new com.intellij.uiDesigner.core.GridLayoutManager(1, 5, new Insets(0, 0, 0, 0), -1, -1)); - panel1.setMaximumSize(new Dimension(175, 2147483647)); - panel1.setMinimumSize(new Dimension(175, 24)); - panel1.setOpaque(false); - toolBar1.add(panel1); - panel1.add(firstPageButton, new com.intellij.uiDesigner.core.GridConstraints(0, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_NONE, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); - panel1.add(previousPageButton, new com.intellij.uiDesigner.core.GridConstraints(0, 1, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_NONE, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); - panel1.add(nextPageButton, new com.intellij.uiDesigner.core.GridConstraints(0, 3, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_NONE, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); - panel1.add(lastPageButton, new com.intellij.uiDesigner.core.GridConstraints(0, 4, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_NONE, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); - pageNumberTextBox = new JTextPane(); - pageNumberTextBox.setEditable(false); - panel1.add(pageNumberTextBox, new com.intellij.uiDesigner.core.GridConstraints(0, 2, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_BOTH, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_WANT_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_WANT_GROW, new Dimension(40, 20), new Dimension(40, 20), new Dimension(40, 20), 0, false)); - final JToolBar.Separator toolBar$Separator4 = new JToolBar.Separator(); - toolBar1.add(toolBar$Separator4); - closeButton = new JButton(); - closeButton.setText("Close"); - toolBar1.add(closeButton); - documentViewer = new JScrollPane(); - documentViewer.setVerticalScrollBarPolicy(20); - contentPane.add(documentViewer, BorderLayout.CENTER); - imageLabel = new JLabel(); - imageLabel.setHorizontalAlignment(0); - imageLabel.setHorizontalTextPosition(0); - imageLabel.setMaximumSize(new Dimension(500, 500)); - imageLabel.setMinimumSize(new Dimension(500, 500)); - imageLabel.setPreferredSize(new Dimension(500, 500)); - imageLabel.setRequestFocusEnabled(true); - imageLabel.setText(""); - documentViewer.setViewportView(imageLabel); - final JPanel panel2 = new JPanel(); - panel2.setLayout(new com.intellij.uiDesigner.core.GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1)); - contentPane.add(panel2, BorderLayout.SOUTH); - progressBar = new JProgressBar(); - progressBar.setPreferredSize(new Dimension(60, 14)); - panel2.add(progressBar, new com.intellij.uiDesigner.core.GridConstraints(0, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_NONE, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, null, new Dimension(300, 10), null, 0, false)); - } - - /** - * @noinspection ALL - */ - public JComponent $$$getRootComponent$$$() { - return contentPane; - } - - /** - * A simple extension of the BasicArrowButton which displays two arrows instead of one. - */ - public class DoubleArrowButton extends BasicArrowButton { - public DoubleArrowButton(int type) { - super(type); - mArrowType = type; - } - - public void paintTriangle(Graphics g, int x, int y, int size, - int direction, boolean isEnabled) { - - super.paintTriangle(g, x - (size / 2), y, size, mArrowType, isEnabled); - super.paintTriangle(g, x + (size / 2), y, size, mArrowType, isEnabled); - } - - private int mArrowType; - } -} - diff --git a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/ReceiveNotificationOfMissingFontsAndFontSubstitution.java b/Examples/src/main/java/com/aspose/words/examples/rendering_printing/ReceiveNotificationOfMissingFontsAndFontSubstitution.java deleted file mode 100644 index aecc948c..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/ReceiveNotificationOfMissingFontsAndFontSubstitution.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.aspose.words.examples.rendering_printing; - -import com.aspose.words.Document; -import com.aspose.words.FontSettings; -import com.aspose.words.PdfSaveOptions; -import com.aspose.words.examples.Utils; - -public class ReceiveNotificationOfMissingFontsAndFontSubstitution { - - private static final String dataDir = Utils.getSharedDataDir(ReceiveNotificationOfMissingFontsAndFontSubstitution.class) + "RenderingAndPrinting/"; - - public static void main(String[] args) throws Exception { - // Load the document to render. - Document doc = new Document(dataDir + "Rendering.doc"); - - // We can choose the default font to use in the case of any missing fonts. - FontSettings.getDefaultInstance().setDefaultFontName("Arial"); - - // For testing we will set Aspose.Words to look for fonts only in a folder which doesn't exist. Since Aspose.Words won't - // find any fonts in the specified directory, then during rendering the fonts in the document will be subsuited with the default - // font specified under FontSettings.DefaultFontName. We can pick up on this subsuition using our callback. - FontSettings.getDefaultInstance().setFontsFolder("", false); - - // Create a new class implementing IWarningCallback which collect any warnings produced during document save. - HandleDocumentWarnings callback = new HandleDocumentWarnings(); - - doc.setWarningCallback(callback); - - // Pass the save options along with the save path to the save method. - doc.save(dataDir + "Rendering.MissingFontNotification Out.pdf"); - - getNotificationBeforeSaving(doc); - } - - public static void getNotificationBeforeSaving(Document doc) throws Exception { - doc.updatePageLayout(); - - // Create a new class implementing IWarningCallback and assign it to the PdfSaveOptions class. - HandleDocumentWarnings callback = new HandleDocumentWarnings(); - PdfSaveOptions saveOptions = new PdfSaveOptions(); - doc.setWarningCallback(callback); - - // Even though the document was rendered previously, any save warnings are notified to the user during document save. - doc.save(dataDir + "Rendering.FontsNotificationUpdatePageLayout Out.pdf"); - } - -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/RenderShapes.java b/Examples/src/main/java/com/aspose/words/examples/rendering_printing/RenderShapes.java deleted file mode 100644 index 6d5efd0e..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/RenderShapes.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright 2001-2015 Aspose Pty Ltd. All Rights Reserved. - * - * This file is part of Aspose.Words. The source code in this file - * is only intended as a supplement to the documentation, and is provided - * "as is", without warranty of any kind, either expressed or implied. - */ - -package com.aspose.words.examples.rendering_printing; - -import com.aspose.words.*; -import com.aspose.words.Shape; -import com.aspose.words.examples.Utils; - -import javax.imageio.ImageIO; -import java.awt.*; -import java.awt.geom.Point2D; -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; - -public class RenderShapes -{ - public static void main(String[] args) throws Exception - { - // The path to the documents directory. - String dataDir = Utils.getDataDir(RenderShapes.class); - - // Load the documents which store the shapes we want to render. - Document doc = new Document(dataDir + "TestFile.doc"); - Document doc2 = new Document(dataDir + "TestFile.docx"); - - // Retrieve the target shape from the document. In our sample document this is the first shape. - Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); - Shape drawingML = (Shape)doc2.getChild(NodeType.SHAPE, 0, true); - - // Test rendering of different types of nodes. - RenderShapeToDisk(dataDir, shape); - RenderShapeToStream(dataDir, shape); - RenderShapeToGraphics(dataDir, shape); - RenderDrawingMLToDisk(dataDir, drawingML); - RenderCellToImage(dataDir, doc); - RenderRowToImage(dataDir, doc); - RenderParagraphToImage(dataDir, doc); - FindShapeSizes(shape); - } - - public static void RenderShapeToDisk(String dataDir, Shape shape) throws Exception - { - ShapeRenderer r = shape.getShapeRenderer(); - - // Define custom options which control how the image is rendered. Render the shape to the JPEG raster format. - ImageSaveOptions imageOptions = new ImageSaveOptions(SaveFormat.JPEG); - - imageOptions.setScale(1.5f); - - // Save the rendered image to disk. - r.save(dataDir + "TestFile.RenderToDisk Out.jpg", imageOptions); - - System.out.println("Shape rendered to disk successfully."); - } - - public static void RenderShapeToStream(String dataDir, Shape shape) throws Exception - { - ShapeRenderer r = new ShapeRenderer(shape); - - // Define custom options which control how the image is rendered. Render the shape to the vector format EMF. - ImageSaveOptions imageOptions = new ImageSaveOptions(SaveFormat.PNG) { - }; - - // Output the image in gray scale - imageOptions.setImageColorMode(ImageColorMode.GRAYSCALE); - - // Reduce the brightness a bit (default is 0.5f). - imageOptions.setImageBrightness(0.45f); - - - FileOutputStream stream = new FileOutputStream(dataDir + "TestFile.RenderToStream Out.jpg"); - - // Save the rendered image to the stream using different options. - r.save(stream, imageOptions); - - System.out.println("Shape rendered to stream successfully."); - } - - public static void RenderDrawingMLToDisk(String dataDir, Shape drawingML) throws Exception - { - // Save the DrawingML image to disk in JPEG format and using default options. - drawingML.getShapeRenderer().save(dataDir + "TestFile.RenderDrawingML Out.jpg", null); - - System.out.println("Shape rendered to disk successfully."); - } - - public static void RenderShapeToGraphics(String dataDir, Shape shape) throws Exception - { - // The shape renderer is retrieved using this method. This is made into a separate object from the shape as it internally - // caches the rendered shape. - ShapeRenderer r = shape.getShapeRenderer(); - - // Find the size that the shape will be rendered to at the specified scale and resolution. - Dimension shapeSizeInPixels = r.getSizeInPixels(1.0f, 96.0f); - - // Rotating the shape may result in clipping as the image canvas is too small. Find the longest side - // and make sure that the graphics canvas is large enough to compensate for this. - int maxSide = Math.max(shapeSizeInPixels.width, shapeSizeInPixels.height); - - BufferedImage image = new BufferedImage((int) (maxSide * 1.25), (int) (maxSide * 1.25), BufferedImage.TYPE_INT_ARGB); - - // Rendering to a graphics object means we can specify settings and transformations to be applied to - // the shape that is rendered. In our case we will rotate the rendered shape. - Graphics2D gr = (Graphics2D)image.getGraphics(); - - - // Clear the shape with the background color of the document. - gr.setBackground(shape.getDocument().getPageColor()); - gr.clearRect(0, 0, image.getWidth(), image.getHeight()); - // Center the rotation using translation method below - gr.translate(image.getWidth() / 8, image.getHeight() / 2); - // Rotate the image by 45 degrees. - gr.rotate(45 * Math.PI / 180); - // Undo the translation. - gr.translate(-image.getWidth() / 8, -image.getHeight() / 2); - - // Render the shape onto the graphics object. - r.renderToSize(gr, 0, 0, shapeSizeInPixels.width, shapeSizeInPixels.height); - - ImageIO.write(image, "png", new File(dataDir + "TestFile.RenderToGraphics.png")); - - gr.dispose(); - - System.out.println("Shape rendered to Graphics successfully."); - } - - public static void RenderCellToImage(String dataDir, Document doc) throws Exception - { - Cell cell = (Cell)doc.getChild(NodeType.CELL, 2, true); // The third cell in the first table. - RenderNode(cell, dataDir + "TestFile.RenderCell Out.png", null); - - System.out.println("Cell rendered to image successfully."); - } - - public static void RenderRowToImage(String dataDir, Document doc) throws Exception - { - Row row = (Row)doc.getChild(NodeType.ROW, 0, true); // The first row in the first table. - RenderNode(row, dataDir + "TestFile.RenderRow Out.png", null); - - System.out.println("Row rendered to image successfully."); - } - - public static void RenderParagraphToImage(String dataDir, Document doc) throws Exception - { - Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true); - Paragraph paragraph = shape.getLastParagraph(); - - // Save the node with a light pink background. - ImageSaveOptions options = new ImageSaveOptions(SaveFormat.PNG); - options.setPaperColor(new Color(255, 182, 193)); - - RenderNode(paragraph, dataDir + "TestFile.RenderParagraph Out.png", options); - - System.out.println("Paragraph rendered to image successfully."); - } - - public static void FindShapeSizes(Shape shape) throws Exception - { - Point2D.Float shapeSizeInDocument = shape.getShapeRenderer().getSizeInPoints(); - float width = shapeSizeInDocument.x; // The width of the shape. - float height = shapeSizeInDocument.y; // The height of the shape. - Dimension shapeRenderedSize = shape.getShapeRenderer().getSizeInPixels(1.0f, 96.0f); - - BufferedImage image = new BufferedImage(shapeRenderedSize.width, shapeRenderedSize.height, BufferedImage.TYPE_INT_RGB); - - Graphics gr = image.getGraphics(); - - // Render shape onto the graphics object using the RenderToScale or RenderToSize methods of ShapeRenderer class. - - gr.dispose(); - - } - - /// - /// Renders any node in a document to the path specified using the image save options. - /// - /// The node to render. - /// The path to save the rendered image to. - /// The image options to use during rendering. This can be null. - public static void RenderNode(Node node, String filePath, ImageSaveOptions imageOptions) throws Exception - { - // Run some argument checks. - if (node == null) - throw new IllegalArgumentException("Node cannot be null"); - - // If no image options are supplied, create default options. - if (imageOptions == null) - imageOptions = new ImageSaveOptions(FileFormatUtil.extensionToSaveFormat((filePath.split("\\.")[filePath.split("\\.").length - 1]))); - - // Store the paper color to be used on the final image and change to transparent. - // This will cause any content around the rendered node to be removed later on. - Color savePaperColor = imageOptions.getPaperColor(); - //imageOptions.PaperColor = Color.Transparent; - imageOptions.setPaperColor(new Color(0, 0, 0, 0)); - // There a bug which affects the cache of a cloned node. To avoid this we instead clone the entire document including all nodes, - // find the matching node in the cloned document and render that instead. - Document doc = (Document)node.getDocument().deepClone(true); - node = doc.getChild(NodeType.ANY, node.getDocument().getChildNodes(NodeType.ANY, true).indexOf(node), true); - - // Create a temporary shape to store the target node in. This shape will be rendered to retrieve - // the rendered content of the node. - Shape shape = new Shape(doc, ShapeType.TEXT_BOX); - Section parentSection = (Section)node.getAncestor(NodeType.SECTION); - - // Assume that the node cannot be larger than the page in size. - shape.setWidth(parentSection.getPageSetup().getPageWidth()); - shape.setHeight(parentSection.getPageSetup().getPageHeight()); - shape.setFillColor(new Color(0, 0, 0, 0)); // We must make the shape and paper color transparent. - - // Don't draw a surrounding line on the shape. - shape.setStroked(false); - - // Move up through the DOM until we find node which is suitable to insert into a Shape (a node with a parent can contain paragraph, tables the same as a shape). - // Each parent node is cloned on the way up so even a descendant node passed to this method can be rendered. - // Since we are working with the actual nodes of the document we need to clone the target node into the temporary shape. - Node currentNode = node; - while (!(currentNode.getParentNode() instanceof InlineStory - || currentNode.getParentNode() instanceof Story - || currentNode.getParentNode() instanceof ShapeBase)) - { - CompositeNode parent = (CompositeNode)currentNode.getParentNode().deepClone(false); - currentNode = currentNode.getParentNode(); - parent.appendChild(node.deepClone(true)); - node = parent; // Store this new node to be inserted into the shape. - } - - // We must add the shape to the document tree to have it rendered. - shape.appendChild(node.deepClone(true)); - parentSection.getBody().getFirstParagraph().appendChild(shape); - - // Render the shape to stream so we can take advantage of the effects of the ImageSaveOptions class. - // Retrieve the rendered image and remove the shape from the document. - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - shape.getShapeRenderer().save(stream, imageOptions); - shape.remove(); - - // Load the image into a new bitmap. - BufferedImage renderedImage = ImageIO.read(new ByteArrayInputStream(stream.toByteArray())); - - // Extract the actual content of the image by cropping transparent space around - // the rendered shape. - Rectangle cropRectangle = FindBoundingBoxAroundNode(renderedImage); - - BufferedImage croppedImage = new BufferedImage(cropRectangle.width, cropRectangle.height, BufferedImage.TYPE_INT_RGB); - - // Create the final image with the proper background color. - Graphics2D g = croppedImage.createGraphics(); - g.setBackground(savePaperColor); - g.clearRect(0, 0, croppedImage.getWidth(), croppedImage.getHeight()); - g.drawImage(renderedImage, - 0, 0, croppedImage.getWidth(), croppedImage.getHeight(), - cropRectangle.x, cropRectangle.y, cropRectangle.x + cropRectangle.width, cropRectangle.y + cropRectangle.height, - null); - - ImageIO.write(croppedImage, "png", new File(filePath)); - } - - /// - /// Finds the minimum bounding box around non-transparent pixels in a Bitmap. - /// - public static Rectangle FindBoundingBoxAroundNode(BufferedImage originalBitmap) - { - Point min = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE); - Point max = new Point(Integer.MIN_VALUE, Integer.MIN_VALUE); - - for (int x = 0; x < originalBitmap.getWidth(); ++x) - { - for (int y = 0; y < originalBitmap.getHeight(); ++y) - { - // For each pixel that is not transparent calculate the bounding box around it. - if (originalBitmap.getRGB(x, y) != 0) - { - min.x = Math.min(x, min.x); - min.y = Math.min(y, min.y); - max.x = Math.max(x, max.x); - max.y = Math.max(y, max.y); - } - } - } - - // Add one pixel to the width and height to avoid clipping. - return new Rectangle(min.x, min.y, (max.x - min.x) + 1, (max.y - min.y) + 1); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/SaveAsMultipageTiff.java b/Examples/src/main/java/com/aspose/words/examples/rendering_printing/SaveAsMultipageTiff.java deleted file mode 100644 index b4cf08ab..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/SaveAsMultipageTiff.java +++ /dev/null @@ -1,31 +0,0 @@ - -package com.aspose.words.examples.rendering_printing; - -import com.aspose.words.Document; -import com.aspose.words.ImageSaveOptions; -import com.aspose.words.SaveFormat; -import com.aspose.words.TiffCompression; -import com.aspose.words.examples.Utils; - -public class SaveAsMultipageTiff { - - private static final String dataDir = Utils.getSharedDataDir(SaveAsMultipageTiff.class) + "RenderingAndPrinting/"; - - public static void main(String[] args) throws Exception { - - // Open the document. - Document doc = new Document(dataDir + "TestFile.doc"); - // Save the document as multipage TIFF. - doc.save(dataDir + "TestFile Out.tiff"); - - //Create an ImageSaveOptions object to pass to the Save method - ImageSaveOptions options = new ImageSaveOptions(SaveFormat.TIFF); - options.setPageIndex(0); - options.setPageCount(2); - options.setTiffCompression(TiffCompression.CCITT_4); - options.setResolution(160); - doc.save(dataDir + "TestFileWithOptions Out.tiff", options); - - System.out.println("Document saved as multi page TIFF successfully."); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/SpecifyDefaultFontToUseWhenRendering.java b/Examples/src/main/java/com/aspose/words/examples/rendering_printing/SpecifyDefaultFontToUseWhenRendering.java deleted file mode 100644 index cb69c49e..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/SpecifyDefaultFontToUseWhenRendering.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.aspose.words.examples.rendering_printing; - -import com.aspose.words.Document; -import com.aspose.words.FontSettings; -import com.aspose.words.examples.Utils; - -public class SpecifyDefaultFontToUseWhenRendering { - - private static final String dataDir = Utils.getSharedDataDir(SpecifyDefaultFontToUseWhenRendering.class) + "RenderingAndPrinting/"; - - public static void main(String[] args) throws Exception { - - Document doc = new Document(dataDir + "Rendering.doc"); - - // If the default font defined here cannot be found during rendering then the closest font on the machine is used instead. - FontSettings.getDefaultInstance().setDefaultFontName("Arial Unicode MS"); - - // Now the set default font is used in place of any missing fonts during any rendering calls. - doc.save(dataDir + "Rendering.SetDefaultFont Out.pdf"); - doc.save(dataDir + "Rendering.SetDefaultFont Out.xps"); - } - -} diff --git a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/SpecifyTrueTypeFontsLocation.java b/Examples/src/main/java/com/aspose/words/examples/rendering_printing/SpecifyTrueTypeFontsLocation.java deleted file mode 100644 index 45318d7a..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/rendering_printing/SpecifyTrueTypeFontsLocation.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.aspose.words.examples.rendering_printing; - -import java.util.ArrayList; -import java.util.Arrays; - -import com.aspose.words.Document; -import com.aspose.words.FolderFontSource; -import com.aspose.words.FontSettings; -import com.aspose.words.FontSourceBase; -import com.aspose.words.examples.Utils; - -public class SpecifyTrueTypeFontsLocation { - - private static final String dataDir = Utils.getSharedDataDir(SpecifyTrueTypeFontsLocation.class) + "RenderingAndPrinting/"; - - public static void main(String[] args) throws Exception { - // Specifying a Font Folder - specifyAFontFolder(); - - // Specifying Multiple Font Folders - specifyMultipleFontFolders(); - - // Specifying Fonts to be Read from both the System Fonts Folder and a Custom Folder - specifyFontsFromBothSystemFontsFolderAndCustomFolder(); - } - - public static void specifyAFontFolder() throws Exception { - Document doc = new Document(dataDir + "Rendering.doc"); - - // Note that this setting will override any default font sources that are being searched by default. Now only these folders will be searched for - // fonts when rendering or embedding fonts. To add an extra font source while keeping system font sources then use both FontSettings.GetFontSources and - // FontSettings.SetFontSources instead. - FontSettings.getDefaultInstance().setFontsFolder("/Users/username/MyFonts/", false); - - doc.save(dataDir + "Rendering.SpecifyingAFontFolder_Out.pdf"); - } - - public static void specifyMultipleFontFolders() throws Exception { - Document doc = new Document(dataDir + "Rendering.doc"); - - // Note that this setting will override any default font sources that are being searched by default. Now only these folders will be searched for - // fonts when rendering or embedding fonts. To add an extra font source while keeping system font sources then use both FontSettings.GetFontSources and - // FontSettings.SetFontSources instead. - FontSettings.getDefaultInstance().setFontsFolders(new String[] { "/Users/username/MyFonts/", "/Users/username/Documents/Fonts/" }, true); - - doc.save(dataDir + "Rendering.SpecifyMultipleFontFolders_Out.pdf"); - } - - public static void specifyFontsFromBothSystemFontsFolderAndCustomFolder() throws Exception { - Document doc = new Document(dataDir + "Rendering.doc"); - - // Retrieve the array of environment-dependent font sources that are searched by default. - // For example this will contain a "Windows\Fonts\" source on a Windows machines and /Library/Fonts/ on Mac OS X. - // We add this array to a new ArrayList to make adding or removing font entries much easier. - ArrayList fontSources = new ArrayList(Arrays.asList(FontSettings.getDefaultInstance().getFontsSources())); - - // Add a new folder source which will instruct Aspose.Words to search the following folder for fonts. - FolderFontSource folderFontSource = new FolderFontSource("/Users/username/MyFonts/", true); - - // Add the custom folder which contains our fonts to the list of existing font sources. - fontSources.add(folderFontSource); - - // Convert the ArrayList of source back into a primitive array of FontSource objects. - FontSourceBase[] updatedFontSources = fontSources.toArray(new FontSourceBase[fontSources.size()]); - - // Apply the new set of font sources to use. - FontSettings.getDefaultInstance().setFontsSources(updatedFontSources); - - doc.save(dataDir + "Rendering.SpecifyFontsToBeReadFromBothSystemFontsFolderAndCustomFolder_Out.pdf"); - } -} diff --git a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/AboutForm.java b/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/AboutForm.java deleted file mode 100644 index f777e1c3..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/AboutForm.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright 2001-2014 Aspose Pty Ltd. All Rights Reserved. - * - * This file is part of Aspose.Words. The source code in this file - * is only intended as a supplement to the documentation, and is provided - * "as is", without warranty of any kind, either expressed or implied. - */ -package com.aspose.words.examples.viewers_visualizers.document_explorer; - -public class AboutForm extends javax.swing.JDialog { - - /** - * Creates new form AboutForm - */ - public AboutForm() { - - /* Set the Nimbus look and feel */ - // - /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. - * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html - */ - try { - for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { - if ("Nimbus".equals(info.getName())) { - javax.swing.UIManager.setLookAndFeel(info.getClassName()); - break; - } - } - } catch (ClassNotFoundException ex) { - java.util.logging.Logger.getLogger(MainForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); - } catch (InstantiationException ex) { - java.util.logging.Logger.getLogger(MainForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); - } catch (IllegalAccessException ex) { - java.util.logging.Logger.getLogger(MainForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); - } catch (javax.swing.UnsupportedLookAndFeelException ex) { - java.util.logging.Logger.getLogger(MainForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); - } - // - - initComponents(); - } - - /** - * This method is called from within the constructor to initialize the form. - * WARNING: Do NOT modify this code. The content of this method is always - * regenerated by the Form Editor. - */ - @SuppressWarnings("unchecked") - // //GEN-BEGIN:initComponents - private void initComponents() { - - jSplitPane1 = new javax.swing.JSplitPane(); - jPanel1 = new javax.swing.JPanel(); - jLabel2 = new javax.swing.JLabel(); - jScrollPane1 = new javax.swing.JScrollPane(); - jTextPane1 = new javax.swing.JTextPane(); - jSplitPane2 = new javax.swing.JSplitPane(); - jScrollPane2 = new javax.swing.JScrollPane(); - jTextPane2 = new javax.swing.JTextPane(); - jScrollPane3 = new javax.swing.JScrollPane(); - jTextPane3 = new javax.swing.JTextPane(); - jPanel2 = new javax.swing.JPanel(); - jLabel1 = new javax.swing.JLabel(); - closeButton = new javax.swing.JButton(); - - setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - setIconImages(null); - setModalExclusionType(null); - setName("AboutForm"); // NOI18N - setResizable(false); - - jSplitPane1.setDividerLocation(200); - - jPanel1.setBackground(new java.awt.Color(255, 255, 255)); - - jLabel2.setBackground(new java.awt.Color(255, 255, 255)); - jLabel2.setForeground(new java.awt.Color(255, 255, 255)); - jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); - jLabel2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/viewersandvisualizers/documentexplorer/java/images/aspose.gif"))); // NOI18N - jLabel2.setIconTextGap(0); - - javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); - jPanel1.setLayout(jPanel1Layout); - jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 199, Short.MAX_VALUE) - ); - jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 199, Short.MAX_VALUE) - ); - - jSplitPane1.setLeftComponent(jPanel1); - - jScrollPane1.setViewportView(jTextPane1); - - jSplitPane1.setRightComponent(jScrollPane1); - - jSplitPane2.setDividerLocation(70); - jSplitPane2.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); - jSplitPane2.setEnabled(false); - - jTextPane2.setEditable(false); - jTextPane2.setBorder(null); - jTextPane2.setFont(new java.awt.Font("Verdana", 1, 24)); // NOI18N - jTextPane2.setText("Document Explorer Demo for Aspose.Words "); - jScrollPane2.setViewportView(jTextPane2); - - jSplitPane2.setTopComponent(jScrollPane2); - - jTextPane3.setEditable(false); - jTextPane3.setBorder(null); - jTextPane3.setText("Use DocumentExplorer to:\n- Learn from source code how to use Aspose.Words in your project.\n- Visually explore document elements in the Aspose.Words Object Model.\nusing Aspose.Words.\n- Quickly convert between DOC, DOCX, ODF, EPUB, PDF, RTF, SWF, WordML, HTML, MHTML and plain text formats.\n"); - jScrollPane3.setViewportView(jTextPane3); - - jSplitPane2.setRightComponent(jScrollPane3); - - jSplitPane1.setRightComponent(jSplitPane2); - - jLabel1.setFont(new java.awt.Font("Verdana", 0, 14)); // NOI18N - jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); - jLabel1.setText("Copyright 2002-2011 Aspose Pty Ltd. All Rights Reserved. "); - - javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); - jPanel2.setLayout(jPanel2Layout); - jPanel2Layout.setHorizontalGroup( - jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addGap(108, 108, 108) - .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 529, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(87, Short.MAX_VALUE)) - ); - jPanel2Layout.setVerticalGroup( - jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 34, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 11, Short.MAX_VALUE)) - ); - - closeButton.setLabel("OK"); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); - getContentPane().setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addGroup(layout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) - .addComponent(closeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 59, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap()) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 201, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(closeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap()) - ); - - pack(); - }// //GEN-END:initComponents - // Variables declaration - do not modify//GEN-BEGIN:variables - protected javax.swing.JButton closeButton; - private javax.swing.JLabel jLabel1; - private javax.swing.JLabel jLabel2; - private javax.swing.JPanel jPanel1; - private javax.swing.JPanel jPanel2; - private javax.swing.JScrollPane jScrollPane1; - private javax.swing.JScrollPane jScrollPane2; - private javax.swing.JScrollPane jScrollPane3; - private javax.swing.JSplitPane jSplitPane1; - private javax.swing.JSplitPane jSplitPane2; - private javax.swing.JTextPane jTextPane1; - private javax.swing.JTextPane jTextPane2; - private javax.swing.JTextPane jTextPane3; - // End of variables declaration//GEN-END:variables -} diff --git a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/DocumentExplorer.java b/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/DocumentExplorer.java deleted file mode 100644 index 78c0d9a2..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/DocumentExplorer.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2001-2014 Aspose Pty Ltd. All Rights Reserved. - * - * This file is part of Aspose.Words. The source code in this file - * is only intended as a supplement to the documentation, and is provided - * "as is", without warranty of any kind, either expressed or implied. - */ -package com.aspose.words.examples.viewers_visualizers.document_explorer; - -import com.aspose.words.examples.*; - -public class DocumentExplorer { - - public static void main(String[] args) throws Exception { - // The path to the documents directory. - String dataDir = com.aspose.words.examples.Utils.getDataDir(DocumentExplorer.class); - - new Main(); - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/Globals.java b/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/Globals.java deleted file mode 100644 index 18ca5497..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/Globals.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2001-2014 Aspose Pty Ltd. All Rights Reserved. - * - * This file is part of Aspose.Words. The source code in this file - * is only intended as a supplement to the documentation, and is provided - * "as is", without warranty of any kind, either expressed or implied. - */ -package com.aspose.words.examples.viewers_visualizers.document_explorer; - -import com.aspose.words.Document; - -import javax.swing.*; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeModel; - -/** -* This class is used as a repository for objects, that should be available from any place of the project code. -*/ -public class Globals -{ - /** - * This class is purely static, that's why we prevent instance creation by declaring the constructor as private. - */ - private Globals() {} - - // Titles used within the application. - static final String APPLICATION_TITLE = "Document Explorer"; - static final String UNEXPECTED_EXCEPTION_DIALOG_TITLE = APPLICATION_TITLE + " - unexpected error occured"; - static final String OPEN_DOCUMENT_DIALOG_TITLE = "Open Document"; - static final String SAVE_DOCUMENT_DIALOG_TITLE = "Save Document As"; - - // Open File filters - static final OpenFileFilter OPEN_FILE_FILTER_ALL_SUPPORTED_FORMATS = new OpenFileFilter( - new String[] {".doc",".dot",".docx",".dotx",".docm",".dotm",".xml",".wml",".rtf",".odt",".ott",".htm",".html",".xhtml",".mht",".mhtm",".mhtml"}, "All Supported Formats (*.doc;*.dot;*.docx;*.dotx;*.docm;*.dotm;*.xml;*.wml;*.rtf;*.odt;*.ott;*.htm;*.html;*.xhtml;*.mht;*.mhtm;*.mhtml)"); - - static final OpenFileFilter OPEN_FILE_FILTER_DOC_FORMAT = new OpenFileFilter( - new String[] {".doc", ".doct"}, "Word 97-2003 Documents (*.doc;*.dot)"); - - static final OpenFileFilter OPEN_FILE_FILTER_DOCX_FORMAT = new OpenFileFilter( - new String[] {".docx", ".dotx", ".docm", ".dotm"}, "Word 2007 OOXML Documents (*.docx;*.dotx;*.docm;*.dotm)"); - - static final OpenFileFilter OPEN_FILE_FILTER_XML_FORMAT = new OpenFileFilter( - new String[] {".xml", ".wml"}, "XML Documents (*.xml;*.wml)"); - - static final OpenFileFilter OPEN_FILE_FILTER_RTF_FORMAT = new OpenFileFilter( - new String[] {".rtf"}, "Rich Text Format (*.rtf)"); - - static final OpenFileFilter OPEN_FILE_FILTER_ODT_FORMAT = new OpenFileFilter( - new String[] {".odt", ".ott"}, "OpenDocument Text (*.odt;*.ott)"); - - static final OpenFileFilter OPEN_FILE_FILTER_HTML_FORMAT = new OpenFileFilter( - new String[] {".htm", ".html", ".xhtml", ".mht", ".mhtm", ".mhtml"}, "Web Pages (*.htm;*.html;*.xhtml;*.mht;*.mhtm;*.mhtml)"); - - // Save File Filters - static final SaveFileFilter SAVE_FILE_FILTER_DOC = new SaveFileFilter( - ".doc", "Word 97-2003 Document (*.doc)"); - - static final SaveFileFilter SAVE_FILE_FILTER_DOCX = new SaveFileFilter( - ".docx", "Word 2007 OOXML Document (*.docx)"); - - static final SaveFileFilter SAVE_FILE_FILTER_DOCM = new SaveFileFilter( - ".docm", "Word 2007 OOXML Macro-Enabled Document (*.docm)"); - - static final SaveFileFilter SAVE_FILE_FILTER_PDF = new SaveFileFilter( - ".pdf", "PDF (*.pdf)"); - - static final SaveFileFilter SAVE_FILE_FILTER_XPS = new SaveFileFilter( - ".xps", "XPS Document (*.xps)"); - - static final SaveFileFilter SAVE_FILE_FILTER_PDT = new SaveFileFilter( - ".odt", "OpenDocument Text (*.odt)"); - - static final SaveFileFilter SAVE_FILE_FILTER_HTML = new SaveFileFilter( - ".html", "Web Page (*.html)"); - - static final SaveFileFilter SAVE_FILE_FILTER_MHT = new SaveFileFilter( - ".mht", "Single File Web Page (*.mht)"); - - static final SaveFileFilter SAVE_FILE_FILTER_RTF = new SaveFileFilter( - ".rtf", "Rich Text Format (*.rtf)"); - - static final SaveFileFilter SAVE_FILE_FILTER_XML = new SaveFileFilter( - ".xml", "Word 2003 WordprocessingML (*.xml)"); - - static final SaveFileFilter SAVE_FILE_FILTER_FOPC = new SaveFileFilter( - ".fopc", "FlatOPC XML Document (*.fopc)"); - - static final SaveFileFilter SAVE_FILE_FILTER_TXT = new SaveFileFilter( - ".txt", "Plain Text (*.txt)"); - - static final SaveFileFilter SAVE_FILE_FILTER_EPUB = new SaveFileFilter( - ".epub", "IDPF EPUB Document (*.epub)"); - - static final SaveFileFilter SAVE_FILE_FILTER_SWF = new SaveFileFilter( - ".swf", "Macromedia Flash File (*.swf)"); - - static final SaveFileFilter SAVE_FILE_FILTER_XAML = new SaveFileFilter( - ".xaml", "XAML Fixed Document (*.xaml)"); - - /** - * Reference for application's main form. - */ - static MainForm mMainForm; - - /** - * Reference for currently loaded Document. - */ - static Document mDocument; - - /** - * Reference for current Tree Model - */ - static DefaultTreeModel mTreeModel; - - /** - * Reference for the current Tree - */ - static JTree mTree; - - /** - * Reference for the current root node. - */ - static DefaultMutableTreeNode mRootNode; -} diff --git a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/Item.java b/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/Item.java deleted file mode 100644 index 4cbc3a44..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/Item.java +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright 2001-2014 Aspose Pty Ltd. All Rights Reserved. - * - * This file is part of Aspose.Words. The source code in this file - * is only intended as a supplement to the documentation, and is provided - * "as is", without warranty of any kind, either expressed or implied. - */ -package com.aspose.words.examples.viewers_visualizers.document_explorer; - -import com.aspose.words.*; - -import javax.swing.*; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.TreeNode; -import javax.swing.tree.TreePath; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -/** -* Base class used to provide GUI representation for document nodes. -*/ -public class Item -{ - private Node mNode; - private DefaultMutableTreeNode mTreeNode; - private ImageIcon mIcon; - - private static ArrayList mControlCharFields; - private static Map mNodeTypes; - private static Map mHeaderFooterTypes; - private static Map mItemSet; - private static ArrayList mIconNames = new ArrayList(); - - /** - * Creates Item for the supplied document node. - */ - public Item(Node node) - { - mNode = node; - } - - /** - * Returns the node in the document that this Item represents. - */ - public Node getNode() - { - return mNode; - } - - /** - * The display name for this Item. Can be customized by overriding this method in inheriting classes. - */ - public String getName() throws Exception - { - return getNodeTypeString(mNode); - } - - /** - * The text of the corresponding document node. - */ - public String getText() throws Exception - { - String text = mNode.getText(); - - // Most control characters are converted to human readable form. - // E.g. [!PageBreak!], [!Cell!], etc. - for (Field fieldInfo : mControlCharFields) - { - if (fieldInfo.getType() == char.class && Modifier.isStatic(fieldInfo.getModifiers())) - { - Character ch = fieldInfo.getChar(null); - - // Represent a paragraph break using the special formatting marker. This makes the text easier to read. - if(fieldInfo.getName().equals("PARAGRAPH_BREAK_CHAR")) - text = text.replace(ch.toString(), "?" + "\n"); // JTextArea lines are separated using simple "\n" character and not using system independent new line character. - else - text = text.replace(ch.toString(), java.text.MessageFormat.format("[!{0}!]", fieldInfo.getName().replace("_CHAR", ""))); - } - } - - // All break chars should be supplemented with line feeds - text = text.replace("BREAK!]", "BREAK!]\n"); - return text; - } - - /** - * Creates a TreeNode for this item to be displayed in the Document Explorer TreeView control. - */ - public DefaultMutableTreeNode getTreeNode() throws Exception - { - if (mTreeNode == null) - { - mTreeNode = new DefaultMutableTreeNode(this); - if (!mIconNames.contains(getIconName())) - { - mIconNames.add(getIconName()); - } - - if (mNode instanceof CompositeNode && ((CompositeNode)mNode).getChildNodes().getCount() > 0) - { - mTreeNode.add(new DefaultMutableTreeNode("#dummy")); - } - } - return mTreeNode; - } - - /** - * Returns the icon to display in the Document Explorer TreeView control. - */ - public ImageIcon getIcon() throws Exception - { - if (mIcon == null) - { - mIcon = loadIcon(getIconName()); - if (mIcon == null) - mIcon = loadIcon("Node"); - } - return mIcon; - } - - /** - * The icon for this node can be customized by overriding this property in the inheriting classes. - * The name represents name of .ico file without extension located in the Icons folder of the project. - */ - protected String getIconName() throws Exception - { - return getClass().getSimpleName().replace("Item", ""); - } - - /** - * Provides lazy on-expand loading of underlying tree nodes. - */ - public void onExpand() throws Exception - { - if ("#dummy".equals(getTreeNode().getFirstChild().toString())) - { - getTreeNode().removeAllChildren(); - Globals.mTreeModel.reload(getTreeNode()); - for (Object o : ((CompositeNode)mNode).getChildNodes()) - { - Node n = (Node)o; - getTreeNode().add(Item.createItem(n).getTreeNode()); - } - } - } - - /** - * Loads and returns an icon from the assembly resource stream. - */ - private ImageIcon loadIcon(String iconName) - { - java.net.URL imgURL = MainForm.class.getResource("images/" + iconName + ".gif"); - if(imgURL != null) - return new ImageIcon(imgURL); - else - return null; - } - - /** - * Removes this node from the document and the tree. - */ - public void remove() throws Exception - { - if (this.isRemovable()) - { - mNode.remove(); - TreeNode parent = mTreeNode.getParent(); - mTreeNode.removeFromParent(); - Globals.mTreeModel.reload(parent); - TreePath path = new TreePath(Globals.mRootNode); - Globals.mTree.setSelectionPath(path); - } - } - - /** - * Returns if this node can be removed from the document. Some nodes such as the last paragraph in the - * document cannot be removed. - */ - public boolean isRemovable() - { - return true; - } - - /** - * Static ctor. - */ - static - { - // Populate a list of node types along with their class implementation. - mItemSet = new HashMap(); - for(Class itemClass : DocumentItems.class.getDeclaredClasses()) - { - try - { - String nodeTypeString = (String) itemClass.getField("NODE_TYPE_STRING").get(null); - mItemSet.put(nodeTypeString, itemClass.getName()); - } - catch (Exception e) - { - // IllegalAccessException, NoSuchFieldException or NoSuchMethodException - skip such exceptions if there are any. - } - } - - // Fill a list containing the information of each control char. - mControlCharFields = new ArrayList(); - Field[] fields = ControlChar.class.getFields(); - for(Field fieldInfo : fields) - { - if(fieldInfo.getType() == char.class && Modifier.isStatic(fieldInfo.getModifiers())) - { - if(!fieldInfo.getName().equals("SPACE_CHAR")) - mControlCharFields.add(fieldInfo); - } - } - - // Map node type integer values to their equivalent string name. - mNodeTypes = new HashMap(); - Field[] nodeTypefields = NodeType.class.getFields(); - - for(Field fieldInfo : nodeTypefields) - { - if (fieldInfo.getType() == int.class && Modifier.isStatic(fieldInfo.getModifiers())) - { - try - { - int integerValue = fieldInfo.getInt(null); - mNodeTypes.put(integerValue, fieldInfo.getName()); - } - catch (IllegalAccessException e) - { - // Skip any invalid fields. - } - } - } - - // Maps header/footer type integer values to string names. - mHeaderFooterTypes = new HashMap(); - fields = HeaderFooterType.class.getFields(); - - for(Field fieldInfo : fields) - { - if(fieldInfo.getType() == int.class && Modifier.isStatic(fieldInfo.getModifiers())) - { - try - { - int integerValue = fieldInfo.getInt(null); - mHeaderFooterTypes.put(integerValue, fieldInfo.getName()); - } - catch (IllegalAccessException e) - { - // Skip any invalid fields. - } - } - } - } - - /** - * Item class factory implementation. - */ - public static Item createItem(Node node) throws ClassNotFoundException, NoSuchMethodException, - IllegalAccessException, InvocationTargetException, - InstantiationException - { - String typeName = getNodeTypeString(node); - if (mItemSet.containsKey(typeName)) - return (Item)Class.forName(mItemSet.get(typeName)). - getConstructor(DocumentItems.class, Node.class). - newInstance(null, node); - else - return new Item(node); - } - - /** - * Object.toString method used by Tree. - */ - public String toString() - { - // Introduced non-checked RuntimeException on purpose to not change Object.toString() signature - try - { - return getName(); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - - /** - * Convert numerical representation of the node type to string. - */ - private static String getNodeTypeString(Node node) - { - int nodeType = node.getNodeType(); - if(mNodeTypes.containsKey(nodeType)) - return mNodeTypes.get(nodeType); - else - return ""; - } - - /** - * Convert numerical representation of HeaderFooter integer type to string. - */ - protected static String getHeaderFooterTypeAsString(HeaderFooter headerFooter) throws Exception - { - int headerFooterType = headerFooter.getHeaderFooterType(); - if(mHeaderFooterTypes.containsKey(headerFooterType)) - return mHeaderFooterTypes.get(headerFooterType); - else - return ""; - } -} \ No newline at end of file diff --git a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/Utils.java b/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/Utils.java deleted file mode 100644 index 33abf54a..00000000 --- a/Examples/src/main/java/com/aspose/words/examples/viewers_visualizers/document_explorer/Utils.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2001-2014 Aspose Pty Ltd. All Rights Reserved. - * - * This file is part of Aspose.Words. The source code in this file - * is only intended as a supplement to the documentation, and is provided - * "as is", without warranty of any kind, either expressed or implied. - */ -package com.aspose.words.examples.viewers_visualizers.document_explorer; - -import javax.swing.*; -import java.io.File; - -public class Utils { - - private Utils() { - } - - /* - * Gets the file extension of the passed file. - */ - public static String getExtension(String s) { - String ext = ""; - int i = s.lastIndexOf('.'); - - if (i > 0 && i < s.length() - 1) { - ext = s.substring(i + 1).toLowerCase(); - } - - return ext; - } - - /* - * Changes the extension of a file. - * - * Note: The extension should include a dot. - */ - public static File setExtension(File f, String ext) { - String name = f.getName(); - String newName; - - assert !"".equals(name) : "Empty file name."; - - // Don't change if the new extension is the same as the original. - if (name.endsWith(ext)) { - return f; - } - - int lastIndexOfDot = name.lastIndexOf('.'); - - if (lastIndexOfDot < 0) // File name without any extension. - { - newName = name + ext; - } else // Change the existing extension. - { - newName = name.substring(0, lastIndexOfDot) + ext; - } - - return new File(f.getParent(), newName); - } - - /** - * Returns an ImageIcon, or null if the path was invalid. - */ - public static ImageIcon createImageIcon(String path) { - java.net.URL imgURL = MainForm.class.getResource(path); - if (imgURL != null) { - return new ImageIcon(imgURL); - } else { - return null; - } - } -} \ No newline at end of file diff --git a/Examples/src/main/resources/Barcode/Document.docx b/Examples/src/main/resources/Barcode/Document.docx deleted file mode 100644 index 4276d8e8..00000000 Binary files a/Examples/src/main/resources/Barcode/Document.docx and /dev/null differ diff --git a/Examples/src/main/resources/Document/Document.doc b/Examples/src/main/resources/Document/Document.doc deleted file mode 100644 index f22b1228..00000000 Binary files a/Examples/src/main/resources/Document/Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/Document/DocumentA.doc b/Examples/src/main/resources/Document/DocumentA.doc deleted file mode 100644 index 271621c6..00000000 Binary files a/Examples/src/main/resources/Document/DocumentA.doc and /dev/null differ diff --git a/Examples/src/main/resources/Document/DocumentB.doc b/Examples/src/main/resources/Document/DocumentB.doc deleted file mode 100755 index 8cf6e39d..00000000 Binary files a/Examples/src/main/resources/Document/DocumentB.doc and /dev/null differ diff --git a/Examples/src/main/resources/Document/Properties.doc b/Examples/src/main/resources/Document/Properties.doc deleted file mode 100755 index f6c21ed9..00000000 Binary files a/Examples/src/main/resources/Document/Properties.doc and /dev/null differ diff --git a/Examples/src/main/resources/DocumentObjectModel/Document.doc b/Examples/src/main/resources/DocumentObjectModel/Document.doc deleted file mode 100755 index cc74d18a..00000000 Binary files a/Examples/src/main/resources/DocumentObjectModel/Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/DocumentObjectModel/Node.RecurseAllNodes.doc b/Examples/src/main/resources/DocumentObjectModel/Node.RecurseAllNodes.doc deleted file mode 100755 index 916c5799..00000000 Binary files a/Examples/src/main/resources/DocumentObjectModel/Node.RecurseAllNodes.doc and /dev/null differ diff --git a/Examples/src/main/resources/ExtractedSelectedContentBetweenNodes/Visitor.ToText.doc b/Examples/src/main/resources/ExtractedSelectedContentBetweenNodes/Visitor.ToText.doc deleted file mode 100755 index d56c5f66..00000000 Binary files a/Examples/src/main/resources/ExtractedSelectedContentBetweenNodes/Visitor.ToText.doc and /dev/null differ diff --git a/Examples/src/main/resources/Fields/RenameMergeFields.doc b/Examples/src/main/resources/Fields/RenameMergeFields.doc deleted file mode 100755 index c5ad164a..00000000 Binary files a/Examples/src/main/resources/Fields/RenameMergeFields.doc and /dev/null differ diff --git a/Examples/src/main/resources/FindAndReplace/Field.ReplaceTextWithFields.doc b/Examples/src/main/resources/FindAndReplace/Field.ReplaceTextWithFields.doc deleted file mode 100755 index 5a8bcc4a..00000000 Binary files a/Examples/src/main/resources/FindAndReplace/Field.ReplaceTextWithFields.doc and /dev/null differ diff --git a/Examples/src/main/resources/FindAndReplace/Range.ReplaceWithEvaluator.doc b/Examples/src/main/resources/FindAndReplace/Range.ReplaceWithEvaluator.doc deleted file mode 100755 index 62b9b046..00000000 Binary files a/Examples/src/main/resources/FindAndReplace/Range.ReplaceWithEvaluator.doc and /dev/null differ diff --git a/Examples/src/main/resources/FindAndReplace/ReplaceWithRegex.doc b/Examples/src/main/resources/FindAndReplace/ReplaceWithRegex.doc deleted file mode 100755 index 62b9b046..00000000 Binary files a/Examples/src/main/resources/FindAndReplace/ReplaceWithRegex.doc and /dev/null differ diff --git a/Examples/src/main/resources/FindAndReplace/ReplaceWithString.doc b/Examples/src/main/resources/FindAndReplace/ReplaceWithString.doc deleted file mode 100644 index 1a079806..00000000 Binary files a/Examples/src/main/resources/FindAndReplace/ReplaceWithString.doc and /dev/null differ diff --git a/Examples/src/main/resources/FindAndReplace/TestFile.doc b/Examples/src/main/resources/FindAndReplace/TestFile.doc deleted file mode 100755 index 88abe746..00000000 Binary files a/Examples/src/main/resources/FindAndReplace/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/HeadersAndFooters/Aspose.Words.gif b/Examples/src/main/resources/HeadersAndFooters/Aspose.Words.gif deleted file mode 100755 index fa491bdd..00000000 Binary files a/Examples/src/main/resources/HeadersAndFooters/Aspose.Words.gif and /dev/null differ diff --git a/Examples/src/main/resources/HeadersAndFooters/HeaderFooter.RemoveFooters.doc b/Examples/src/main/resources/HeadersAndFooters/HeaderFooter.RemoveFooters.doc deleted file mode 100755 index 34cd18d1..00000000 Binary files a/Examples/src/main/resources/HeadersAndFooters/HeaderFooter.RemoveFooters.doc and /dev/null differ diff --git a/Examples/src/main/resources/Hyperlink/ReplaceHyperlinks.docx b/Examples/src/main/resources/Hyperlink/ReplaceHyperlinks.docx deleted file mode 100644 index acf364c2..00000000 Binary files a/Examples/src/main/resources/Hyperlink/ReplaceHyperlinks.docx and /dev/null differ diff --git a/Examples/src/main/resources/InsertDocumentIntoAnother/InsertDocument1.doc b/Examples/src/main/resources/InsertDocumentIntoAnother/InsertDocument1.doc deleted file mode 100755 index d088765e..00000000 Binary files a/Examples/src/main/resources/InsertDocumentIntoAnother/InsertDocument1.doc and /dev/null differ diff --git a/Examples/src/main/resources/InsertDocumentIntoAnother/InsertDocument2.doc b/Examples/src/main/resources/InsertDocumentIntoAnother/InsertDocument2.doc deleted file mode 100755 index caeeb05f..00000000 Binary files a/Examples/src/main/resources/InsertDocumentIntoAnother/InsertDocument2.doc and /dev/null differ diff --git a/Examples/src/main/resources/LoadingSavingAndConverting/Document.doc b/Examples/src/main/resources/LoadingSavingAndConverting/Document.doc deleted file mode 100755 index cc74d18a..00000000 Binary files a/Examples/src/main/resources/LoadingSavingAndConverting/Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/MailMerge/Customers.mdb b/Examples/src/main/resources/MailMerge/Customers.mdb deleted file mode 100644 index 572929de..00000000 Binary files a/Examples/src/main/resources/MailMerge/Customers.mdb and /dev/null differ diff --git a/Examples/src/main/resources/MailMerge/Customers.xml b/Examples/src/main/resources/MailMerge/Customers.xml deleted file mode 100755 index 9ed59b20..00000000 --- a/Examples/src/main/resources/MailMerge/Customers.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/Examples/src/main/resources/MailMerge/Invoice Template.doc b/Examples/src/main/resources/MailMerge/Invoice Template.doc deleted file mode 100755 index 2013090d..00000000 Binary files a/Examples/src/main/resources/MailMerge/Invoice Template.doc and /dev/null differ diff --git a/Examples/src/main/resources/MailMerge/InvoiceDB.mdb b/Examples/src/main/resources/MailMerge/InvoiceDB.mdb deleted file mode 100644 index 043b3390..00000000 Binary files a/Examples/src/main/resources/MailMerge/InvoiceDB.mdb and /dev/null differ diff --git a/Examples/src/main/resources/MailMerge/MailMerge.AlternatingRows.doc b/Examples/src/main/resources/MailMerge/MailMerge.AlternatingRows.doc deleted file mode 100755 index f0be6091..00000000 Binary files a/Examples/src/main/resources/MailMerge/MailMerge.AlternatingRows.doc and /dev/null differ diff --git a/Examples/src/main/resources/MailMerge/MailMerge.ExecuteArray.doc b/Examples/src/main/resources/MailMerge/MailMerge.ExecuteArray.doc deleted file mode 100644 index bef8b12e..00000000 Binary files a/Examples/src/main/resources/MailMerge/MailMerge.ExecuteArray.doc and /dev/null differ diff --git a/Examples/src/main/resources/MailMerge/MailMerge.ExecuteWithRegions.doc b/Examples/src/main/resources/MailMerge/MailMerge.ExecuteWithRegions.doc deleted file mode 100755 index 2daa6c45..00000000 Binary files a/Examples/src/main/resources/MailMerge/MailMerge.ExecuteWithRegions.doc and /dev/null differ diff --git a/Examples/src/main/resources/MailMerge/MailMerge.MergeImage.doc b/Examples/src/main/resources/MailMerge/MailMerge.MergeImage.doc deleted file mode 100755 index 7daccedd..00000000 Binary files a/Examples/src/main/resources/MailMerge/MailMerge.MergeImage.doc and /dev/null differ diff --git a/Examples/src/main/resources/MailMerge/Northwind.mdb b/Examples/src/main/resources/MailMerge/Northwind.mdb deleted file mode 100755 index 2db0719c..00000000 Binary files a/Examples/src/main/resources/MailMerge/Northwind.mdb and /dev/null differ diff --git a/Examples/src/main/resources/MailMerge/Template.doc b/Examples/src/main/resources/MailMerge/Template.doc deleted file mode 100755 index 4049d5fd..00000000 Binary files a/Examples/src/main/resources/MailMerge/Template.doc and /dev/null differ diff --git a/Examples/src/main/resources/MailMerge/TestFile.doc b/Examples/src/main/resources/MailMerge/TestFile.doc deleted file mode 100755 index da89398c..00000000 Binary files a/Examples/src/main/resources/MailMerge/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/MailMerge/VendorTemplate.doc b/Examples/src/main/resources/MailMerge/VendorTemplate.doc deleted file mode 100644 index 22582cad..00000000 Binary files a/Examples/src/main/resources/MailMerge/VendorTemplate.doc and /dev/null differ diff --git a/Examples/src/main/resources/RenderingAndPrinting/Rendering.doc b/Examples/src/main/resources/RenderingAndPrinting/Rendering.doc deleted file mode 100755 index 6e97a1eb..00000000 Binary files a/Examples/src/main/resources/RenderingAndPrinting/Rendering.doc and /dev/null differ diff --git a/Examples/src/main/resources/RenderingAndPrinting/TestFile.doc b/Examples/src/main/resources/RenderingAndPrinting/TestFile.doc deleted file mode 100644 index 4373efc3..00000000 Binary files a/Examples/src/main/resources/RenderingAndPrinting/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/RenderingAndPrinting/in.docx b/Examples/src/main/resources/RenderingAndPrinting/in.docx deleted file mode 100755 index d6d7756d..00000000 Binary files a/Examples/src/main/resources/RenderingAndPrinting/in.docx and /dev/null differ diff --git a/Examples/src/main/resources/Styles/TestFile.doc b/Examples/src/main/resources/Styles/TestFile.doc deleted file mode 100644 index d6d7756d..00000000 Binary files a/Examples/src/main/resources/Styles/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/TableOfContents/Document.TableOfContents.doc b/Examples/src/main/resources/TableOfContents/Document.TableOfContents.doc deleted file mode 100755 index a8c29746..00000000 Binary files a/Examples/src/main/resources/TableOfContents/Document.TableOfContents.doc and /dev/null differ diff --git a/Examples/src/main/resources/Tables/Table.Document.doc b/Examples/src/main/resources/Tables/Table.Document.doc deleted file mode 100644 index 746320ca..00000000 Binary files a/Examples/src/main/resources/Tables/Table.Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/Tables/Table.EmptyTable.doc b/Examples/src/main/resources/Tables/Table.EmptyTable.doc deleted file mode 100755 index b5c3672a..00000000 Binary files a/Examples/src/main/resources/Tables/Table.EmptyTable.doc and /dev/null differ diff --git a/Examples/src/main/resources/Tables/Table.MergedCells.doc b/Examples/src/main/resources/Tables/Table.MergedCells.doc deleted file mode 100755 index e6b61c90..00000000 Binary files a/Examples/src/main/resources/Tables/Table.MergedCells.doc and /dev/null differ diff --git a/Examples/src/main/resources/Tables/Table.SimpleTable.doc b/Examples/src/main/resources/Tables/Table.SimpleTable.doc deleted file mode 100644 index f51042d6..00000000 Binary files a/Examples/src/main/resources/Tables/Table.SimpleTable.doc and /dev/null differ diff --git a/Examples/src/main/resources/Tables/Table.TableAcrossPage.doc b/Examples/src/main/resources/Tables/Table.TableAcrossPage.doc deleted file mode 100644 index 7e0faf24..00000000 Binary files a/Examples/src/main/resources/Tables/Table.TableAcrossPage.doc and /dev/null differ diff --git a/Examples/src/main/resources/Tables/Table.TableStyle.docx b/Examples/src/main/resources/Tables/Table.TableStyle.docx deleted file mode 100755 index cee0d5a4..00000000 Binary files a/Examples/src/main/resources/Tables/Table.TableStyle.docx and /dev/null differ diff --git a/Examples/src/main/resources/Tables/TestFile.doc b/Examples/src/main/resources/Tables/TestFile.doc deleted file mode 100644 index d6d7756d..00000000 Binary files a/Examples/src/main/resources/Tables/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/linq/BubbleChart/BubbleChart.docx b/Examples/src/main/resources/com/aspose/words/examples/linq/BubbleChart/BubbleChart.docx deleted file mode 100644 index f107e010..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/linq/BubbleChart/BubbleChart.docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/linq/BulletedList/BulletedList.doc b/Examples/src/main/resources/com/aspose/words/examples/linq/BulletedList/BulletedList.doc deleted file mode 100644 index 365025f5..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/linq/BulletedList/BulletedList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/linq/ChartWithFilteringGroupingOrdering/ChartWithFilteringGroupingOrdering.docx b/Examples/src/main/resources/com/aspose/words/examples/linq/ChartWithFilteringGroupingOrdering/ChartWithFilteringGroupingOrdering.docx deleted file mode 100644 index cdf9f8e9..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/linq/ChartWithFilteringGroupingOrdering/ChartWithFilteringGroupingOrdering.docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/linq/Common/photo.png b/Examples/src/main/resources/com/aspose/words/examples/linq/Common/photo.png deleted file mode 100644 index f3edba4a..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/linq/Common/photo.png and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/linq/CommonList/CommonList.doc b/Examples/src/main/resources/com/aspose/words/examples/linq/CommonList/CommonList.doc deleted file mode 100644 index 08c89187..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/linq/CommonList/CommonList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/linq/CommonMasterDetail/CommonMasterDetail.doc b/Examples/src/main/resources/com/aspose/words/examples/linq/CommonMasterDetail/CommonMasterDetail.doc deleted file mode 100644 index c7bb74d3..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/linq/CommonMasterDetail/CommonMasterDetail.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/linq/HelloWorld/HelloWorld.doc b/Examples/src/main/resources/com/aspose/words/examples/linq/HelloWorld/HelloWorld.doc deleted file mode 100644 index 7869c607..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/linq/HelloWorld/HelloWorld.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/linq/InParagraphList/InParagraphList.doc b/Examples/src/main/resources/com/aspose/words/examples/linq/InParagraphList/InParagraphList.doc deleted file mode 100644 index 6704bc95..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/linq/InParagraphList/InParagraphList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/linq/InTableAlternateContent/InTableAlternateContent - Copy.doc b/Examples/src/main/resources/com/aspose/words/examples/linq/InTableAlternateContent/InTableAlternateContent - Copy.doc deleted file mode 100644 index cd1536d5..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/linq/InTableAlternateContent/InTableAlternateContent - Copy.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/linq/InTableAlternateContent/InTableAlternateContent.doc b/Examples/src/main/resources/com/aspose/words/examples/linq/InTableAlternateContent/InTableAlternateContent.doc deleted file mode 100644 index 5ab7eebd..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/linq/InTableAlternateContent/InTableAlternateContent.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/linq/InTableAlternateContent/InTableList.doc b/Examples/src/main/resources/com/aspose/words/examples/linq/InTableAlternateContent/InTableList.doc deleted file mode 100644 index f1fc2aab..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/linq/InTableAlternateContent/InTableList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/linq/InTableList/InTableList.doc b/Examples/src/main/resources/com/aspose/words/examples/linq/InTableList/InTableList.doc deleted file mode 100644 index f1fc2aab..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/linq/InTableList/InTableList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/linq/InTableMasterDetail/InTableMasterDetail.doc b/Examples/src/main/resources/com/aspose/words/examples/linq/InTableMasterDetail/InTableMasterDetail.doc deleted file mode 100644 index 09f04433..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/linq/InTableMasterDetail/InTableMasterDetail.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/linq/InTableRow/InTableList.doc b/Examples/src/main/resources/com/aspose/words/examples/linq/InTableRow/InTableList.doc deleted file mode 100644 index 7e101ea2..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/linq/InTableRow/InTableList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/linq/InTableWithFilteringGroupingSorting/InTableWithFilteringGroupingSorting.doc b/Examples/src/main/resources/com/aspose/words/examples/linq/InTableWithFilteringGroupingSorting/InTableWithFilteringGroupingSorting.doc deleted file mode 100644 index 5c27f6a0..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/linq/InTableWithFilteringGroupingSorting/InTableWithFilteringGroupingSorting.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/linq/MulticoloredNumberedList/MulticoloredNumberedList.doc b/Examples/src/main/resources/com/aspose/words/examples/linq/MulticoloredNumberedList/MulticoloredNumberedList.doc deleted file mode 100644 index 4ab56c33..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/linq/MulticoloredNumberedList/MulticoloredNumberedList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/linq/NumberedList/NumberedList.doc b/Examples/src/main/resources/com/aspose/words/examples/linq/NumberedList/NumberedList.doc deleted file mode 100644 index 90e00b6e..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/linq/NumberedList/NumberedList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/linq/PieChart/PieChart.docx b/Examples/src/main/resources/com/aspose/words/examples/linq/PieChart/PieChart.docx deleted file mode 100644 index d807f69e..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/linq/PieChart/PieChart.docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/linq/ScatterChart/ScatterChart.docx b/Examples/src/main/resources/com/aspose/words/examples/linq/ScatterChart/ScatterChart.docx deleted file mode 100644 index 27003139..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/linq/ScatterChart/ScatterChart.docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/linq/SingleRow/SingleRow.doc b/Examples/src/main/resources/com/aspose/words/examples/linq/SingleRow/SingleRow.doc deleted file mode 100644 index bdb799e6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/linq/SingleRow/SingleRow.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (HTML).html b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (HTML).html deleted file mode 100644 index 485911f2..00000000 --- a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (HTML).html +++ /dev/null @@ -1,855 +0,0 @@ - - - - - - - - - - - - - - - - - - -
          - -

          3.6. Svnserve Based Server

          - -

          3.6.1. Introduction

          - -

          Subversion -includes Svnserve - a lightweight stand-alone server which uses a custom -protocol over an ordinary TCP/IP connection. It is ideal for smaller -installations, or where a full blown Apache server cannot be used.

          - -

          In most cases svnserve is easier -to setup and runs faster than the Apache based server, although it doesn't have -some of the advanced features. And now that SASL support is included it is easy -to secure as well.

          - -

          3.6.2. Installing svnserve

          - -

          1.      -Get the -latest version of Subversion from http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91 -. Alternatively get a pre-packaged installer from CollabNet at http://www.collab.net/downloads/subversion -. This installer will setup svnserve as a Windows service, and also -includes some of the tools you need if you are going to use SASL for security.

          - -

          2.      -If -you already have a version of Subversion installed, and svnserve is running, -you will need to stop it before continuing.

          - -

          3.      -Run -the Subversion installer. If you run the installer on your server (recommended) -you can skip step 4.

          - -

          4.      -Open -the windows-explorer, go to the installation directory of Subversion (usually C:\Program -Files\Subversion) and -in the bin directory, -find the files svnserve.exe, intl3_svn.dll, libapr.dll, libapriconv.dll, libapriutil.dll, libdb*.dll, libeay32.dll and ssleay32.dll - copy these files, or just copy all of -the bin directory, into a directory on your -server e.g. c:\svnserve

          - -

          3.6.3. Running svnserve

          - -

          Now that svnserve is installed, -you need it running on your server. The simplest approach is to run the -following from a DOS shell or create a windows shortcut:

          - -
          svnserve.exe --daemon
          - -

          svnserve will now start waiting for incoming -requests on port 3690. The --daemon switch tells svnserve -to run as a daemon process, so it will always exist until it is manually -terminated.

          - -

          If you have not yet created a -repository, follow the instructions given with the Apache server setup Section 3.7.4, Configuration.

          - -

          To test that svnserve is working, use TortoiseSVNRepo-Browser to view a repository.

          - -
          - - - - diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (JPG).jpg b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (JPG).jpg deleted file mode 100644 index 27430480..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (JPG).jpg and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (MHTML).mhtml b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (MHTML).mhtml deleted file mode 100644 index 2e20c971..00000000 --- a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (MHTML).mhtml +++ /dev/null @@ -1,1016 +0,0 @@ -MIME-Version: 1.0 -Content-Type: multipart/related; boundary="----=_NextPart_01CA0927.871204C0" - -This document is a Single File Web Page, also known as a Web Archive file. If you are seeing this message, your browser or editor doesn't support Web Archive files. Please download a browser that supports Web Archive, such as Windows Internet Explorer. - -------=_NextPart_01CA0927.871204C0 -Content-Location: file:///C:/8CB3C889/TestFile(doc).htm -Content-Transfer-Encoding: quoted-printable -Content-Type: text/html; charset="us-ascii" - - - - - - - - - - - - - - - - - - - -
          - -

          3.6. Svnserve Based Server

          - -

          3.6.1. Introduction

          - -

          Su= -bversion -includes Svnserve - a lightweight stand-alone server which uses a custom -protocol over an ordinary TCP/IP connection. It is ideal for smaller -installations, or where a full blown Apache server cannot be used.

          - -

          In most cases svnserve is= - easier -to setup and runs faster than the Apache based server, although it doesn't = -have -some of the advanced features. And now that SASL support is included it is = -easy -to secure as well.

          - -

          3.6.2. Installing svnserve

          - -

          1.      -Get the -latest version of Subversion from http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=3D= -91 -. Alternatively get a pre-packaged installer from CollabNet at http://www.c= -ollab.net/downloads/subversion -. This installer will setup svnserve as a Windows service, and also -includes some of the tools you need if you are going to use SASL for securi= -ty.

          - -

          2.      -If -you already have a version of Subversion installed, and svnserve is running, -you will need to stop it before continuing.

          - -

          3.      -Run -the Subversion installer. If you run the installer on your server (recommen= -ded) -you can skip step 4.

          - -

          4.      -Open -the windows-explorer, go to the installation directory of Subversion (usual= -ly C:\Program -Files\Subversion) and -in the bin direct= -ory, -find the files svnserve.exe, intl3_svn.dll, libapr.dll, libapriconv.dll, libapriutil.dll, libdb*.dll, libeay32.dll<= -span -lang=3DEN style=3D'mso-ansi-language:EN'> and ssleay32.dll<= -span -lang=3DEN style=3D'mso-ansi-language:EN'> - copy these files, or just copy = -all of -the bin directory, into a directory on yo= -ur -server e.g. c:\svnserve

          - -

          3.6.3. Running svnserve

          - -

          Now that svnserve is inst= -alled, -you need it running on your server. The simplest approach is to run the -following from a DOS shell or create a windows shortcut: = -

          - -
          svnserve.exe --daemon
          - -

          svnse= -rve will now start waiting for incomi= -ng -requests on port 3690. The --daemon switch tells svnser= -ve -to run as a daemon process, so it will always exist until it is manually -terminated.

          - -

          If you have not yet creat= -ed a -repository, follow the instructions given with the Apache server setup Section 3.7.4, -“Configuration”.

          - -

          To test that svnserve is = -working, use TortoiseSVN = -→ Repo-Browser to view a repository.

          - -
          - - - - - -------=_NextPart_01CA0927.871204C0 -Content-Location: file:///C:/8CB3C889/TestFile(doc)_files/themedata.thmx -Content-Transfer-Encoding: base64 -Content-Type: application/vnd.ms-officetheme - -UEsDBBQABgAIAAAAIQCCirwT+gAAABwCAAATAAAAW0NvbnRlbnRfVHlwZXNdLnhtbKyRy2rDMBBF -94X+g9C22HK6KKXYzqJJd30s0g8Y5LEtao+ENAnJ33fsuFC6CC10IxBizpl7Va6P46AOGJPzVOlV -XmiFZH3jqKv0++4pu9cqMVADgyes9AmTXtfXV+XuFDApmaZU6Z45PBiTbI8jpNwHJHlpfRyB5Ro7 -E8B+QIfmtijujPXESJzxxNB1+SoLRNegeoPILzCKx7Cg8Pv5DCSAmAtYq8czYVqi0hDC4CywRDAH -an7oM9+2zmLj7X4UaT6DF9jNBDO/XGD1P+ov5wZb2A+stkfp4lx/xCH9LdtSay6Tc/7Uu5AuGC6X -t7Rh5r+tPwEAAP//AwBQSwMEFAAGAAgAAAAhAKXWp+fAAAAANgEAAAsAAABfcmVscy8ucmVsc4SP -z2rDMAyH74W9g9F9UdLDGCV2L6WQQy+jfQDhKH9oIhvbG+vbT8cGCrsIhKTv96k9/q6L+eGU5yAW -mqoGw+JDP8to4XY9v3+CyYWkpyUIW3hwhqN727VfvFDRozzNMRulSLYwlRIPiNlPvFKuQmTRyRDS -SkXbNGIkf6eRcV/XH5ieGeA2TNP1FlLXN2Cuj6jJ/7PDMMyeT8F/ryzlRQRuN5RMaeRioagv41O9 -kKhlqtQe0LW4+db9AQAA//8DAFBLAwQUAAYACAAAACEAa3mWFoMAAACKAAAAHAAAAHRoZW1lL3Ro -ZW1lL3RoZW1lTWFuYWdlci54bWwMzE0KwyAQQOF9oXeQ2TdjuyhFYrLLrrv2AEOcGkHHoNKf29fl -44M3zt8U1ZtLDVksnAcNimXNLoi38Hwspxuo2kgcxSxs4ccV5ul4GMm0jRPfSchzUX0j1ZCFrbXd -INa1K9Uh7yzdXrkkaj2LR1fo0/cp4kXrKyYKAjj9AQAA//8DAFBLAwQUAAYACAAAACEAcgdl85gG -AABQGwAAFgAAAHRoZW1lL3RoZW1lL3RoZW1lMS54bWzsWU9v2zYUvw/YdyB0b2MndhoHdYrYsZst -TRvEboceaYmW2FCiQNJJfRva44ABw7phhxXYbYdhW4EW2KX7NNk6bB3Qr7BHUpLFWF6SNtiKrQ4Q -W+SP7/97fKSuXrsfM3RIhKQ8aXv1yzUPkcTnAU3Ctnd72L+05iGpcBJgxhPS9qZEetc23n/vKl5X -EYkJgvWJXMdtL1IqXV9akj4MY3mZpySBuTEXMVbwKMKlQOAjoBuzpeVabXUpxjTxUIJjIHtrPKY+ -QUNN0tvIifcYPCZK6gGfiYEmTZwVBhsc1DVCTmWXCXSIWdsDPgE/GpL7ykMMSwUTba/R1H/e0sbV -JbyeLWJqwdrSur75ZOuyBcHBsuEpwlHBtN5vtK5sFfQNgKl5XK/X6/bqBT0DwL4PmlpZyjQb/bV6 -J6dZAtmf87S7tWat4eJL9FfmZG51Op1mK5PFEjUg+7Mxh1+rrTY2lx28AVl8cw7f6Gx2u6sO3oAs -fnUO37/SWm24eAOKGE0O5tA1+PT7GfUCMuZsuxK+BvC1WgafoSAaiujSLMY8UYtiLcb3uOgDQAMZ -VjRBapqSMfYhirs4HgmKNQO8TnBpxg75cm5I80LSFzRVbe/DFENGzOi9ev79q+dP0fGDZ8cPfjp+ -+PD4wY+WkLNqGydhedXLbz/78/HH6I+n37x89EU1Xpbxv/7wyS8/f14NhPSZifPiyye/PXvy4qtP -f//uUQV8U+BRGT6kMZHoJjlC+zwGxYxVXMnJSJxvxTDCtLxiMwklTrDmUkG/pyIHfXOKWeYdR44O -cS14R0D5qAJen9xzBB5EYqJoBeedKHaAu5yzDheVVtjRvEpmHk6SsJq5mJRx+xgfVvHu4sTxb2+S -Qt3Mw9JRvBsRR8w9hhOFQ5IQhfQcPyCkQru7lDp23aW+4JKPFbpLUQfTSpMM6ciJptmibRqDX6ZV -OoO/Hdvs3kEdzqq03iKHLhKyArMK4YeEOWa8jicKx1UkhzhmZYPfwCqqEnIwFX4Z15MKPB0SxlEv -IFJWrbklQN+S03cwVKxKt++yaewihaIHVTRvYM7LyC1+0I1wnFZhBzSJytgP5AGEKEZ7XFXBd7mb -IfoZ/ICThe6+Q4nj7tOrwW0aOiLNAkTPTIT2JZRqpwLHNPm7cswo1GMbAxdXjqEAvvj6cUVkva2F -eBP2pKpM2D5RfhfhThbdLhcBfftr7haeJHsEwnx+43lXct+VXO8/X3IX5fNZC+2stkLZ1X2DbYpN -ixwv7JDHlLGBmjJyQ5omWcI+EfRhUK8zp0NSnJjSCH5mdd3BhQKbNUhw9RFV0SDCKTTYdU8TCWVG -OpQo5bLt1cxwJW2NhyZd2WNhUx8YbD2QWO3ywA6v6OH8XFCQMbtNaA6fOaMVTeCszFauZERB7ddh -VtdCnZlb3YhmSp3DrVAZfDivGgwW1oQGBEHbAlZehfO5Zg0HE8xIoO1u997cLcYLF+kiGeGAZD7S -es/7qG6clMeKuQmA2KnwkT7knWK1EreWJvsG3M7ipDK7xgJ2uffexEt5BM+8pPP2RDqypJycLEFH -ba/VXG56yMdp2xvDmRZ+xil4XeqeD7MQLoZ8JWzYn5rMJstn3mzlirlJUIdrCmv3OYWdOpAKqbaw -jGxomKksBFiiOVn5l5tg1otSwEb6a0ixsgbB8K9JAXZ0XUvGY+KrsrNLI9p29jErpXyiiBhEwREa -sYnYx+B+HaqgT0AlXE2YiqAf4B5NW9tMucU5S7ry7ZXB2XHM0ghn5VanaJ7JFm7yuJDBPJXEA90q -ZTfKnV8Vk/IXpEo5jP9nquj9BG4KVgLtAR+ucQVGOl/bHhcq4lCF0oj6fQGNg6kdEC1wFwvTEFRw -mWy+BTnU3zbnLA2T1nDgU/s0RILCfqQiQcgelCUTfacQq2d7lyXJMkImokriytSKPSKHhA11DVzV -e7uHIgh1U02yMmBwJ+PPfc4yaBTqJqecb04NKfZemwP/dOdjkxmUcuuwaWhy+xciVuyqdr1Znu+9 -ZUX0xKzNauRZAcxKW0ErS/vXFOGcW62tWHMaLzdz4cCL8xrDYNEQpXDfg/Q/2P+o8Jl9M6E31CHf -h9qK4EWDJgZhA1F9yTYeSBdIOziCxskO2mDSpKxps9ZJWy3frC+40y34njC2luws/j6nsYvmzGXn -5OJFGjuzsGNrO7bQ1ODZkykKQ+P8IGMcY15pld868dE9cPQW3O9PmJImmOCdksDQeg5MHkDyW45m -6cZfAAAA//8DAFBLAwQUAAYACAAAACEADdGQn7YAAAAbAQAAJwAAAHRoZW1lL3RoZW1lL19yZWxz -L3RoZW1lTWFuYWdlci54bWwucmVsc4SPTQrCMBSE94J3CG9v07oQkSbdiNCt1AOE5DUNNj8kUezt -Da4sCC6HYb6ZabuXnckTYzLeMWiqGgg66ZVxmsFtuOyOQFIWTonZO2SwYIKObzftFWeRSyhNJiRS -KC4xmHIOJ0qTnNCKVPmArjijj1bkIqOmQci70Ej3dX2g8ZsBfMUkvWIQe9UAGZZQmv+z/TgaiWcv -HxZd/lFBc9mFBSiixszgI5uqTATKW7q6xN8AAAD//wMAUEsBAi0AFAAGAAgAAAAhAIKKvBP6AAAA -HAIAABMAAAAAAAAAAAAAAAAAAAAAAFtDb250ZW50X1R5cGVzXS54bWxQSwECLQAUAAYACAAAACEA -pdan58AAAAA2AQAACwAAAAAAAAAAAAAAAAArAQAAX3JlbHMvLnJlbHNQSwECLQAUAAYACAAAACEA -a3mWFoMAAACKAAAAHAAAAAAAAAAAAAAAAAAUAgAAdGhlbWUvdGhlbWUvdGhlbWVNYW5hZ2VyLnht -bFBLAQItABQABgAIAAAAIQByB2XzmAYAAFAbAAAWAAAAAAAAAAAAAAAAANECAAB0aGVtZS90aGVt -ZS90aGVtZTEueG1sUEsBAi0AFAAGAAgAAAAhAA3RkJ+2AAAAGwEAACcAAAAAAAAAAAAAAAAAnQkA -AHRoZW1lL3RoZW1lL19yZWxzL3RoZW1lTWFuYWdlci54bWwucmVsc1BLBQYAAAAABQAFAF0BAACY -CgAAAAA= - -------=_NextPart_01CA0927.871204C0 -Content-Location: file:///C:/8CB3C889/TestFile(doc)_files/colorschememapping.xml -Content-Transfer-Encoding: quoted-printable -Content-Type: text/xml - - - -------=_NextPart_01CA0927.871204C0 -Content-Location: file:///C:/8CB3C889/TestFile(doc)_files/filelist.xml -Content-Transfer-Encoding: quoted-printable -Content-Type: text/xml; charset="utf-8" - - - - - - - -------=_NextPart_01CA0927.871204C0-- diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (WordML).xml b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (WordML).xml deleted file mode 100644 index ab74f33d..00000000 --- a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (WordML).xml +++ /dev/null @@ -1,3 +0,0 @@ - - -Tolsks202009-07-20T00:28:00Z2009-07-20T00:28:00Z13642080FPS1742440123.6. Svnserve Based Server3.6.1. IntroductionSubversion includes Svnserve - a lightweight stand-alone server which uses a custom protocol over an ordinary TCP/IP connection. It is ideal for smaller installations, or where a full blown Apache server cannot be used. In most cases svnserve is easier to setup and runs faster than the Apache based server, although it doesn't have some of the advanced features. And now that SASL support is included it is easy to secure as well. 3.6.2. Installing svnserveGet the latest version of Subversion from http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91 . Alternatively get a pre-packaged installer from CollabNet at http://www.collab.net/downloads/subversion . This installer will setup svnserve as a Windows service, and also includes some of the tools you need if you are going to use SASL for security. If you already have a version of Subversion installed, and svnserve is running, you will need to stop it before continuing. Run the Subversion installer. If you run the installer on your server (recommended) you can skip step 4. Open the windows-explorer, go to the installation directory of Subversion (usually C:\Program Files\Subversion) and in the bin directory, find the files svnserve.exe, intl3_svn.dll, libapr.dll, libapriconv.dll, libapriutil.dll, libdb*.dll, libeay32.dll and ssleay32.dll - copy these files, or just copy all of the bin directory, into a directory on your server e.g. c:\svnserve 3.6.3. Running svnserveNow that svnserve is installed, you need it running on your server. The simplest approach is to run the following from a DOS shell or create a windows shortcut: svnserve.exe --daemonsvnserve will now start waiting for incoming requests on port 3690. The --daemon switch tells svnserve to run as a daemon process, so it will always exist until it is manually terminated. If you have not yet created a repository, follow the instructions given with the Apache server setup Section 3.7.4, “Configuration”. To test that svnserve is working, use TortoiseSVNRepo-Browser to view a repository. \ No newline at end of file diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (XML).xml b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (XML).xml deleted file mode 100644 index bee6fa37..00000000 --- a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (XML).xml +++ /dev/null @@ -1,3 +0,0 @@ - - -3.6. Svnserve Based Server3.6.1. IntroductionSubversion includes Svnserve - a lightweight stand-alone server which uses a custom protocol over an ordinary TCP/IP connection. It is ideal for smaller installations, or where a full blown Apache server cannot be used. In most cases svnserve is easier to setup and runs faster than the Apache based server, although it doesn't have some of the advanced features. And now that SASL support is included it is easy to secure as well. 3.6.2. Installing svnserveGet the latest version of Subversion from http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91 . Alternatively get a pre-packaged installer from CollabNet at http://www.collab.net/downloads/subversion . This installer will setup svnserve as a Windows service, and also includes some of the tools you need if you are going to use SASL for security. If you already have a version of Subversion installed, and svnserve is running, you will need to stop it before continuing. Run the Subversion installer. If you run the installer on your server (recommended) you can skip step 4. Open the windows-explorer, go to the installation directory of Subversion (usually C:\Program Files\Subversion) and in the bin directory, find the files svnserve.exe, intl3_svn.dll, libapr.dll, libapriconv.dll, libapriutil.dll, libdb*.dll, libeay32.dll and ssleay32.dll - copy these files, or just copy all of the bin directory, into a directory on your server e.g. c:\svnserve 3.6.3. Running svnserveNow that svnserve is installed, you need it running on your server. The simplest approach is to run the following from a DOS shell or create a windows shortcut: svnserve.exe --daemonsvnserve will now start waiting for incoming requests on port 3690. The --daemon switch tells svnserve to run as a daemon process, so it will always exist until it is manually terminated. If you have not yet created a repository, follow the instructions given with the Apache server setup Section 3.7.4, “Configuration”. To test that svnserve is working, use TortoiseSVNRepo-Browser to view a repository. Tolsks21601-01-01T00:00:00Z2009-07-19T23:56:00Z2009-07-19T23:56:00Z113642080Microsoft Office Word0174falseTitle1FPSfalse2440false4194381605mk:@MSITStore:C:\Program%20Files\TortoiseSVN\bin\TortoiseSVN_en.chm::/tsvn-serversetup-apache.htmltsvn-serversetup-apache-47471150305http://www.collab.net/downloads/subversion4194384005http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91false12.0000 \ No newline at end of file diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (doc).doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (doc).doc deleted file mode 100644 index ef27828a..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (doc).doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (docm).docm b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (docm).docm deleted file mode 100644 index aee5c2cf..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (docm).docm and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (docx).docx b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (docx).docx deleted file mode 100644 index 4d077f59..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (docx).docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (dot).dot b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (dot).dot deleted file mode 100644 index 72a5e521..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (dot).dot and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (dotx).dotx b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (dotx).dotx deleted file mode 100644 index 4524a959..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (dotx).dotx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (enc).doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (enc).doc deleted file mode 100644 index a339815c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (enc).doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (enc).docx b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (enc).docx deleted file mode 100644 index 0d14e3c4..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (enc).docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (odt).odt b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (odt).odt deleted file mode 100644 index bd0c9161..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (odt).odt and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (pre97).doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (pre97).doc deleted file mode 100644 index 33599e33..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (pre97).doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (rtf).rtf b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (rtf).rtf deleted file mode 100644 index 3d44a726..00000000 --- a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormat/Test File (rtf).rtf +++ /dev/null @@ -1,242 +0,0 @@ -{\rtf1\adeflang1025\ansi\ansicpg1251\uc1\adeff0\deff0\stshfdbch37\stshfloch37\stshfhich37\stshfbi0\deflang1049\deflangfe1049\themelang1049\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\f2\fbidi \fmodern\fcharset204\fprq1{\*\panose 02070309020205020404}Courier New;}{\f34\fbidi \froman\fcharset204\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\f36\fbidi \froman\fcharset204\fprq2{\*\panose 02040503050406030204}Cambria;} -{\f37\fbidi \fswiss\fcharset204\fprq2{\*\panose 020f0502020204030204}Calibri;}{\f38\fbidi \fswiss\fcharset204\fprq2{\*\panose 020b0604030504040204}Tahoma;}{\flomajor\f31500\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fdbmajor\f31501\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \froman\fcharset204\fprq2{\*\panose 02040503050406030204}Cambria;} -{\fbimajor\f31503\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fdbminor\f31505\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset204\fprq2{\*\panose 020f0502020204030204}Calibri;} -{\fbiminor\f31507\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f41\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\f39\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\f42\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\f46\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f61\fbidi \fmodern\fcharset0\fprq1 Courier New;}{\f59\fbidi \fmodern\fcharset238\fprq1 Courier New CE;} -{\f62\fbidi \fmodern\fcharset161\fprq1 Courier New Greek;}{\f63\fbidi \fmodern\fcharset162\fprq1 Courier New Tur;}{\f64\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew);}{\f65\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic);} -{\f66\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f67\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f381\fbidi \froman\fcharset0\fprq2 Cambria Math;}{\f379\fbidi \froman\fcharset238\fprq2 Cambria Math CE;} -{\f382\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f383\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f386\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}{\f401\fbidi \froman\fcharset0\fprq2 Cambria;} -{\f399\fbidi \froman\fcharset238\fprq2 Cambria CE;}{\f402\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\f403\fbidi \froman\fcharset162\fprq2 Cambria Tur;}{\f406\fbidi \froman\fcharset186\fprq2 Cambria Baltic;} -{\f411\fbidi \fswiss\fcharset0\fprq2 Calibri;}{\f409\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f412\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f413\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} -{\f416\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f421\fbidi \fswiss\fcharset0\fprq2 Tahoma;}{\f419\fbidi \fswiss\fcharset238\fprq2 Tahoma CE;}{\f422\fbidi \fswiss\fcharset161\fprq2 Tahoma Greek;}{\f423\fbidi \fswiss\fcharset162\fprq2 Tahoma Tur;} -{\f424\fbidi \fswiss\fcharset177\fprq2 Tahoma (Hebrew);}{\f425\fbidi \fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f426\fbidi \fswiss\fcharset186\fprq2 Tahoma Baltic;}{\f427\fbidi \fswiss\fcharset163\fprq2 Tahoma (Vietnamese);} -{\f428\fbidi \fswiss\fcharset222\fprq2 Tahoma (Thai);}{\flomajor\f31510\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbmajor\f31520\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31530\fbidi \froman\fcharset0\fprq2 Cambria;} -{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;}{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;} -{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;}{\fbimajor\f31540\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\flominor\f31550\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31560\fbidi \froman\fcharset0\fprq2 Times New Roman;} -{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31570\fbidi \fswiss\fcharset0\fprq2 Calibri;}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;} -{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;} -{\fbiminor\f31580\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; -\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; -\red192\green192\blue192;\red54\green95\blue145;\red79\green129\blue189;}{\*\defchp \loch\af37\hich\af37\dbch\af37 }{\*\defpap \ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{ -\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1049\langfe1033\loch\f37\hich\af37\dbch\af37\cgrid\langnp1049\langfenp1033 -\snext0 \sqformat \spriority0 Normal;}{\s1\ql \li0\ri0\sb480\sl276\slmult1\keep\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \ab\af0\afs28\alang1025 \ltrch\fcs0 -\b\f36\fs28\cf17\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 \sbasedon0 \snext0 \slink15 \sqformat \spriority9 heading 1;}{\s2\ql \li0\ri0\sb240\sa60\sl276\slmult1 -\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \ab\ai\af0\afs28\alang1025 \ltrch\fcs0 \b\i\f36\fs28\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 -\sbasedon0 \snext0 \slink17 \sqformat \spriority9 heading 2;}{\s3\ql \li0\ri0\sb240\sa60\sl276\slmult1\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \ab\af0\afs26\alang1025 \ltrch\fcs0 -\b\f36\fs26\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 \sbasedon0 \snext0 \slink18 \sqformat \spriority9 heading 3;}{\s4\ql \li0\ri0\sb240\sa60\sl276\slmult1 -\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel3\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \ab\af0\afs28\alang1025 \ltrch\fcs0 \b\f37\fs28\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 \sbasedon0 \snext0 \slink19 \sqformat \spriority9 -heading 4;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* -\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv -\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\loch\f37\hich\af37\dbch\af37\cgrid\langnp1049\langfenp1049 -\snext11 \ssemihidden \sunhideused \sqformat Normal Table;}{\*\cs15 \additive \rtlch\fcs1 \ab\af0\afs28 \ltrch\fcs0 \b\f36\fs28\cf17 \sbasedon10 \slink1 \slocked \spriority9 Heading 1 Char;}{\*\cs16 \additive \rtlch\fcs1 \ab\ai\af0 \ltrch\fcs0 \b\i\cf18 -\sbasedon10 \sqformat \spriority21 Intense Emphasis;}{\*\cs17 \additive \rtlch\fcs1 \ab\ai\af0\afs28 \ltrch\fcs0 \b\i\f36\fs28\lang0\langfe1033\langfenp1033 \sbasedon10 \slink2 \slocked \ssemihidden \spriority9 Heading 2 Char;}{\*\cs18 \additive -\rtlch\fcs1 \ab\af0\afs26 \ltrch\fcs0 \b\f36\fs26\lang0\langfe1033\langfenp1033 \sbasedon10 \slink3 \slocked \ssemihidden \spriority9 Heading 3 Char;}{\*\cs19 \additive \rtlch\fcs1 \ab\af0\afs28 \ltrch\fcs0 \b\f37\fs28\lang0\langfe1033\langfenp1033 -\sbasedon10 \slink4 \slocked \spriority9 Heading 4 Char;}{\*\cs20 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf2 \sbasedon10 \ssemihidden \sunhideused Hyperlink;}{ -\s21\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 -\sbasedon0 \snext21 \sunhideused Normal (Web);}{\*\cs22 \additive \rtlch\fcs1 \ai\af0 \ltrch\fcs0 \i \sbasedon10 \sqformat \spriority20 Emphasis;}{\*\cs23 \additive \rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20 \sbasedon10 \ssemihidden \sunhideused -HTML Code;}{\s24\ql \li0\ri0\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af2\afs20\alang1025 -\ltrch\fcs0 \f2\fs20\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 \sbasedon0 \snext24 \slink25 \ssemihidden \sunhideused HTML Preformatted;}{\*\cs25 \additive \rtlch\fcs1 \af2 \ltrch\fcs0 \f2\cf1 \sbasedon10 \slink24 \slocked \ssemihidden -HTML Preformatted Char;}{\*\cs26 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 \spriority0 guimenu;}{\*\cs27 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 \spriority0 guimenuitem;}{\*\cs28 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 -\sbasedon10 \spriority0 quote;}{\*\cs29 \additive \rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \fs16 \sbasedon10 \ssemihidden \sunhideused annotation reference;}{\s30\ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1033\loch\f37\hich\af37\dbch\af37\cgrid\langnp1049\langfenp1033 -\sbasedon0 \snext30 \slink31 \ssemihidden \sunhideused annotation text;}{\*\cs31 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \lang0\langfe1033\langfenp1033 \sbasedon10 \slink30 \slocked \ssemihidden Comment Text Char;}{\s32\ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \ab\af0\afs20\alang1025 \ltrch\fcs0 \b\fs20\lang1049\langfe1033\loch\f37\hich\af37\dbch\af37\cgrid\langnp1049\langfenp1033 -\sbasedon30 \snext30 \slink33 \ssemihidden \sunhideused annotation subject;}{\*\cs33 \additive \rtlch\fcs1 \ab\af0 \ltrch\fcs0 \b\lang0\langfe1033\langfenp1033 \sbasedon31 \slink32 \slocked \ssemihidden Comment Subject Char;}{ -\s34\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af38\afs16\alang1025 \ltrch\fcs0 \fs16\lang1049\langfe1033\loch\f38\hich\af38\dbch\af37\cgrid\langnp1049\langfenp1033 -\sbasedon0 \snext34 \slink35 \ssemihidden \sunhideused Balloon Text;}{\*\cs35 \additive \rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\lang0\langfe1033\langfenp1033 \sbasedon10 \slink34 \slocked \ssemihidden Balloon Text Char;}}{\*\listtable -{\list\listtemplateid-72729606{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li720 -\jclisttab\tx720\lin720 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li1440 -\jclisttab\tx1440\lin1440 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li2160 -\jclisttab\tx2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li2880 -\jclisttab\tx2880\lin2880 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li3600 -\jclisttab\tx3600\lin3600 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li4320 -\jclisttab\tx4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li5040 -\jclisttab\tx5040\lin5040 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li5760 -\jclisttab\tx5760\lin5760 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li6480 -\jclisttab\tx6480\lin6480 }{\listname ;}\listid401415626}}{\*\listoverridetable{\listoverride\listid401415626\listoverridecount0\ls1}}{\*\rsidtbl \rsid2572821\rsid15558508}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0 -\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\author Tols}{\operator ks}{\creatim\yr2009\mo7\dy20\hr10\min41}{\revtim\yr2009\mo7\dy20\hr10\min41}{\version2}{\edmins0}{\nofpages1}{\nofwords323}{\nofchars2121}{\*\company FPS} -{\nofcharsws2440}{\vern32893}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}\paperw11906\paperh16838\margl1701\margr850\margt1134\margb1134\gutter0\ltrsect -\deftab708\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors1 -\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1701\dgvorigin1134\dghshow1\dgvshow1 -\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct -\asianbrkrule\rsidroot1181740\newtblstyruls\nogrowautofit\utinl \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sectrsid2572821\sftnbj {\*\pnseclvl1 -\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5 -\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang -{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\s2\ql \li0\ri0\sb240\sa60\sl276\slmult1 -\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 \ab\ai\af0\afs28\alang1025 \ltrch\fcs0 \b\i\f36\fs28\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 -\lang9\langfe1033\langnp9\insrsid2572821 {\*\bkmkstart tsvn-serversetup-svnserve}{\*\bkmkend tsvn-serversetup-svnserve}3.6.\~Svnserve Based Server -\par }\pard\plain \ltrpar\s3\ql \li0\ri0\sb240\sa60\sl276\slmult1\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 \ab\af0\afs26\alang1025 \ltrch\fcs0 -\b\f36\fs26\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1033\langnp9\insrsid2572821 {\*\bkmkstart tsvn-serversetup-svnserve-1}{\*\bkmkend tsvn-serversetup-svnserve-1}3.6.1.\~Introduction -\par }\pard\plain \ltrpar\s21\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 -\fs24\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 {\*\bkmkstart id776356}{\*\bkmkend id776356} -Subversion includes Svnserve - a lightweight stand-alone server which uses a custom protocol over an ordinary TCP/IP connection. It is ideal for smaller installations, or where a full blown Apache server cannot be used. -\par In most cases svnserve is easier to setup and runs faster than the Apache based server, although it doesn't have some of the advanced features. And now that SASL support is included it is easy to secure as well. -\par }\pard\plain \ltrpar\s3\ql \li0\ri0\sb240\sa60\sl276\slmult1\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 \ab\af0\afs26\alang1025 \ltrch\fcs0 -\b\f36\fs26\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1033\langnp9\insrsid2572821 {\*\bkmkstart tsvn-serversetup-svnserve-2}{\*\bkmkend tsvn-serversetup-svnserve-2}3.6.2.\~Installing svnserve -\par {\listtext\pard\plain\ltrpar \s21 \rtlch\fcs1 \af0 \ltrch\fcs0 \cf1\lang9\langfe1049\dbch\af0\langnp9\insrsid2572821 \hich\af0\dbch\af0\loch\f0 1.\tab}}\pard\plain \ltrpar\s21\ql \fi-360\li720\ri0\sb100\sa100\sbauto1\saauto1\widctlpar -\jclisttab\tx720\wrapdefault\aspalpha\aspnum\faauto\ls1\adjustright\rin0\lin720\itap0\pararsid2572821 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 -\lang9\langfe1049\langnp9\insrsid2572821 Get the latest version of Subversion from }{\field{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 - HYPERLINK "http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91" \\t "_top" }}{\fldrslt {\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs22\i\lang9\langfe1049\langnp9\insrsid2572821 -http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs20\ul\cf2\lang9\langfe1049\langnp9\insrsid2572821 }}}\sectd \ltrsect -\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sectrsid2572821\sftnbj {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 . Alternatively get a pre-packaged installer from CollabNet at }{\field{\*\fldinst -{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 HYPERLINK "http://www.collab.net/downloads/subversion" \\t "_top" }}{\fldrslt {\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs22\i\lang9\langfe1049\langnp9\insrsid2572821 -http://www.collab.net/downloads/subversion}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs20\ul\cf2\lang9\langfe1049\langnp9\insrsid2572821 }}}\sectd \ltrsect\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sectrsid2572821\sftnbj { -\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 . This installer will setup svnserve as a Windows service, and also includes some of the tools you need if you are going to use SASL for security. -\par {\listtext\pard\plain\ltrpar \s21 \rtlch\fcs1 \af0 \ltrch\fcs0 \cf1\lang9\langfe1049\dbch\af0\langnp9\insrsid2572821 \hich\af0\dbch\af0\loch\f0 2.\tab} -If you already have a version of Subversion installed, and svnserve is running, you will need to stop it before continuing. -\par {\listtext\pard\plain\ltrpar \s21 \rtlch\fcs1 \af0 \ltrch\fcs0 \cf1\lang9\langfe1049\dbch\af0\langnp9\insrsid2572821 \hich\af0\dbch\af0\loch\f0 3.\tab} -Run the Subversion installer. If you run the installer on your server (recommended) you can skip step 4. -\par {\listtext\pard\plain\ltrpar \s21 \rtlch\fcs1 \af0 \ltrch\fcs0 \cf1\lang9\langfe1049\dbch\af0\langnp9\insrsid2572821 \hich\af0\dbch\af0\loch\f0 4.\tab}Open the windows-explorer, go to the installation directory of Subversion (usually }{\rtlch\fcs1 -\af2\afs20 \ltrch\fcs0 \cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 C:\\Program Files\\Subversion}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 ) and in the }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 -\cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 bin}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 directory, find the files }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 -svnserve.exe}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 , }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 intl3_svn.dll}{\rtlch\fcs1 \af0 \ltrch\fcs0 -\lang9\langfe1049\langnp9\insrsid2572821 , }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 libapr.dll}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 , }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 -\cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 libapriconv.dll}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 , }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 libapriutil.dll}{ -\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 , }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 libdb*.dll}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 , }{ -\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 libeay32.dll}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 and }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 -\cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 ssleay32.dll}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 - copy these files, or just copy all of the }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 -\cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 bin}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 directory, into a directory on your server e.g. }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 -\cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 c:\\svnserve}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 -\par }\pard\plain \ltrpar\s3\ql \li0\ri0\sb240\sa60\sl276\slmult1\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 \ab\af0\afs26\alang1025 \ltrch\fcs0 -\b\f36\fs26\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1033\langnp9\insrsid2572821 {\*\bkmkstart tsvn-serversetup-svnserve-3}{\*\bkmkend tsvn-serversetup-svnserve-3}3.6.3.\~Running svnserve -\par }\pard\plain \ltrpar\s21\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 -\fs24\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 Now that svnserve is installed, you need it running on your server. The simplest approach is to run the following from -a DOS shell or create a windows shortcut: -\par }\pard\plain \ltrpar\s24\ql \li0\ri0\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 -\af2\afs20\alang1025 \ltrch\fcs0 \f2\fs20\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af2 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 svnserve.exe --daemon -\par }\pard\plain \ltrpar\s21\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 -\fs24\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 -svnserve will now start waiting for incoming requests on port 3690. The --daemon switch tells svnserve to run as a daemon process, so it will always exist until it is manually terminated. -\par If you have not yet created a repository, follow the instructions given with the Apache server setup }{\field{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 HYPERLINK "mk:@MSITStore:C:\\\\Program%20Files\\\\TortoiseSVN -\\\\bin\\\\TortoiseSVN_en.chm::/tsvn-serversetup-apache.html" \\l "tsvn-serversetup-apache-4" \\o "3.7.4.\~Configuration" }}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs20\ul\cf2\lang9\langfe1049\langnp9\insrsid2572821 Section\~3.7.4, \'93Configuration\'94} -}}\sectd \ltrsect\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sectrsid2572821\sftnbj {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 . -\par To test that svnserve is working, use }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs26\lang9\langfe1049\langnp9\insrsid2572821 TortoiseSVN}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 \u8594\'3e }{\rtlch\fcs1 \af0 \ltrch\fcs0 -\cs27\lang9\langfe1049\langnp9\insrsid2572821 Repo-Browser}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 to view a repository. -\par }{\*\themedata 504b030414000600080000002100828abc13fa0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb6ac3301045f785fe83d0b6d8 -72ba28a5d8cea249777d2cd20f18e4b12d6a8f843409c9df77ecb850ba082d74231062ce997b55ae8fe3a00e1893f354e9555e6885647de3a8abf4fbee29bbd7 -2a3150038327acf409935ed7d757e5ee14302999a654e99e393c18936c8f23a4dc072479697d1c81e51a3b13c07e4087e6b628ee8cf5c4489cf1c4d075f92a0b -44d7a07a83c82f308ac7b0a0f0fbf90c2480980b58abc733615aa2d210c2e02cb04430076a7ee833dfb6ce62e3ed7e14693e8317d8cd0433bf5c60f53fea2fe7 -065bd80facb647e9e25c7fc421fd2ddb526b2e9373fed4bb902e182e97b7b461e6bfad3f010000ffff0300504b030414000600080000002100a5d6a7e7c00000 -00360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4fc7060abb08 -84a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b63095120f88d94fbc -52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462a1a82fe353 -bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f7468656d652f7468 -656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b4b0d592c9c -070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b4757e8d3f7 -29e245eb2b260a0238fd010000ffff0300504b030414000600080000002100720765f398060000501b0000160000007468656d652f7468656d652f7468656d65 -312e786d6cec594f6fdb3614bf0fd87720746f6327761a07758ad8b19b2d4d1bc46e871e698996d850a240d2497d1bdae38001c3ba618715d86d87615b8116d8 -a5fb34d93a6c1dd0afb0475292c5585e9236d88aad0e105be48fefff7b7ca4ae5ebb1f33744884a43c697bf5cb350f91c4e7014dc2b6777bd8bfb4e621a97012 -60c613d2f6a6447ad736de7fef2a5e5711890982f5895cc76d2f522a5d5f5a923e0c637999a72481b931173156f028c2a540e023a01bb3a5e55a6d7529c634f1 -508263207b6b3ca63e41434dd2dbc889f7183c264aea019f8981264d9c15061b1cd435424e659709748859db033e013f1a92fbca430c4b05136dafd1d47fded2 -c6d525bc9e2d626ac1dad2babef964ebb205c1c1b2e129c251c1b4de6fb4ae6c15f40d80a9795cafd7ebf6ea053d03c0be0f9a5a59ca341bfdb57a27a75902d9 -9ff3b4bbb566ade1e24bf457e6646e753a9d662b93c5123520fbb331875fabad3636971dbc01597c730edfe86c76bbab0ede802c7e750edfbfd25a6db878038a -184d0ee6d035f8f4fb19f50232e66cbb12be06f0b55a069fa1201a8ae8d22cc63c518b622dc6f7b8e8034003195634416a9a9231f6218abb381e098a3503bc4e -7069c60ef9726e48f342d21734556defc3144346cce8bd7afefdabe74fd1f18367c70f7e3a7ef8f0f8c18f9690b36a1b276179d5cb6f3ffbf3f1c7e88fa7dfbc -7cf445355e96f1bffef0c92f3f7f5e0d84f49989f3e2cb27bf3d7bf2e2ab4f7fffee51057c53e051193ea43191e8263942fb3c06c58c555cc9c9489c6fc530c2 -b4bc623309254eb0e65241bfa722077d738a59e61d478e0e712d784740f9a8025e9fdc73041e4462a26805e79d287680bb9cb30e179556d8d1bc4a661e4e92b0 -9ab9989471fb181f56f1eee2c4f16f6f9242ddccc3d251bc1b1147cc3d86138543921085f41c3f20a442bbbb943a76dda5bee0928f15ba4b5107d34a930ce9c8 -89a6d9a26d1a835fa6553a83bf1ddbecde411dceaab4de22872e12b202b30ae187843966bc8e270ac755248738666583dfc02aaa127230157e19d7930a3c1d12 -c6512f205256adb92540df92d3773054ac4ab7efb269ec2285a20755346f60cecbc82d7ed08d709c5661073489cad80fe4018428467b5c55c177b99b21fa19fc -809385eebe4389e3eed3abc16d1a3a22cd0244cf4c84f625946aa702c734f9bb72cc28d4631b0317578ea100bef8fa714564bdad857813f6a4aa4cd83e517e17 -e14e16dd2e17017dfb6bee169e247b04c27c7ee3795772df955cef3f5f7217e5f3590bedacb642d9d57d836d8a4d8b1c2fec90c794b1819a3272439a2659c23e -11f46150af33a743529c98d2087e6675ddc185029b354870f51155d120c22934d8754f130965463a9428e5b2edd5cc70256d8d87265dd96361531f186c3d9058 -edf2c00eafe8e1fc5c509031bb4d680e9f39a3154de0accc56ae644441edd76156d7429d995bdd88664a9dc3ad50197c38af1a0c16d684060441db02565e85f3 -b9660d0713cc48a0ed6ef7dedc2dc60b17e92219e180643ed27acffba86e9c94c78ab90980d8a9f0913ee49d62b512b79626fb06dccee2a432bbc60276b9f7de -c44b7904cfbca4f3f6443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc399167ec629785dea9e0fb3102e867c256cd89f9acc26cb67de6ce58ab94950876b0a -6bf739859d3a900aa9b6b08c6c6898a92c0458a23959f9979b60d68b52c046fa6b48b1b206c1f0af490176745d4bc663e2abb2b34b23da76f6312ba57ca28818 -44c1111ab189d8c7e07e1daaa04f40255c4d988aa01fe01e4d5bdb4cb9c5394bbaf2ed95c1d971ccd20867e556a7689ec9166ef2b890c13c95c403dd2a6537ca -9d5f1593f217a44a398cff67aae8fd046e0a5602ed011fae7105463a5fdb1e172ae25085d288fa7d018d83a91d102d70170bd3105470996cbe0539d4df36e72c -0d93d670e053fb344482c27ea42241c81e9425137da710ab677b9725c9324226a24ae2cad48a3d2287840d750d5cd57bbb87220875534db232607027e3cf7dce -326814ea26a79c6f4e0d29f65e9b03ff74e76393199472ebb0696872fb172256ecaa76bd599eefbd6545f4c4accd6ae45901cc4a5b412b4bfbd714e19c5badad -58731a2f3773e1c08bf31ac360d110a570df83f43fd8ffa8f0997d33a137d421df87da8ae0458326066103517dc9361e4817483b3882c6c90eda60d2a4ac69b3 -d6495b2ddfac2fb8d32df89e30b696ec2cfe3ea7b18be6cc65e7e4e2451a3bb3b0636b3bb6d0d4e0d993290a43e3fc20631c635e6995df3af1d13d70f416dcef -4f98922698e09d92c0d07a0e4c1e40f25b8e66e9c65f000000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d65 -2f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d36 -3f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e -3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d985 -0528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100828abc13fa0000001c020000130000000000000000000000 -0000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b00000000000000000000 -0000002b0100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c0000000000000000000000000014020000 -7468656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100720765f398060000501b00001600000000000000 -000000000000d10200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b01000027000000 -000000000000000000009d0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000980a00000000} -{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d -617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 -6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 -656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} -{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7; -\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4; -\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7;\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid; -\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography; -\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 0105000002000000180000004d73786d6c322e534158584d4c5265616465722e352e3000000000000000000000060000 -d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffffec69d9888b8b3d4c859eaf6cd158be0f00000000000000000000000070c4 -317dca08ca01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (HTML).html b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (HTML).html deleted file mode 100644 index 485911f2..00000000 --- a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (HTML).html +++ /dev/null @@ -1,855 +0,0 @@ - - - - - - - - - - - - - - - - - - -
          - -

          3.6. Svnserve Based Server

          - -

          3.6.1. Introduction

          - -

          Subversion -includes Svnserve - a lightweight stand-alone server which uses a custom -protocol over an ordinary TCP/IP connection. It is ideal for smaller -installations, or where a full blown Apache server cannot be used.

          - -

          In most cases svnserve is easier -to setup and runs faster than the Apache based server, although it doesn't have -some of the advanced features. And now that SASL support is included it is easy -to secure as well.

          - -

          3.6.2. Installing svnserve

          - -

          1.      -Get the -latest version of Subversion from http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91 -. Alternatively get a pre-packaged installer from CollabNet at http://www.collab.net/downloads/subversion -. This installer will setup svnserve as a Windows service, and also -includes some of the tools you need if you are going to use SASL for security.

          - -

          2.      -If -you already have a version of Subversion installed, and svnserve is running, -you will need to stop it before continuing.

          - -

          3.      -Run -the Subversion installer. If you run the installer on your server (recommended) -you can skip step 4.

          - -

          4.      -Open -the windows-explorer, go to the installation directory of Subversion (usually C:\Program -Files\Subversion) and -in the bin directory, -find the files svnserve.exe, intl3_svn.dll, libapr.dll, libapriconv.dll, libapriutil.dll, libdb*.dll, libeay32.dll and ssleay32.dll - copy these files, or just copy all of -the bin directory, into a directory on your -server e.g. c:\svnserve

          - -

          3.6.3. Running svnserve

          - -

          Now that svnserve is installed, -you need it running on your server. The simplest approach is to run the -following from a DOS shell or create a windows shortcut:

          - -
          svnserve.exe --daemon
          - -

          svnserve will now start waiting for incoming -requests on port 3690. The --daemon switch tells svnserve -to run as a daemon process, so it will always exist until it is manually -terminated.

          - -

          If you have not yet created a -repository, follow the instructions given with the Apache server setup Section 3.7.4, Configuration.

          - -

          To test that svnserve is working, use TortoiseSVNRepo-Browser to view a repository.

          - -
          - - - - diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (JPG).jpg b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (JPG).jpg deleted file mode 100644 index 27430480..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (JPG).jpg and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (MHTML).mhtml b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (MHTML).mhtml deleted file mode 100644 index 2e20c971..00000000 --- a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (MHTML).mhtml +++ /dev/null @@ -1,1016 +0,0 @@ -MIME-Version: 1.0 -Content-Type: multipart/related; boundary="----=_NextPart_01CA0927.871204C0" - -This document is a Single File Web Page, also known as a Web Archive file. If you are seeing this message, your browser or editor doesn't support Web Archive files. Please download a browser that supports Web Archive, such as Windows Internet Explorer. - -------=_NextPart_01CA0927.871204C0 -Content-Location: file:///C:/8CB3C889/TestFile(doc).htm -Content-Transfer-Encoding: quoted-printable -Content-Type: text/html; charset="us-ascii" - - - - - - - - - - - - - - - - - - - -
          - -

          3.6. Svnserve Based Server

          - -

          3.6.1. Introduction

          - -

          Su= -bversion -includes Svnserve - a lightweight stand-alone server which uses a custom -protocol over an ordinary TCP/IP connection. It is ideal for smaller -installations, or where a full blown Apache server cannot be used.

          - -

          In most cases svnserve is= - easier -to setup and runs faster than the Apache based server, although it doesn't = -have -some of the advanced features. And now that SASL support is included it is = -easy -to secure as well.

          - -

          3.6.2. Installing svnserve

          - -

          1.      -Get the -latest version of Subversion from http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=3D= -91 -. Alternatively get a pre-packaged installer from CollabNet at http://www.c= -ollab.net/downloads/subversion -. This installer will setup svnserve as a Windows service, and also -includes some of the tools you need if you are going to use SASL for securi= -ty.

          - -

          2.      -If -you already have a version of Subversion installed, and svnserve is running, -you will need to stop it before continuing.

          - -

          3.      -Run -the Subversion installer. If you run the installer on your server (recommen= -ded) -you can skip step 4.

          - -

          4.      -Open -the windows-explorer, go to the installation directory of Subversion (usual= -ly C:\Program -Files\Subversion) and -in the bin direct= -ory, -find the files svnserve.exe, intl3_svn.dll, libapr.dll, libapriconv.dll, libapriutil.dll, libdb*.dll, libeay32.dll<= -span -lang=3DEN style=3D'mso-ansi-language:EN'> and ssleay32.dll<= -span -lang=3DEN style=3D'mso-ansi-language:EN'> - copy these files, or just copy = -all of -the bin directory, into a directory on yo= -ur -server e.g. c:\svnserve

          - -

          3.6.3. Running svnserve

          - -

          Now that svnserve is inst= -alled, -you need it running on your server. The simplest approach is to run the -following from a DOS shell or create a windows shortcut: = -

          - -
          svnserve.exe --daemon
          - -

          svnse= -rve will now start waiting for incomi= -ng -requests on port 3690. The --daemon switch tells svnser= -ve -to run as a daemon process, so it will always exist until it is manually -terminated.

          - -

          If you have not yet creat= -ed a -repository, follow the instructions given with the Apache server setup Section 3.7.4, -“Configuration”.

          - -

          To test that svnserve is = -working, use TortoiseSVN = -→ Repo-Browser to view a repository.

          - -
          - - - - - -------=_NextPart_01CA0927.871204C0 -Content-Location: file:///C:/8CB3C889/TestFile(doc)_files/themedata.thmx -Content-Transfer-Encoding: base64 -Content-Type: application/vnd.ms-officetheme - -UEsDBBQABgAIAAAAIQCCirwT+gAAABwCAAATAAAAW0NvbnRlbnRfVHlwZXNdLnhtbKyRy2rDMBBF -94X+g9C22HK6KKXYzqJJd30s0g8Y5LEtao+ENAnJ33fsuFC6CC10IxBizpl7Va6P46AOGJPzVOlV -XmiFZH3jqKv0++4pu9cqMVADgyes9AmTXtfXV+XuFDApmaZU6Z45PBiTbI8jpNwHJHlpfRyB5Ro7 -E8B+QIfmtijujPXESJzxxNB1+SoLRNegeoPILzCKx7Cg8Pv5DCSAmAtYq8czYVqi0hDC4CywRDAH -an7oM9+2zmLj7X4UaT6DF9jNBDO/XGD1P+ov5wZb2A+stkfp4lx/xCH9LdtSay6Tc/7Uu5AuGC6X -t7Rh5r+tPwEAAP//AwBQSwMEFAAGAAgAAAAhAKXWp+fAAAAANgEAAAsAAABfcmVscy8ucmVsc4SP -z2rDMAyH74W9g9F9UdLDGCV2L6WQQy+jfQDhKH9oIhvbG+vbT8cGCrsIhKTv96k9/q6L+eGU5yAW -mqoGw+JDP8to4XY9v3+CyYWkpyUIW3hwhqN727VfvFDRozzNMRulSLYwlRIPiNlPvFKuQmTRyRDS -SkXbNGIkf6eRcV/XH5ieGeA2TNP1FlLXN2Cuj6jJ/7PDMMyeT8F/ryzlRQRuN5RMaeRioagv41O9 -kKhlqtQe0LW4+db9AQAA//8DAFBLAwQUAAYACAAAACEAa3mWFoMAAACKAAAAHAAAAHRoZW1lL3Ro -ZW1lL3RoZW1lTWFuYWdlci54bWwMzE0KwyAQQOF9oXeQ2TdjuyhFYrLLrrv2AEOcGkHHoNKf29fl -44M3zt8U1ZtLDVksnAcNimXNLoi38Hwspxuo2kgcxSxs4ccV5ul4GMm0jRPfSchzUX0j1ZCFrbXd -INa1K9Uh7yzdXrkkaj2LR1fo0/cp4kXrKyYKAjj9AQAA//8DAFBLAwQUAAYACAAAACEAcgdl85gG -AABQGwAAFgAAAHRoZW1lL3RoZW1lL3RoZW1lMS54bWzsWU9v2zYUvw/YdyB0b2MndhoHdYrYsZst -TRvEboceaYmW2FCiQNJJfRva44ABw7phhxXYbYdhW4EW2KX7NNk6bB3Qr7BHUpLFWF6SNtiKrQ4Q -W+SP7/97fKSuXrsfM3RIhKQ8aXv1yzUPkcTnAU3Ctnd72L+05iGpcBJgxhPS9qZEetc23n/vKl5X -EYkJgvWJXMdtL1IqXV9akj4MY3mZpySBuTEXMVbwKMKlQOAjoBuzpeVabXUpxjTxUIJjIHtrPKY+ -QUNN0tvIifcYPCZK6gGfiYEmTZwVBhsc1DVCTmWXCXSIWdsDPgE/GpL7ykMMSwUTba/R1H/e0sbV -JbyeLWJqwdrSur75ZOuyBcHBsuEpwlHBtN5vtK5sFfQNgKl5XK/X6/bqBT0DwL4PmlpZyjQb/bV6 -J6dZAtmf87S7tWat4eJL9FfmZG51Op1mK5PFEjUg+7Mxh1+rrTY2lx28AVl8cw7f6Gx2u6sO3oAs -fnUO37/SWm24eAOKGE0O5tA1+PT7GfUCMuZsuxK+BvC1WgafoSAaiujSLMY8UYtiLcb3uOgDQAMZ -VjRBapqSMfYhirs4HgmKNQO8TnBpxg75cm5I80LSFzRVbe/DFENGzOi9ev79q+dP0fGDZ8cPfjp+ -+PD4wY+WkLNqGydhedXLbz/78/HH6I+n37x89EU1Xpbxv/7wyS8/f14NhPSZifPiyye/PXvy4qtP -f//uUQV8U+BRGT6kMZHoJjlC+zwGxYxVXMnJSJxvxTDCtLxiMwklTrDmUkG/pyIHfXOKWeYdR44O -cS14R0D5qAJen9xzBB5EYqJoBeedKHaAu5yzDheVVtjRvEpmHk6SsJq5mJRx+xgfVvHu4sTxb2+S -Qt3Mw9JRvBsRR8w9hhOFQ5IQhfQcPyCkQru7lDp23aW+4JKPFbpLUQfTSpMM6ciJptmibRqDX6ZV -OoO/Hdvs3kEdzqq03iKHLhKyArMK4YeEOWa8jicKx1UkhzhmZYPfwCqqEnIwFX4Z15MKPB0SxlEv -IFJWrbklQN+S03cwVKxKt++yaewihaIHVTRvYM7LyC1+0I1wnFZhBzSJytgP5AGEKEZ7XFXBd7mb -IfoZ/ICThe6+Q4nj7tOrwW0aOiLNAkTPTIT2JZRqpwLHNPm7cswo1GMbAxdXjqEAvvj6cUVkva2F -eBP2pKpM2D5RfhfhThbdLhcBfftr7haeJHsEwnx+43lXct+VXO8/X3IX5fNZC+2stkLZ1X2DbYpN -ixwv7JDHlLGBmjJyQ5omWcI+EfRhUK8zp0NSnJjSCH5mdd3BhQKbNUhw9RFV0SDCKTTYdU8TCWVG -OpQo5bLt1cxwJW2NhyZd2WNhUx8YbD2QWO3ywA6v6OH8XFCQMbtNaA6fOaMVTeCszFauZERB7ddh -VtdCnZlb3YhmSp3DrVAZfDivGgwW1oQGBEHbAlZehfO5Zg0HE8xIoO1u997cLcYLF+kiGeGAZD7S -es/7qG6clMeKuQmA2KnwkT7knWK1EreWJvsG3M7ipDK7xgJ2uffexEt5BM+8pPP2RDqypJycLEFH -ba/VXG56yMdp2xvDmRZ+xil4XeqeD7MQLoZ8JWzYn5rMJstn3mzlirlJUIdrCmv3OYWdOpAKqbaw -jGxomKksBFiiOVn5l5tg1otSwEb6a0ixsgbB8K9JAXZ0XUvGY+KrsrNLI9p29jErpXyiiBhEwREa -sYnYx+B+HaqgT0AlXE2YiqAf4B5NW9tMucU5S7ry7ZXB2XHM0ghn5VanaJ7JFm7yuJDBPJXEA90q -ZTfKnV8Vk/IXpEo5jP9nquj9BG4KVgLtAR+ucQVGOl/bHhcq4lCF0oj6fQGNg6kdEC1wFwvTEFRw -mWy+BTnU3zbnLA2T1nDgU/s0RILCfqQiQcgelCUTfacQq2d7lyXJMkImokriytSKPSKHhA11DVzV -e7uHIgh1U02yMmBwJ+PPfc4yaBTqJqecb04NKfZemwP/dOdjkxmUcuuwaWhy+xciVuyqdr1Znu+9 -ZUX0xKzNauRZAcxKW0ErS/vXFOGcW62tWHMaLzdz4cCL8xrDYNEQpXDfg/Q/2P+o8Jl9M6E31CHf -h9qK4EWDJgZhA1F9yTYeSBdIOziCxskO2mDSpKxps9ZJWy3frC+40y34njC2luws/j6nsYvmzGXn -5OJFGjuzsGNrO7bQ1ODZkykKQ+P8IGMcY15pld868dE9cPQW3O9PmJImmOCdksDQeg5MHkDyW45m -6cZfAAAA//8DAFBLAwQUAAYACAAAACEADdGQn7YAAAAbAQAAJwAAAHRoZW1lL3RoZW1lL19yZWxz -L3RoZW1lTWFuYWdlci54bWwucmVsc4SPTQrCMBSE94J3CG9v07oQkSbdiNCt1AOE5DUNNj8kUezt -Da4sCC6HYb6ZabuXnckTYzLeMWiqGgg66ZVxmsFtuOyOQFIWTonZO2SwYIKObzftFWeRSyhNJiRS -KC4xmHIOJ0qTnNCKVPmArjijj1bkIqOmQci70Ej3dX2g8ZsBfMUkvWIQe9UAGZZQmv+z/TgaiWcv -HxZd/lFBc9mFBSiixszgI5uqTATKW7q6xN8AAAD//wMAUEsBAi0AFAAGAAgAAAAhAIKKvBP6AAAA -HAIAABMAAAAAAAAAAAAAAAAAAAAAAFtDb250ZW50X1R5cGVzXS54bWxQSwECLQAUAAYACAAAACEA -pdan58AAAAA2AQAACwAAAAAAAAAAAAAAAAArAQAAX3JlbHMvLnJlbHNQSwECLQAUAAYACAAAACEA -a3mWFoMAAACKAAAAHAAAAAAAAAAAAAAAAAAUAgAAdGhlbWUvdGhlbWUvdGhlbWVNYW5hZ2VyLnht -bFBLAQItABQABgAIAAAAIQByB2XzmAYAAFAbAAAWAAAAAAAAAAAAAAAAANECAAB0aGVtZS90aGVt -ZS90aGVtZTEueG1sUEsBAi0AFAAGAAgAAAAhAA3RkJ+2AAAAGwEAACcAAAAAAAAAAAAAAAAAnQkA -AHRoZW1lL3RoZW1lL19yZWxzL3RoZW1lTWFuYWdlci54bWwucmVsc1BLBQYAAAAABQAFAF0BAACY -CgAAAAA= - -------=_NextPart_01CA0927.871204C0 -Content-Location: file:///C:/8CB3C889/TestFile(doc)_files/colorschememapping.xml -Content-Transfer-Encoding: quoted-printable -Content-Type: text/xml - - - -------=_NextPart_01CA0927.871204C0 -Content-Location: file:///C:/8CB3C889/TestFile(doc)_files/filelist.xml -Content-Transfer-Encoding: quoted-printable -Content-Type: text/xml; charset="utf-8" - - - - - - - -------=_NextPart_01CA0927.871204C0-- diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (WordML).xml b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (WordML).xml deleted file mode 100644 index ab74f33d..00000000 --- a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (WordML).xml +++ /dev/null @@ -1,3 +0,0 @@ - - -Tolsks202009-07-20T00:28:00Z2009-07-20T00:28:00Z13642080FPS1742440123.6. Svnserve Based Server3.6.1. IntroductionSubversion includes Svnserve - a lightweight stand-alone server which uses a custom protocol over an ordinary TCP/IP connection. It is ideal for smaller installations, or where a full blown Apache server cannot be used. In most cases svnserve is easier to setup and runs faster than the Apache based server, although it doesn't have some of the advanced features. And now that SASL support is included it is easy to secure as well. 3.6.2. Installing svnserveGet the latest version of Subversion from http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91 . Alternatively get a pre-packaged installer from CollabNet at http://www.collab.net/downloads/subversion . This installer will setup svnserve as a Windows service, and also includes some of the tools you need if you are going to use SASL for security. If you already have a version of Subversion installed, and svnserve is running, you will need to stop it before continuing. Run the Subversion installer. If you run the installer on your server (recommended) you can skip step 4. Open the windows-explorer, go to the installation directory of Subversion (usually C:\Program Files\Subversion) and in the bin directory, find the files svnserve.exe, intl3_svn.dll, libapr.dll, libapriconv.dll, libapriutil.dll, libdb*.dll, libeay32.dll and ssleay32.dll - copy these files, or just copy all of the bin directory, into a directory on your server e.g. c:\svnserve 3.6.3. Running svnserveNow that svnserve is installed, you need it running on your server. The simplest approach is to run the following from a DOS shell or create a windows shortcut: svnserve.exe --daemonsvnserve will now start waiting for incoming requests on port 3690. The --daemon switch tells svnserve to run as a daemon process, so it will always exist until it is manually terminated. If you have not yet created a repository, follow the instructions given with the Apache server setup Section 3.7.4, “Configuration”. To test that svnserve is working, use TortoiseSVNRepo-Browser to view a repository. \ No newline at end of file diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (XML).xml b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (XML).xml deleted file mode 100644 index bee6fa37..00000000 --- a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (XML).xml +++ /dev/null @@ -1,3 +0,0 @@ - - -3.6. Svnserve Based Server3.6.1. IntroductionSubversion includes Svnserve - a lightweight stand-alone server which uses a custom protocol over an ordinary TCP/IP connection. It is ideal for smaller installations, or where a full blown Apache server cannot be used. In most cases svnserve is easier to setup and runs faster than the Apache based server, although it doesn't have some of the advanced features. And now that SASL support is included it is easy to secure as well. 3.6.2. Installing svnserveGet the latest version of Subversion from http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91 . Alternatively get a pre-packaged installer from CollabNet at http://www.collab.net/downloads/subversion . This installer will setup svnserve as a Windows service, and also includes some of the tools you need if you are going to use SASL for security. If you already have a version of Subversion installed, and svnserve is running, you will need to stop it before continuing. Run the Subversion installer. If you run the installer on your server (recommended) you can skip step 4. Open the windows-explorer, go to the installation directory of Subversion (usually C:\Program Files\Subversion) and in the bin directory, find the files svnserve.exe, intl3_svn.dll, libapr.dll, libapriconv.dll, libapriutil.dll, libdb*.dll, libeay32.dll and ssleay32.dll - copy these files, or just copy all of the bin directory, into a directory on your server e.g. c:\svnserve 3.6.3. Running svnserveNow that svnserve is installed, you need it running on your server. The simplest approach is to run the following from a DOS shell or create a windows shortcut: svnserve.exe --daemonsvnserve will now start waiting for incoming requests on port 3690. The --daemon switch tells svnserve to run as a daemon process, so it will always exist until it is manually terminated. If you have not yet created a repository, follow the instructions given with the Apache server setup Section 3.7.4, “Configuration”. To test that svnserve is working, use TortoiseSVNRepo-Browser to view a repository. Tolsks21601-01-01T00:00:00Z2009-07-19T23:56:00Z2009-07-19T23:56:00Z113642080Microsoft Office Word0174falseTitle1FPSfalse2440false4194381605mk:@MSITStore:C:\Program%20Files\TortoiseSVN\bin\TortoiseSVN_en.chm::/tsvn-serversetup-apache.htmltsvn-serversetup-apache-47471150305http://www.collab.net/downloads/subversion4194384005http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91false12.0000 \ No newline at end of file diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (doc).doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (doc).doc deleted file mode 100644 index ef27828a..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (doc).doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (docm).docm b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (docm).docm deleted file mode 100644 index aee5c2cf..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (docm).docm and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (docx).docx b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (docx).docx deleted file mode 100644 index 4d077f59..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (docx).docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (dot).dot b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (dot).dot deleted file mode 100644 index 72a5e521..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (dot).dot and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (dotx).dotx b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (dotx).dotx deleted file mode 100644 index 4524a959..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (dotx).dotx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (enc).doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (enc).doc deleted file mode 100644 index a339815c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (enc).doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (enc).docx b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (enc).docx deleted file mode 100644 index 0d14e3c4..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (enc).docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (odt).odt b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (odt).odt deleted file mode 100644 index bd0c9161..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (odt).odt and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (pre97).doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (pre97).doc deleted file mode 100644 index 33599e33..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (pre97).doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (rtf).rtf b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (rtf).rtf deleted file mode 100644 index 3d44a726..00000000 --- a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/CheckFormatCompatibility/Test File (rtf).rtf +++ /dev/null @@ -1,242 +0,0 @@ -{\rtf1\adeflang1025\ansi\ansicpg1251\uc1\adeff0\deff0\stshfdbch37\stshfloch37\stshfhich37\stshfbi0\deflang1049\deflangfe1049\themelang1049\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\f2\fbidi \fmodern\fcharset204\fprq1{\*\panose 02070309020205020404}Courier New;}{\f34\fbidi \froman\fcharset204\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\f36\fbidi \froman\fcharset204\fprq2{\*\panose 02040503050406030204}Cambria;} -{\f37\fbidi \fswiss\fcharset204\fprq2{\*\panose 020f0502020204030204}Calibri;}{\f38\fbidi \fswiss\fcharset204\fprq2{\*\panose 020b0604030504040204}Tahoma;}{\flomajor\f31500\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fdbmajor\f31501\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \froman\fcharset204\fprq2{\*\panose 02040503050406030204}Cambria;} -{\fbimajor\f31503\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fdbminor\f31505\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset204\fprq2{\*\panose 020f0502020204030204}Calibri;} -{\fbiminor\f31507\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f41\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\f39\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\f42\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\f46\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f61\fbidi \fmodern\fcharset0\fprq1 Courier New;}{\f59\fbidi \fmodern\fcharset238\fprq1 Courier New CE;} -{\f62\fbidi \fmodern\fcharset161\fprq1 Courier New Greek;}{\f63\fbidi \fmodern\fcharset162\fprq1 Courier New Tur;}{\f64\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew);}{\f65\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic);} -{\f66\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f67\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f381\fbidi \froman\fcharset0\fprq2 Cambria Math;}{\f379\fbidi \froman\fcharset238\fprq2 Cambria Math CE;} -{\f382\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f383\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f386\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}{\f401\fbidi \froman\fcharset0\fprq2 Cambria;} -{\f399\fbidi \froman\fcharset238\fprq2 Cambria CE;}{\f402\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\f403\fbidi \froman\fcharset162\fprq2 Cambria Tur;}{\f406\fbidi \froman\fcharset186\fprq2 Cambria Baltic;} -{\f411\fbidi \fswiss\fcharset0\fprq2 Calibri;}{\f409\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f412\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f413\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} -{\f416\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f421\fbidi \fswiss\fcharset0\fprq2 Tahoma;}{\f419\fbidi \fswiss\fcharset238\fprq2 Tahoma CE;}{\f422\fbidi \fswiss\fcharset161\fprq2 Tahoma Greek;}{\f423\fbidi \fswiss\fcharset162\fprq2 Tahoma Tur;} -{\f424\fbidi \fswiss\fcharset177\fprq2 Tahoma (Hebrew);}{\f425\fbidi \fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f426\fbidi \fswiss\fcharset186\fprq2 Tahoma Baltic;}{\f427\fbidi \fswiss\fcharset163\fprq2 Tahoma (Vietnamese);} -{\f428\fbidi \fswiss\fcharset222\fprq2 Tahoma (Thai);}{\flomajor\f31510\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbmajor\f31520\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31530\fbidi \froman\fcharset0\fprq2 Cambria;} -{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;}{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;} -{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;}{\fbimajor\f31540\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\flominor\f31550\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31560\fbidi \froman\fcharset0\fprq2 Times New Roman;} -{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31570\fbidi \fswiss\fcharset0\fprq2 Calibri;}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;} -{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;} -{\fbiminor\f31580\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; -\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; -\red192\green192\blue192;\red54\green95\blue145;\red79\green129\blue189;}{\*\defchp \loch\af37\hich\af37\dbch\af37 }{\*\defpap \ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{ -\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1049\langfe1033\loch\f37\hich\af37\dbch\af37\cgrid\langnp1049\langfenp1033 -\snext0 \sqformat \spriority0 Normal;}{\s1\ql \li0\ri0\sb480\sl276\slmult1\keep\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \ab\af0\afs28\alang1025 \ltrch\fcs0 -\b\f36\fs28\cf17\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 \sbasedon0 \snext0 \slink15 \sqformat \spriority9 heading 1;}{\s2\ql \li0\ri0\sb240\sa60\sl276\slmult1 -\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \ab\ai\af0\afs28\alang1025 \ltrch\fcs0 \b\i\f36\fs28\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 -\sbasedon0 \snext0 \slink17 \sqformat \spriority9 heading 2;}{\s3\ql \li0\ri0\sb240\sa60\sl276\slmult1\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \ab\af0\afs26\alang1025 \ltrch\fcs0 -\b\f36\fs26\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 \sbasedon0 \snext0 \slink18 \sqformat \spriority9 heading 3;}{\s4\ql \li0\ri0\sb240\sa60\sl276\slmult1 -\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel3\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \ab\af0\afs28\alang1025 \ltrch\fcs0 \b\f37\fs28\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 \sbasedon0 \snext0 \slink19 \sqformat \spriority9 -heading 4;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* -\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv -\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\loch\f37\hich\af37\dbch\af37\cgrid\langnp1049\langfenp1049 -\snext11 \ssemihidden \sunhideused \sqformat Normal Table;}{\*\cs15 \additive \rtlch\fcs1 \ab\af0\afs28 \ltrch\fcs0 \b\f36\fs28\cf17 \sbasedon10 \slink1 \slocked \spriority9 Heading 1 Char;}{\*\cs16 \additive \rtlch\fcs1 \ab\ai\af0 \ltrch\fcs0 \b\i\cf18 -\sbasedon10 \sqformat \spriority21 Intense Emphasis;}{\*\cs17 \additive \rtlch\fcs1 \ab\ai\af0\afs28 \ltrch\fcs0 \b\i\f36\fs28\lang0\langfe1033\langfenp1033 \sbasedon10 \slink2 \slocked \ssemihidden \spriority9 Heading 2 Char;}{\*\cs18 \additive -\rtlch\fcs1 \ab\af0\afs26 \ltrch\fcs0 \b\f36\fs26\lang0\langfe1033\langfenp1033 \sbasedon10 \slink3 \slocked \ssemihidden \spriority9 Heading 3 Char;}{\*\cs19 \additive \rtlch\fcs1 \ab\af0\afs28 \ltrch\fcs0 \b\f37\fs28\lang0\langfe1033\langfenp1033 -\sbasedon10 \slink4 \slocked \spriority9 Heading 4 Char;}{\*\cs20 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf2 \sbasedon10 \ssemihidden \sunhideused Hyperlink;}{ -\s21\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 -\sbasedon0 \snext21 \sunhideused Normal (Web);}{\*\cs22 \additive \rtlch\fcs1 \ai\af0 \ltrch\fcs0 \i \sbasedon10 \sqformat \spriority20 Emphasis;}{\*\cs23 \additive \rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20 \sbasedon10 \ssemihidden \sunhideused -HTML Code;}{\s24\ql \li0\ri0\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af2\afs20\alang1025 -\ltrch\fcs0 \f2\fs20\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 \sbasedon0 \snext24 \slink25 \ssemihidden \sunhideused HTML Preformatted;}{\*\cs25 \additive \rtlch\fcs1 \af2 \ltrch\fcs0 \f2\cf1 \sbasedon10 \slink24 \slocked \ssemihidden -HTML Preformatted Char;}{\*\cs26 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 \spriority0 guimenu;}{\*\cs27 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 \spriority0 guimenuitem;}{\*\cs28 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 -\sbasedon10 \spriority0 quote;}{\*\cs29 \additive \rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \fs16 \sbasedon10 \ssemihidden \sunhideused annotation reference;}{\s30\ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1033\loch\f37\hich\af37\dbch\af37\cgrid\langnp1049\langfenp1033 -\sbasedon0 \snext30 \slink31 \ssemihidden \sunhideused annotation text;}{\*\cs31 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \lang0\langfe1033\langfenp1033 \sbasedon10 \slink30 \slocked \ssemihidden Comment Text Char;}{\s32\ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \ab\af0\afs20\alang1025 \ltrch\fcs0 \b\fs20\lang1049\langfe1033\loch\f37\hich\af37\dbch\af37\cgrid\langnp1049\langfenp1033 -\sbasedon30 \snext30 \slink33 \ssemihidden \sunhideused annotation subject;}{\*\cs33 \additive \rtlch\fcs1 \ab\af0 \ltrch\fcs0 \b\lang0\langfe1033\langfenp1033 \sbasedon31 \slink32 \slocked \ssemihidden Comment Subject Char;}{ -\s34\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af38\afs16\alang1025 \ltrch\fcs0 \fs16\lang1049\langfe1033\loch\f38\hich\af38\dbch\af37\cgrid\langnp1049\langfenp1033 -\sbasedon0 \snext34 \slink35 \ssemihidden \sunhideused Balloon Text;}{\*\cs35 \additive \rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\lang0\langfe1033\langfenp1033 \sbasedon10 \slink34 \slocked \ssemihidden Balloon Text Char;}}{\*\listtable -{\list\listtemplateid-72729606{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li720 -\jclisttab\tx720\lin720 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li1440 -\jclisttab\tx1440\lin1440 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li2160 -\jclisttab\tx2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li2880 -\jclisttab\tx2880\lin2880 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li3600 -\jclisttab\tx3600\lin3600 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li4320 -\jclisttab\tx4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li5040 -\jclisttab\tx5040\lin5040 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li5760 -\jclisttab\tx5760\lin5760 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li6480 -\jclisttab\tx6480\lin6480 }{\listname ;}\listid401415626}}{\*\listoverridetable{\listoverride\listid401415626\listoverridecount0\ls1}}{\*\rsidtbl \rsid2572821\rsid15558508}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0 -\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\author Tols}{\operator ks}{\creatim\yr2009\mo7\dy20\hr10\min41}{\revtim\yr2009\mo7\dy20\hr10\min41}{\version2}{\edmins0}{\nofpages1}{\nofwords323}{\nofchars2121}{\*\company FPS} -{\nofcharsws2440}{\vern32893}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}\paperw11906\paperh16838\margl1701\margr850\margt1134\margb1134\gutter0\ltrsect -\deftab708\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors1 -\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1701\dgvorigin1134\dghshow1\dgvshow1 -\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct -\asianbrkrule\rsidroot1181740\newtblstyruls\nogrowautofit\utinl \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sectrsid2572821\sftnbj {\*\pnseclvl1 -\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5 -\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang -{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\s2\ql \li0\ri0\sb240\sa60\sl276\slmult1 -\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 \ab\ai\af0\afs28\alang1025 \ltrch\fcs0 \b\i\f36\fs28\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 -\lang9\langfe1033\langnp9\insrsid2572821 {\*\bkmkstart tsvn-serversetup-svnserve}{\*\bkmkend tsvn-serversetup-svnserve}3.6.\~Svnserve Based Server -\par }\pard\plain \ltrpar\s3\ql \li0\ri0\sb240\sa60\sl276\slmult1\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 \ab\af0\afs26\alang1025 \ltrch\fcs0 -\b\f36\fs26\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1033\langnp9\insrsid2572821 {\*\bkmkstart tsvn-serversetup-svnserve-1}{\*\bkmkend tsvn-serversetup-svnserve-1}3.6.1.\~Introduction -\par }\pard\plain \ltrpar\s21\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 -\fs24\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 {\*\bkmkstart id776356}{\*\bkmkend id776356} -Subversion includes Svnserve - a lightweight stand-alone server which uses a custom protocol over an ordinary TCP/IP connection. It is ideal for smaller installations, or where a full blown Apache server cannot be used. -\par In most cases svnserve is easier to setup and runs faster than the Apache based server, although it doesn't have some of the advanced features. And now that SASL support is included it is easy to secure as well. -\par }\pard\plain \ltrpar\s3\ql \li0\ri0\sb240\sa60\sl276\slmult1\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 \ab\af0\afs26\alang1025 \ltrch\fcs0 -\b\f36\fs26\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1033\langnp9\insrsid2572821 {\*\bkmkstart tsvn-serversetup-svnserve-2}{\*\bkmkend tsvn-serversetup-svnserve-2}3.6.2.\~Installing svnserve -\par {\listtext\pard\plain\ltrpar \s21 \rtlch\fcs1 \af0 \ltrch\fcs0 \cf1\lang9\langfe1049\dbch\af0\langnp9\insrsid2572821 \hich\af0\dbch\af0\loch\f0 1.\tab}}\pard\plain \ltrpar\s21\ql \fi-360\li720\ri0\sb100\sa100\sbauto1\saauto1\widctlpar -\jclisttab\tx720\wrapdefault\aspalpha\aspnum\faauto\ls1\adjustright\rin0\lin720\itap0\pararsid2572821 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 -\lang9\langfe1049\langnp9\insrsid2572821 Get the latest version of Subversion from }{\field{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 - HYPERLINK "http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91" \\t "_top" }}{\fldrslt {\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs22\i\lang9\langfe1049\langnp9\insrsid2572821 -http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs20\ul\cf2\lang9\langfe1049\langnp9\insrsid2572821 }}}\sectd \ltrsect -\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sectrsid2572821\sftnbj {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 . Alternatively get a pre-packaged installer from CollabNet at }{\field{\*\fldinst -{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 HYPERLINK "http://www.collab.net/downloads/subversion" \\t "_top" }}{\fldrslt {\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs22\i\lang9\langfe1049\langnp9\insrsid2572821 -http://www.collab.net/downloads/subversion}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs20\ul\cf2\lang9\langfe1049\langnp9\insrsid2572821 }}}\sectd \ltrsect\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sectrsid2572821\sftnbj { -\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 . This installer will setup svnserve as a Windows service, and also includes some of the tools you need if you are going to use SASL for security. -\par {\listtext\pard\plain\ltrpar \s21 \rtlch\fcs1 \af0 \ltrch\fcs0 \cf1\lang9\langfe1049\dbch\af0\langnp9\insrsid2572821 \hich\af0\dbch\af0\loch\f0 2.\tab} -If you already have a version of Subversion installed, and svnserve is running, you will need to stop it before continuing. -\par {\listtext\pard\plain\ltrpar \s21 \rtlch\fcs1 \af0 \ltrch\fcs0 \cf1\lang9\langfe1049\dbch\af0\langnp9\insrsid2572821 \hich\af0\dbch\af0\loch\f0 3.\tab} -Run the Subversion installer. If you run the installer on your server (recommended) you can skip step 4. -\par {\listtext\pard\plain\ltrpar \s21 \rtlch\fcs1 \af0 \ltrch\fcs0 \cf1\lang9\langfe1049\dbch\af0\langnp9\insrsid2572821 \hich\af0\dbch\af0\loch\f0 4.\tab}Open the windows-explorer, go to the installation directory of Subversion (usually }{\rtlch\fcs1 -\af2\afs20 \ltrch\fcs0 \cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 C:\\Program Files\\Subversion}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 ) and in the }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 -\cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 bin}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 directory, find the files }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 -svnserve.exe}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 , }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 intl3_svn.dll}{\rtlch\fcs1 \af0 \ltrch\fcs0 -\lang9\langfe1049\langnp9\insrsid2572821 , }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 libapr.dll}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 , }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 -\cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 libapriconv.dll}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 , }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 libapriutil.dll}{ -\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 , }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 libdb*.dll}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 , }{ -\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 libeay32.dll}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 and }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 -\cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 ssleay32.dll}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 - copy these files, or just copy all of the }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 -\cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 bin}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 directory, into a directory on your server e.g. }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 -\cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 c:\\svnserve}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 -\par }\pard\plain \ltrpar\s3\ql \li0\ri0\sb240\sa60\sl276\slmult1\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 \ab\af0\afs26\alang1025 \ltrch\fcs0 -\b\f36\fs26\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1033\langnp9\insrsid2572821 {\*\bkmkstart tsvn-serversetup-svnserve-3}{\*\bkmkend tsvn-serversetup-svnserve-3}3.6.3.\~Running svnserve -\par }\pard\plain \ltrpar\s21\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 -\fs24\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 Now that svnserve is installed, you need it running on your server. The simplest approach is to run the following from -a DOS shell or create a windows shortcut: -\par }\pard\plain \ltrpar\s24\ql \li0\ri0\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 -\af2\afs20\alang1025 \ltrch\fcs0 \f2\fs20\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af2 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 svnserve.exe --daemon -\par }\pard\plain \ltrpar\s21\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 -\fs24\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 -svnserve will now start waiting for incoming requests on port 3690. The --daemon switch tells svnserve to run as a daemon process, so it will always exist until it is manually terminated. -\par If you have not yet created a repository, follow the instructions given with the Apache server setup }{\field{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 HYPERLINK "mk:@MSITStore:C:\\\\Program%20Files\\\\TortoiseSVN -\\\\bin\\\\TortoiseSVN_en.chm::/tsvn-serversetup-apache.html" \\l "tsvn-serversetup-apache-4" \\o "3.7.4.\~Configuration" }}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs20\ul\cf2\lang9\langfe1049\langnp9\insrsid2572821 Section\~3.7.4, \'93Configuration\'94} -}}\sectd \ltrsect\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sectrsid2572821\sftnbj {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 . -\par To test that svnserve is working, use }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs26\lang9\langfe1049\langnp9\insrsid2572821 TortoiseSVN}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 \u8594\'3e }{\rtlch\fcs1 \af0 \ltrch\fcs0 -\cs27\lang9\langfe1049\langnp9\insrsid2572821 Repo-Browser}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 to view a repository. -\par }{\*\themedata 504b030414000600080000002100828abc13fa0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb6ac3301045f785fe83d0b6d8 -72ba28a5d8cea249777d2cd20f18e4b12d6a8f843409c9df77ecb850ba082d74231062ce997b55ae8fe3a00e1893f354e9555e6885647de3a8abf4fbee29bbd7 -2a3150038327acf409935ed7d757e5ee14302999a654e99e393c18936c8f23a4dc072479697d1c81e51a3b13c07e4087e6b628ee8cf5c4489cf1c4d075f92a0b -44d7a07a83c82f308ac7b0a0f0fbf90c2480980b58abc733615aa2d210c2e02cb04430076a7ee833dfb6ce62e3ed7e14693e8317d8cd0433bf5c60f53fea2fe7 -065bd80facb647e9e25c7fc421fd2ddb526b2e9373fed4bb902e182e97b7b461e6bfad3f010000ffff0300504b030414000600080000002100a5d6a7e7c00000 -00360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4fc7060abb08 -84a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b63095120f88d94fbc -52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462a1a82fe353 -bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f7468656d652f7468 -656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b4b0d592c9c -070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b4757e8d3f7 -29e245eb2b260a0238fd010000ffff0300504b030414000600080000002100720765f398060000501b0000160000007468656d652f7468656d652f7468656d65 -312e786d6cec594f6fdb3614bf0fd87720746f6327761a07758ad8b19b2d4d1bc46e871e698996d850a240d2497d1bdae38001c3ba618715d86d87615b8116d8 -a5fb34d93a6c1dd0afb0475292c5585e9236d88aad0e105be48fefff7b7ca4ae5ebb1f33744884a43c697bf5cb350f91c4e7014dc2b6777bd8bfb4e621a97012 -60c613d2f6a6447ad736de7fef2a5e5711890982f5895cc76d2f522a5d5f5a923e0c637999a72481b931173156f028c2a540e023a01bb3a5e55a6d7529c634f1 -508263207b6b3ca63e41434dd2dbc889f7183c264aea019f8981264d9c15061b1cd435424e659709748859db033e013f1a92fbca430c4b05136dafd1d47fded2 -c6d525bc9e2d626ac1dad2babef964ebb205c1c1b2e129c251c1b4de6fb4ae6c15f40d80a9795cafd7ebf6ea053d03c0be0f9a5a59ca341bfdb57a27a75902d9 -9ff3b4bbb566ade1e24bf457e6646e753a9d662b93c5123520fbb331875fabad3636971dbc01597c730edfe86c76bbab0ede802c7e750edfbfd25a6db878038a -184d0ee6d035f8f4fb19f50232e66cbb12be06f0b55a069fa1201a8ae8d22cc63c518b622dc6f7b8e8034003195634416a9a9231f6218abb381e098a3503bc4e -7069c60ef9726e48f342d21734556defc3144346cce8bd7afefdabe74fd1f18367c70f7e3a7ef8f0f8c18f9690b36a1b276179d5cb6f3ffbf3f1c7e88fa7dfbc -7cf445355e96f1bffef0c92f3f7f5e0d84f49989f3e2cb27bf3d7bf2e2ab4f7fffee51057c53e051193ea43191e8263942fb3c06c58c555cc9c9489c6fc530c2 -b4bc623309254eb0e65241bfa722077d738a59e61d478e0e712d784740f9a8025e9fdc73041e4462a26805e79d287680bb9cb30e179556d8d1bc4a661e4e92b0 -9ab9989471fb181f56f1eee2c4f16f6f9242ddccc3d251bc1b1147cc3d86138543921085f41c3f20a442bbbb943a76dda5bee0928f15ba4b5107d34a930ce9c8 -89a6d9a26d1a835fa6553a83bf1ddbecde411dceaab4de22872e12b202b30ae187843966bc8e270ac755248738666583dfc02aaa127230157e19d7930a3c1d12 -c6512f205256adb92540df92d3773054ac4ab7efb269ec2285a20755346f60cecbc82d7ed08d709c5661073489cad80fe4018428467b5c55c177b99b21fa19fc -809385eebe4389e3eed3abc16d1a3a22cd0244cf4c84f625946aa702c734f9bb72cc28d4631b0317578ea100bef8fa714564bdad857813f6a4aa4cd83e517e17 -e14e16dd2e17017dfb6bee169e247b04c27c7ee3795772df955cef3f5f7217e5f3590bedacb642d9d57d836d8a4d8b1c2fec90c794b1819a3272439a2659c23e -11f46150af33a743529c98d2087e6675ddc185029b354870f51155d120c22934d8754f130965463a9428e5b2edd5cc70256d8d87265dd96361531f186c3d9058 -edf2c00eafe8e1fc5c509031bb4d680e9f39a3154de0accc56ae644441edd76156d7429d995bdd88664a9dc3ad50197c38af1a0c16d684060441db02565e85f3 -b9660d0713cc48a0ed6ef7dedc2dc60b17e92219e180643ed27acffba86e9c94c78ab90980d8a9f0913ee49d62b512b79626fb06dccee2a432bbc60276b9f7de -c44b7904cfbca4f3f6443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc399167ec629785dea9e0fb3102e867c256cd89f9acc26cb67de6ce58ab94950876b0a -6bf739859d3a900aa9b6b08c6c6898a92c0458a23959f9979b60d68b52c046fa6b48b1b206c1f0af490176745d4bc663e2abb2b34b23da76f6312ba57ca28818 -44c1111ab189d8c7e07e1daaa04f40255c4d988aa01fe01e4d5bdb4cb9c5394bbaf2ed95c1d971ccd20867e556a7689ec9166ef2b890c13c95c403dd2a6537ca -9d5f1593f217a44a398cff67aae8fd046e0a5602ed011fae7105463a5fdb1e172ae25085d288fa7d018d83a91d102d70170bd3105470996cbe0539d4df36e72c -0d93d670e053fb344482c27ea42241c81e9425137da710ab677b9725c9324226a24ae2cad48a3d2287840d750d5cd57bbb87220875534db232607027e3cf7dce -326814ea26a79c6f4e0d29f65e9b03ff74e76393199472ebb0696872fb172256ecaa76bd599eefbd6545f4c4accd6ae45901cc4a5b412b4bfbd714e19c5badad -58731a2f3773e1c08bf31ac360d110a570df83f43fd8ffa8f0997d33a137d421df87da8ae0458326066103517dc9361e4817483b3882c6c90eda60d2a4ac69b3 -d6495b2ddfac2fb8d32df89e30b696ec2cfe3ea7b18be6cc65e7e4e2451a3bb3b0636b3bb6d0d4e0d993290a43e3fc20631c635e6995df3af1d13d70f416dcef -4f98922698e09d92c0d07a0e4c1e40f25b8e66e9c65f000000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d65 -2f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d36 -3f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e -3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d985 -0528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100828abc13fa0000001c020000130000000000000000000000 -0000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b00000000000000000000 -0000002b0100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c0000000000000000000000000014020000 -7468656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100720765f398060000501b00001600000000000000 -000000000000d10200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b01000027000000 -000000000000000000009d0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000980a00000000} -{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d -617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 -6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 -656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} -{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7; -\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4; -\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7;\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid; -\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography; -\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 0105000002000000180000004d73786d6c322e534158584d4c5265616465722e352e3000000000000000000000060000 -d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffffec69d9888b8b3d4c859eaf6cd158be0f00000000000000000000000070c4 -317dca08ca01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ConvertDocumentToByte/Test File (doc).doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ConvertDocumentToByte/Test File (doc).doc deleted file mode 100644 index d73731cb..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ConvertDocumentToByte/Test File (doc).doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ConvertDocumentToEPUB/Document.EpubConversion.doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ConvertDocumentToEPUB/Document.EpubConversion.doc deleted file mode 100644 index aa54f21e..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ConvertDocumentToEPUB/Document.EpubConversion.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ConvertDocumentToEPUBUysingDefaultSaveOptions/Document.EpubConversion.doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ConvertDocumentToEPUBUysingDefaultSaveOptions/Document.EpubConversion.doc deleted file mode 100644 index aa54f21e..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ConvertDocumentToEPUBUysingDefaultSaveOptions/Document.EpubConversion.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ConvertDocumentToHtmlWithRoundtrip/Test File (doc).doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ConvertDocumentToHtmlWithRoundtrip/Test File (doc).doc deleted file mode 100644 index d73731cb..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ConvertDocumentToHtmlWithRoundtrip/Test File (doc).doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ConvertImageToPdf/Test.bmp b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ConvertImageToPdf/Test.bmp deleted file mode 100644 index c9f5ffe3..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ConvertImageToPdf/Test.bmp and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/DetectDocumentSignatures/Document.Signed.doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/DetectDocumentSignatures/Document.Signed.doc deleted file mode 100644 index a4c9f526..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/DetectDocumentSignatures/Document.Signed.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/DetectDocumentSignatures/Document.Signed.docx b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/DetectDocumentSignatures/Document.Signed.docx deleted file mode 100644 index ce8ca935..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/DetectDocumentSignatures/Document.Signed.docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/Doc2PDF/Template.doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/Doc2PDF/Template.doc deleted file mode 100644 index 6e97a1eb..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/Doc2PDF/Template.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (HTML).html b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (HTML).html deleted file mode 100644 index 485911f2..00000000 --- a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (HTML).html +++ /dev/null @@ -1,855 +0,0 @@ - - - - - - - - - - - - - - - - - - -
          - -

          3.6. Svnserve Based Server

          - -

          3.6.1. Introduction

          - -

          Subversion -includes Svnserve - a lightweight stand-alone server which uses a custom -protocol over an ordinary TCP/IP connection. It is ideal for smaller -installations, or where a full blown Apache server cannot be used.

          - -

          In most cases svnserve is easier -to setup and runs faster than the Apache based server, although it doesn't have -some of the advanced features. And now that SASL support is included it is easy -to secure as well.

          - -

          3.6.2. Installing svnserve

          - -

          1.      -Get the -latest version of Subversion from http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91 -. Alternatively get a pre-packaged installer from CollabNet at http://www.collab.net/downloads/subversion -. This installer will setup svnserve as a Windows service, and also -includes some of the tools you need if you are going to use SASL for security.

          - -

          2.      -If -you already have a version of Subversion installed, and svnserve is running, -you will need to stop it before continuing.

          - -

          3.      -Run -the Subversion installer. If you run the installer on your server (recommended) -you can skip step 4.

          - -

          4.      -Open -the windows-explorer, go to the installation directory of Subversion (usually C:\Program -Files\Subversion) and -in the bin directory, -find the files svnserve.exe, intl3_svn.dll, libapr.dll, libapriconv.dll, libapriutil.dll, libdb*.dll, libeay32.dll and ssleay32.dll - copy these files, or just copy all of -the bin directory, into a directory on your -server e.g. c:\svnserve

          - -

          3.6.3. Running svnserve

          - -

          Now that svnserve is installed, -you need it running on your server. The simplest approach is to run the -following from a DOS shell or create a windows shortcut:

          - -
          svnserve.exe --daemon
          - -

          svnserve will now start waiting for incoming -requests on port 3690. The --daemon switch tells svnserve -to run as a daemon process, so it will always exist until it is manually -terminated.

          - -

          If you have not yet created a -repository, follow the instructions given with the Apache server setup Section 3.7.4, Configuration.

          - -

          To test that svnserve is working, use TortoiseSVNRepo-Browser to view a repository.

          - -
          - - - - diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (JPG).jpg b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (JPG).jpg deleted file mode 100644 index 27430480..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (JPG).jpg and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (MHTML).mhtml b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (MHTML).mhtml deleted file mode 100644 index 2e20c971..00000000 --- a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (MHTML).mhtml +++ /dev/null @@ -1,1016 +0,0 @@ -MIME-Version: 1.0 -Content-Type: multipart/related; boundary="----=_NextPart_01CA0927.871204C0" - -This document is a Single File Web Page, also known as a Web Archive file. If you are seeing this message, your browser or editor doesn't support Web Archive files. Please download a browser that supports Web Archive, such as Windows Internet Explorer. - -------=_NextPart_01CA0927.871204C0 -Content-Location: file:///C:/8CB3C889/TestFile(doc).htm -Content-Transfer-Encoding: quoted-printable -Content-Type: text/html; charset="us-ascii" - - - - - - - - - - - - - - - - - - - -
          - -

          3.6. Svnserve Based Server

          - -

          3.6.1. Introduction

          - -

          Su= -bversion -includes Svnserve - a lightweight stand-alone server which uses a custom -protocol over an ordinary TCP/IP connection. It is ideal for smaller -installations, or where a full blown Apache server cannot be used.

          - -

          In most cases svnserve is= - easier -to setup and runs faster than the Apache based server, although it doesn't = -have -some of the advanced features. And now that SASL support is included it is = -easy -to secure as well.

          - -

          3.6.2. Installing svnserve

          - -

          1.      -Get the -latest version of Subversion from http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=3D= -91 -. Alternatively get a pre-packaged installer from CollabNet at http://www.c= -ollab.net/downloads/subversion -. This installer will setup svnserve as a Windows service, and also -includes some of the tools you need if you are going to use SASL for securi= -ty.

          - -

          2.      -If -you already have a version of Subversion installed, and svnserve is running, -you will need to stop it before continuing.

          - -

          3.      -Run -the Subversion installer. If you run the installer on your server (recommen= -ded) -you can skip step 4.

          - -

          4.      -Open -the windows-explorer, go to the installation directory of Subversion (usual= -ly C:\Program -Files\Subversion) and -in the bin direct= -ory, -find the files svnserve.exe, intl3_svn.dll, libapr.dll, libapriconv.dll, libapriutil.dll, libdb*.dll, libeay32.dll<= -span -lang=3DEN style=3D'mso-ansi-language:EN'> and ssleay32.dll<= -span -lang=3DEN style=3D'mso-ansi-language:EN'> - copy these files, or just copy = -all of -the bin directory, into a directory on yo= -ur -server e.g. c:\svnserve

          - -

          3.6.3. Running svnserve

          - -

          Now that svnserve is inst= -alled, -you need it running on your server. The simplest approach is to run the -following from a DOS shell or create a windows shortcut: = -

          - -
          svnserve.exe --daemon
          - -

          svnse= -rve will now start waiting for incomi= -ng -requests on port 3690. The --daemon switch tells svnser= -ve -to run as a daemon process, so it will always exist until it is manually -terminated.

          - -

          If you have not yet creat= -ed a -repository, follow the instructions given with the Apache server setup Section 3.7.4, -“Configuration”.

          - -

          To test that svnserve is = -working, use TortoiseSVN = -→ Repo-Browser to view a repository.

          - -
          - - - - - -------=_NextPart_01CA0927.871204C0 -Content-Location: file:///C:/8CB3C889/TestFile(doc)_files/themedata.thmx -Content-Transfer-Encoding: base64 -Content-Type: application/vnd.ms-officetheme - -UEsDBBQABgAIAAAAIQCCirwT+gAAABwCAAATAAAAW0NvbnRlbnRfVHlwZXNdLnhtbKyRy2rDMBBF -94X+g9C22HK6KKXYzqJJd30s0g8Y5LEtao+ENAnJ33fsuFC6CC10IxBizpl7Va6P46AOGJPzVOlV -XmiFZH3jqKv0++4pu9cqMVADgyes9AmTXtfXV+XuFDApmaZU6Z45PBiTbI8jpNwHJHlpfRyB5Ro7 -E8B+QIfmtijujPXESJzxxNB1+SoLRNegeoPILzCKx7Cg8Pv5DCSAmAtYq8czYVqi0hDC4CywRDAH -an7oM9+2zmLj7X4UaT6DF9jNBDO/XGD1P+ov5wZb2A+stkfp4lx/xCH9LdtSay6Tc/7Uu5AuGC6X -t7Rh5r+tPwEAAP//AwBQSwMEFAAGAAgAAAAhAKXWp+fAAAAANgEAAAsAAABfcmVscy8ucmVsc4SP -z2rDMAyH74W9g9F9UdLDGCV2L6WQQy+jfQDhKH9oIhvbG+vbT8cGCrsIhKTv96k9/q6L+eGU5yAW -mqoGw+JDP8to4XY9v3+CyYWkpyUIW3hwhqN727VfvFDRozzNMRulSLYwlRIPiNlPvFKuQmTRyRDS -SkXbNGIkf6eRcV/XH5ieGeA2TNP1FlLXN2Cuj6jJ/7PDMMyeT8F/ryzlRQRuN5RMaeRioagv41O9 -kKhlqtQe0LW4+db9AQAA//8DAFBLAwQUAAYACAAAACEAa3mWFoMAAACKAAAAHAAAAHRoZW1lL3Ro -ZW1lL3RoZW1lTWFuYWdlci54bWwMzE0KwyAQQOF9oXeQ2TdjuyhFYrLLrrv2AEOcGkHHoNKf29fl -44M3zt8U1ZtLDVksnAcNimXNLoi38Hwspxuo2kgcxSxs4ccV5ul4GMm0jRPfSchzUX0j1ZCFrbXd -INa1K9Uh7yzdXrkkaj2LR1fo0/cp4kXrKyYKAjj9AQAA//8DAFBLAwQUAAYACAAAACEAcgdl85gG -AABQGwAAFgAAAHRoZW1lL3RoZW1lL3RoZW1lMS54bWzsWU9v2zYUvw/YdyB0b2MndhoHdYrYsZst -TRvEboceaYmW2FCiQNJJfRva44ABw7phhxXYbYdhW4EW2KX7NNk6bB3Qr7BHUpLFWF6SNtiKrQ4Q -W+SP7/97fKSuXrsfM3RIhKQ8aXv1yzUPkcTnAU3Ctnd72L+05iGpcBJgxhPS9qZEetc23n/vKl5X -EYkJgvWJXMdtL1IqXV9akj4MY3mZpySBuTEXMVbwKMKlQOAjoBuzpeVabXUpxjTxUIJjIHtrPKY+ -QUNN0tvIifcYPCZK6gGfiYEmTZwVBhsc1DVCTmWXCXSIWdsDPgE/GpL7ykMMSwUTba/R1H/e0sbV -JbyeLWJqwdrSur75ZOuyBcHBsuEpwlHBtN5vtK5sFfQNgKl5XK/X6/bqBT0DwL4PmlpZyjQb/bV6 -J6dZAtmf87S7tWat4eJL9FfmZG51Op1mK5PFEjUg+7Mxh1+rrTY2lx28AVl8cw7f6Gx2u6sO3oAs -fnUO37/SWm24eAOKGE0O5tA1+PT7GfUCMuZsuxK+BvC1WgafoSAaiujSLMY8UYtiLcb3uOgDQAMZ -VjRBapqSMfYhirs4HgmKNQO8TnBpxg75cm5I80LSFzRVbe/DFENGzOi9ev79q+dP0fGDZ8cPfjp+ -+PD4wY+WkLNqGydhedXLbz/78/HH6I+n37x89EU1Xpbxv/7wyS8/f14NhPSZifPiyye/PXvy4qtP -f//uUQV8U+BRGT6kMZHoJjlC+zwGxYxVXMnJSJxvxTDCtLxiMwklTrDmUkG/pyIHfXOKWeYdR44O -cS14R0D5qAJen9xzBB5EYqJoBeedKHaAu5yzDheVVtjRvEpmHk6SsJq5mJRx+xgfVvHu4sTxb2+S -Qt3Mw9JRvBsRR8w9hhOFQ5IQhfQcPyCkQru7lDp23aW+4JKPFbpLUQfTSpMM6ciJptmibRqDX6ZV -OoO/Hdvs3kEdzqq03iKHLhKyArMK4YeEOWa8jicKx1UkhzhmZYPfwCqqEnIwFX4Z15MKPB0SxlEv -IFJWrbklQN+S03cwVKxKt++yaewihaIHVTRvYM7LyC1+0I1wnFZhBzSJytgP5AGEKEZ7XFXBd7mb -IfoZ/ICThe6+Q4nj7tOrwW0aOiLNAkTPTIT2JZRqpwLHNPm7cswo1GMbAxdXjqEAvvj6cUVkva2F -eBP2pKpM2D5RfhfhThbdLhcBfftr7haeJHsEwnx+43lXct+VXO8/X3IX5fNZC+2stkLZ1X2DbYpN -ixwv7JDHlLGBmjJyQ5omWcI+EfRhUK8zp0NSnJjSCH5mdd3BhQKbNUhw9RFV0SDCKTTYdU8TCWVG -OpQo5bLt1cxwJW2NhyZd2WNhUx8YbD2QWO3ywA6v6OH8XFCQMbtNaA6fOaMVTeCszFauZERB7ddh -VtdCnZlb3YhmSp3DrVAZfDivGgwW1oQGBEHbAlZehfO5Zg0HE8xIoO1u997cLcYLF+kiGeGAZD7S -es/7qG6clMeKuQmA2KnwkT7knWK1EreWJvsG3M7ipDK7xgJ2uffexEt5BM+8pPP2RDqypJycLEFH -ba/VXG56yMdp2xvDmRZ+xil4XeqeD7MQLoZ8JWzYn5rMJstn3mzlirlJUIdrCmv3OYWdOpAKqbaw -jGxomKksBFiiOVn5l5tg1otSwEb6a0ixsgbB8K9JAXZ0XUvGY+KrsrNLI9p29jErpXyiiBhEwREa -sYnYx+B+HaqgT0AlXE2YiqAf4B5NW9tMucU5S7ry7ZXB2XHM0ghn5VanaJ7JFm7yuJDBPJXEA90q -ZTfKnV8Vk/IXpEo5jP9nquj9BG4KVgLtAR+ucQVGOl/bHhcq4lCF0oj6fQGNg6kdEC1wFwvTEFRw -mWy+BTnU3zbnLA2T1nDgU/s0RILCfqQiQcgelCUTfacQq2d7lyXJMkImokriytSKPSKHhA11DVzV -e7uHIgh1U02yMmBwJ+PPfc4yaBTqJqecb04NKfZemwP/dOdjkxmUcuuwaWhy+xciVuyqdr1Znu+9 -ZUX0xKzNauRZAcxKW0ErS/vXFOGcW62tWHMaLzdz4cCL8xrDYNEQpXDfg/Q/2P+o8Jl9M6E31CHf -h9qK4EWDJgZhA1F9yTYeSBdIOziCxskO2mDSpKxps9ZJWy3frC+40y34njC2luws/j6nsYvmzGXn -5OJFGjuzsGNrO7bQ1ODZkykKQ+P8IGMcY15pld868dE9cPQW3O9PmJImmOCdksDQeg5MHkDyW45m -6cZfAAAA//8DAFBLAwQUAAYACAAAACEADdGQn7YAAAAbAQAAJwAAAHRoZW1lL3RoZW1lL19yZWxz -L3RoZW1lTWFuYWdlci54bWwucmVsc4SPTQrCMBSE94J3CG9v07oQkSbdiNCt1AOE5DUNNj8kUezt -Da4sCC6HYb6ZabuXnckTYzLeMWiqGgg66ZVxmsFtuOyOQFIWTonZO2SwYIKObzftFWeRSyhNJiRS -KC4xmHIOJ0qTnNCKVPmArjijj1bkIqOmQci70Ej3dX2g8ZsBfMUkvWIQe9UAGZZQmv+z/TgaiWcv -HxZd/lFBc9mFBSiixszgI5uqTATKW7q6xN8AAAD//wMAUEsBAi0AFAAGAAgAAAAhAIKKvBP6AAAA -HAIAABMAAAAAAAAAAAAAAAAAAAAAAFtDb250ZW50X1R5cGVzXS54bWxQSwECLQAUAAYACAAAACEA -pdan58AAAAA2AQAACwAAAAAAAAAAAAAAAAArAQAAX3JlbHMvLnJlbHNQSwECLQAUAAYACAAAACEA -a3mWFoMAAACKAAAAHAAAAAAAAAAAAAAAAAAUAgAAdGhlbWUvdGhlbWUvdGhlbWVNYW5hZ2VyLnht -bFBLAQItABQABgAIAAAAIQByB2XzmAYAAFAbAAAWAAAAAAAAAAAAAAAAANECAAB0aGVtZS90aGVt -ZS90aGVtZTEueG1sUEsBAi0AFAAGAAgAAAAhAA3RkJ+2AAAAGwEAACcAAAAAAAAAAAAAAAAAnQkA -AHRoZW1lL3RoZW1lL19yZWxzL3RoZW1lTWFuYWdlci54bWwucmVsc1BLBQYAAAAABQAFAF0BAACY -CgAAAAA= - -------=_NextPart_01CA0927.871204C0 -Content-Location: file:///C:/8CB3C889/TestFile(doc)_files/colorschememapping.xml -Content-Transfer-Encoding: quoted-printable -Content-Type: text/xml - - - -------=_NextPart_01CA0927.871204C0 -Content-Location: file:///C:/8CB3C889/TestFile(doc)_files/filelist.xml -Content-Transfer-Encoding: quoted-printable -Content-Type: text/xml; charset="utf-8" - - - - - - - -------=_NextPart_01CA0927.871204C0-- diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (WordML).xml b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (WordML).xml deleted file mode 100644 index ab74f33d..00000000 --- a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (WordML).xml +++ /dev/null @@ -1,3 +0,0 @@ - - -Tolsks202009-07-20T00:28:00Z2009-07-20T00:28:00Z13642080FPS1742440123.6. Svnserve Based Server3.6.1. IntroductionSubversion includes Svnserve - a lightweight stand-alone server which uses a custom protocol over an ordinary TCP/IP connection. It is ideal for smaller installations, or where a full blown Apache server cannot be used. In most cases svnserve is easier to setup and runs faster than the Apache based server, although it doesn't have some of the advanced features. And now that SASL support is included it is easy to secure as well. 3.6.2. Installing svnserveGet the latest version of Subversion from http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91 . Alternatively get a pre-packaged installer from CollabNet at http://www.collab.net/downloads/subversion . This installer will setup svnserve as a Windows service, and also includes some of the tools you need if you are going to use SASL for security. If you already have a version of Subversion installed, and svnserve is running, you will need to stop it before continuing. Run the Subversion installer. If you run the installer on your server (recommended) you can skip step 4. Open the windows-explorer, go to the installation directory of Subversion (usually C:\Program Files\Subversion) and in the bin directory, find the files svnserve.exe, intl3_svn.dll, libapr.dll, libapriconv.dll, libapriutil.dll, libdb*.dll, libeay32.dll and ssleay32.dll - copy these files, or just copy all of the bin directory, into a directory on your server e.g. c:\svnserve 3.6.3. Running svnserveNow that svnserve is installed, you need it running on your server. The simplest approach is to run the following from a DOS shell or create a windows shortcut: svnserve.exe --daemonsvnserve will now start waiting for incoming requests on port 3690. The --daemon switch tells svnserve to run as a daemon process, so it will always exist until it is manually terminated. If you have not yet created a repository, follow the instructions given with the Apache server setup Section 3.7.4, “Configuration”. To test that svnserve is working, use TortoiseSVNRepo-Browser to view a repository. \ No newline at end of file diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (XML).xml b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (XML).xml deleted file mode 100644 index bee6fa37..00000000 --- a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (XML).xml +++ /dev/null @@ -1,3 +0,0 @@ - - -3.6. Svnserve Based Server3.6.1. IntroductionSubversion includes Svnserve - a lightweight stand-alone server which uses a custom protocol over an ordinary TCP/IP connection. It is ideal for smaller installations, or where a full blown Apache server cannot be used. In most cases svnserve is easier to setup and runs faster than the Apache based server, although it doesn't have some of the advanced features. And now that SASL support is included it is easy to secure as well. 3.6.2. Installing svnserveGet the latest version of Subversion from http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91 . Alternatively get a pre-packaged installer from CollabNet at http://www.collab.net/downloads/subversion . This installer will setup svnserve as a Windows service, and also includes some of the tools you need if you are going to use SASL for security. If you already have a version of Subversion installed, and svnserve is running, you will need to stop it before continuing. Run the Subversion installer. If you run the installer on your server (recommended) you can skip step 4. Open the windows-explorer, go to the installation directory of Subversion (usually C:\Program Files\Subversion) and in the bin directory, find the files svnserve.exe, intl3_svn.dll, libapr.dll, libapriconv.dll, libapriutil.dll, libdb*.dll, libeay32.dll and ssleay32.dll - copy these files, or just copy all of the bin directory, into a directory on your server e.g. c:\svnserve 3.6.3. Running svnserveNow that svnserve is installed, you need it running on your server. The simplest approach is to run the following from a DOS shell or create a windows shortcut: svnserve.exe --daemonsvnserve will now start waiting for incoming requests on port 3690. The --daemon switch tells svnserve to run as a daemon process, so it will always exist until it is manually terminated. If you have not yet created a repository, follow the instructions given with the Apache server setup Section 3.7.4, “Configuration”. To test that svnserve is working, use TortoiseSVNRepo-Browser to view a repository. Tolsks21601-01-01T00:00:00Z2009-07-19T23:56:00Z2009-07-19T23:56:00Z113642080Microsoft Office Word0174falseTitle1FPSfalse2440false4194381605mk:@MSITStore:C:\Program%20Files\TortoiseSVN\bin\TortoiseSVN_en.chm::/tsvn-serversetup-apache.htmltsvn-serversetup-apache-47471150305http://www.collab.net/downloads/subversion4194384005http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91false12.0000 \ No newline at end of file diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (doc).doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (doc).doc deleted file mode 100644 index ef27828a..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (doc).doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (docm).docm b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (docm).docm deleted file mode 100644 index aee5c2cf..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (docm).docm and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (docx).docx b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (docx).docx deleted file mode 100644 index 4d077f59..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (docx).docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (dot).dot b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (dot).dot deleted file mode 100644 index 72a5e521..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (dot).dot and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (dotx).dotx b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (dotx).dotx deleted file mode 100644 index 4524a959..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (dotx).dotx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (enc).doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (enc).doc deleted file mode 100644 index a339815c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (enc).doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (enc).docx b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (enc).docx deleted file mode 100644 index 0d14e3c4..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (enc).docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (odt).odt b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (odt).odt deleted file mode 100644 index bd0c9161..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (odt).odt and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (pre97).doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (pre97).doc deleted file mode 100644 index 33599e33..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (pre97).doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (rtf).rtf b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (rtf).rtf deleted file mode 100644 index 3d44a726..00000000 --- a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/GetListOfFilesInFolder/Test File (rtf).rtf +++ /dev/null @@ -1,242 +0,0 @@ -{\rtf1\adeflang1025\ansi\ansicpg1251\uc1\adeff0\deff0\stshfdbch37\stshfloch37\stshfhich37\stshfbi0\deflang1049\deflangfe1049\themelang1049\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\f2\fbidi \fmodern\fcharset204\fprq1{\*\panose 02070309020205020404}Courier New;}{\f34\fbidi \froman\fcharset204\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\f36\fbidi \froman\fcharset204\fprq2{\*\panose 02040503050406030204}Cambria;} -{\f37\fbidi \fswiss\fcharset204\fprq2{\*\panose 020f0502020204030204}Calibri;}{\f38\fbidi \fswiss\fcharset204\fprq2{\*\panose 020b0604030504040204}Tahoma;}{\flomajor\f31500\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fdbmajor\f31501\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \froman\fcharset204\fprq2{\*\panose 02040503050406030204}Cambria;} -{\fbimajor\f31503\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fdbminor\f31505\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset204\fprq2{\*\panose 020f0502020204030204}Calibri;} -{\fbiminor\f31507\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f41\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\f39\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\f42\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\f46\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f61\fbidi \fmodern\fcharset0\fprq1 Courier New;}{\f59\fbidi \fmodern\fcharset238\fprq1 Courier New CE;} -{\f62\fbidi \fmodern\fcharset161\fprq1 Courier New Greek;}{\f63\fbidi \fmodern\fcharset162\fprq1 Courier New Tur;}{\f64\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew);}{\f65\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic);} -{\f66\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f67\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f381\fbidi \froman\fcharset0\fprq2 Cambria Math;}{\f379\fbidi \froman\fcharset238\fprq2 Cambria Math CE;} -{\f382\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f383\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f386\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}{\f401\fbidi \froman\fcharset0\fprq2 Cambria;} -{\f399\fbidi \froman\fcharset238\fprq2 Cambria CE;}{\f402\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\f403\fbidi \froman\fcharset162\fprq2 Cambria Tur;}{\f406\fbidi \froman\fcharset186\fprq2 Cambria Baltic;} -{\f411\fbidi \fswiss\fcharset0\fprq2 Calibri;}{\f409\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f412\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f413\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} -{\f416\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f421\fbidi \fswiss\fcharset0\fprq2 Tahoma;}{\f419\fbidi \fswiss\fcharset238\fprq2 Tahoma CE;}{\f422\fbidi \fswiss\fcharset161\fprq2 Tahoma Greek;}{\f423\fbidi \fswiss\fcharset162\fprq2 Tahoma Tur;} -{\f424\fbidi \fswiss\fcharset177\fprq2 Tahoma (Hebrew);}{\f425\fbidi \fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f426\fbidi \fswiss\fcharset186\fprq2 Tahoma Baltic;}{\f427\fbidi \fswiss\fcharset163\fprq2 Tahoma (Vietnamese);} -{\f428\fbidi \fswiss\fcharset222\fprq2 Tahoma (Thai);}{\flomajor\f31510\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbmajor\f31520\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31530\fbidi \froman\fcharset0\fprq2 Cambria;} -{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;}{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;} -{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;}{\fbimajor\f31540\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\flominor\f31550\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31560\fbidi \froman\fcharset0\fprq2 Times New Roman;} -{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31570\fbidi \fswiss\fcharset0\fprq2 Calibri;}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;} -{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;} -{\fbiminor\f31580\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; -\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; -\red192\green192\blue192;\red54\green95\blue145;\red79\green129\blue189;}{\*\defchp \loch\af37\hich\af37\dbch\af37 }{\*\defpap \ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{ -\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1049\langfe1033\loch\f37\hich\af37\dbch\af37\cgrid\langnp1049\langfenp1033 -\snext0 \sqformat \spriority0 Normal;}{\s1\ql \li0\ri0\sb480\sl276\slmult1\keep\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \ab\af0\afs28\alang1025 \ltrch\fcs0 -\b\f36\fs28\cf17\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 \sbasedon0 \snext0 \slink15 \sqformat \spriority9 heading 1;}{\s2\ql \li0\ri0\sb240\sa60\sl276\slmult1 -\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \ab\ai\af0\afs28\alang1025 \ltrch\fcs0 \b\i\f36\fs28\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 -\sbasedon0 \snext0 \slink17 \sqformat \spriority9 heading 2;}{\s3\ql \li0\ri0\sb240\sa60\sl276\slmult1\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \ab\af0\afs26\alang1025 \ltrch\fcs0 -\b\f36\fs26\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 \sbasedon0 \snext0 \slink18 \sqformat \spriority9 heading 3;}{\s4\ql \li0\ri0\sb240\sa60\sl276\slmult1 -\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel3\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \ab\af0\afs28\alang1025 \ltrch\fcs0 \b\f37\fs28\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 \sbasedon0 \snext0 \slink19 \sqformat \spriority9 -heading 4;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* -\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv -\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\loch\f37\hich\af37\dbch\af37\cgrid\langnp1049\langfenp1049 -\snext11 \ssemihidden \sunhideused \sqformat Normal Table;}{\*\cs15 \additive \rtlch\fcs1 \ab\af0\afs28 \ltrch\fcs0 \b\f36\fs28\cf17 \sbasedon10 \slink1 \slocked \spriority9 Heading 1 Char;}{\*\cs16 \additive \rtlch\fcs1 \ab\ai\af0 \ltrch\fcs0 \b\i\cf18 -\sbasedon10 \sqformat \spriority21 Intense Emphasis;}{\*\cs17 \additive \rtlch\fcs1 \ab\ai\af0\afs28 \ltrch\fcs0 \b\i\f36\fs28\lang0\langfe1033\langfenp1033 \sbasedon10 \slink2 \slocked \ssemihidden \spriority9 Heading 2 Char;}{\*\cs18 \additive -\rtlch\fcs1 \ab\af0\afs26 \ltrch\fcs0 \b\f36\fs26\lang0\langfe1033\langfenp1033 \sbasedon10 \slink3 \slocked \ssemihidden \spriority9 Heading 3 Char;}{\*\cs19 \additive \rtlch\fcs1 \ab\af0\afs28 \ltrch\fcs0 \b\f37\fs28\lang0\langfe1033\langfenp1033 -\sbasedon10 \slink4 \slocked \spriority9 Heading 4 Char;}{\*\cs20 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf2 \sbasedon10 \ssemihidden \sunhideused Hyperlink;}{ -\s21\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 -\sbasedon0 \snext21 \sunhideused Normal (Web);}{\*\cs22 \additive \rtlch\fcs1 \ai\af0 \ltrch\fcs0 \i \sbasedon10 \sqformat \spriority20 Emphasis;}{\*\cs23 \additive \rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20 \sbasedon10 \ssemihidden \sunhideused -HTML Code;}{\s24\ql \li0\ri0\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af2\afs20\alang1025 -\ltrch\fcs0 \f2\fs20\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 \sbasedon0 \snext24 \slink25 \ssemihidden \sunhideused HTML Preformatted;}{\*\cs25 \additive \rtlch\fcs1 \af2 \ltrch\fcs0 \f2\cf1 \sbasedon10 \slink24 \slocked \ssemihidden -HTML Preformatted Char;}{\*\cs26 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 \spriority0 guimenu;}{\*\cs27 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 \spriority0 guimenuitem;}{\*\cs28 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 -\sbasedon10 \spriority0 quote;}{\*\cs29 \additive \rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \fs16 \sbasedon10 \ssemihidden \sunhideused annotation reference;}{\s30\ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1033\loch\f37\hich\af37\dbch\af37\cgrid\langnp1049\langfenp1033 -\sbasedon0 \snext30 \slink31 \ssemihidden \sunhideused annotation text;}{\*\cs31 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \lang0\langfe1033\langfenp1033 \sbasedon10 \slink30 \slocked \ssemihidden Comment Text Char;}{\s32\ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \ab\af0\afs20\alang1025 \ltrch\fcs0 \b\fs20\lang1049\langfe1033\loch\f37\hich\af37\dbch\af37\cgrid\langnp1049\langfenp1033 -\sbasedon30 \snext30 \slink33 \ssemihidden \sunhideused annotation subject;}{\*\cs33 \additive \rtlch\fcs1 \ab\af0 \ltrch\fcs0 \b\lang0\langfe1033\langfenp1033 \sbasedon31 \slink32 \slocked \ssemihidden Comment Subject Char;}{ -\s34\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af38\afs16\alang1025 \ltrch\fcs0 \fs16\lang1049\langfe1033\loch\f38\hich\af38\dbch\af37\cgrid\langnp1049\langfenp1033 -\sbasedon0 \snext34 \slink35 \ssemihidden \sunhideused Balloon Text;}{\*\cs35 \additive \rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\lang0\langfe1033\langfenp1033 \sbasedon10 \slink34 \slocked \ssemihidden Balloon Text Char;}}{\*\listtable -{\list\listtemplateid-72729606{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li720 -\jclisttab\tx720\lin720 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li1440 -\jclisttab\tx1440\lin1440 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li2160 -\jclisttab\tx2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li2880 -\jclisttab\tx2880\lin2880 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li3600 -\jclisttab\tx3600\lin3600 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li4320 -\jclisttab\tx4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li5040 -\jclisttab\tx5040\lin5040 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li5760 -\jclisttab\tx5760\lin5760 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li6480 -\jclisttab\tx6480\lin6480 }{\listname ;}\listid401415626}}{\*\listoverridetable{\listoverride\listid401415626\listoverridecount0\ls1}}{\*\rsidtbl \rsid2572821\rsid15558508}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0 -\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\author Tols}{\operator ks}{\creatim\yr2009\mo7\dy20\hr10\min41}{\revtim\yr2009\mo7\dy20\hr10\min41}{\version2}{\edmins0}{\nofpages1}{\nofwords323}{\nofchars2121}{\*\company FPS} -{\nofcharsws2440}{\vern32893}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}\paperw11906\paperh16838\margl1701\margr850\margt1134\margb1134\gutter0\ltrsect -\deftab708\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors1 -\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1701\dgvorigin1134\dghshow1\dgvshow1 -\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct -\asianbrkrule\rsidroot1181740\newtblstyruls\nogrowautofit\utinl \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sectrsid2572821\sftnbj {\*\pnseclvl1 -\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5 -\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang -{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\s2\ql \li0\ri0\sb240\sa60\sl276\slmult1 -\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 \ab\ai\af0\afs28\alang1025 \ltrch\fcs0 \b\i\f36\fs28\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 -\lang9\langfe1033\langnp9\insrsid2572821 {\*\bkmkstart tsvn-serversetup-svnserve}{\*\bkmkend tsvn-serversetup-svnserve}3.6.\~Svnserve Based Server -\par }\pard\plain \ltrpar\s3\ql \li0\ri0\sb240\sa60\sl276\slmult1\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 \ab\af0\afs26\alang1025 \ltrch\fcs0 -\b\f36\fs26\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1033\langnp9\insrsid2572821 {\*\bkmkstart tsvn-serversetup-svnserve-1}{\*\bkmkend tsvn-serversetup-svnserve-1}3.6.1.\~Introduction -\par }\pard\plain \ltrpar\s21\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 -\fs24\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 {\*\bkmkstart id776356}{\*\bkmkend id776356} -Subversion includes Svnserve - a lightweight stand-alone server which uses a custom protocol over an ordinary TCP/IP connection. It is ideal for smaller installations, or where a full blown Apache server cannot be used. -\par In most cases svnserve is easier to setup and runs faster than the Apache based server, although it doesn't have some of the advanced features. And now that SASL support is included it is easy to secure as well. -\par }\pard\plain \ltrpar\s3\ql \li0\ri0\sb240\sa60\sl276\slmult1\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 \ab\af0\afs26\alang1025 \ltrch\fcs0 -\b\f36\fs26\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1033\langnp9\insrsid2572821 {\*\bkmkstart tsvn-serversetup-svnserve-2}{\*\bkmkend tsvn-serversetup-svnserve-2}3.6.2.\~Installing svnserve -\par {\listtext\pard\plain\ltrpar \s21 \rtlch\fcs1 \af0 \ltrch\fcs0 \cf1\lang9\langfe1049\dbch\af0\langnp9\insrsid2572821 \hich\af0\dbch\af0\loch\f0 1.\tab}}\pard\plain \ltrpar\s21\ql \fi-360\li720\ri0\sb100\sa100\sbauto1\saauto1\widctlpar -\jclisttab\tx720\wrapdefault\aspalpha\aspnum\faauto\ls1\adjustright\rin0\lin720\itap0\pararsid2572821 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 -\lang9\langfe1049\langnp9\insrsid2572821 Get the latest version of Subversion from }{\field{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 - HYPERLINK "http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91" \\t "_top" }}{\fldrslt {\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs22\i\lang9\langfe1049\langnp9\insrsid2572821 -http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs20\ul\cf2\lang9\langfe1049\langnp9\insrsid2572821 }}}\sectd \ltrsect -\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sectrsid2572821\sftnbj {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 . Alternatively get a pre-packaged installer from CollabNet at }{\field{\*\fldinst -{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 HYPERLINK "http://www.collab.net/downloads/subversion" \\t "_top" }}{\fldrslt {\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs22\i\lang9\langfe1049\langnp9\insrsid2572821 -http://www.collab.net/downloads/subversion}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs20\ul\cf2\lang9\langfe1049\langnp9\insrsid2572821 }}}\sectd \ltrsect\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sectrsid2572821\sftnbj { -\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 . This installer will setup svnserve as a Windows service, and also includes some of the tools you need if you are going to use SASL for security. -\par {\listtext\pard\plain\ltrpar \s21 \rtlch\fcs1 \af0 \ltrch\fcs0 \cf1\lang9\langfe1049\dbch\af0\langnp9\insrsid2572821 \hich\af0\dbch\af0\loch\f0 2.\tab} -If you already have a version of Subversion installed, and svnserve is running, you will need to stop it before continuing. -\par {\listtext\pard\plain\ltrpar \s21 \rtlch\fcs1 \af0 \ltrch\fcs0 \cf1\lang9\langfe1049\dbch\af0\langnp9\insrsid2572821 \hich\af0\dbch\af0\loch\f0 3.\tab} -Run the Subversion installer. If you run the installer on your server (recommended) you can skip step 4. -\par {\listtext\pard\plain\ltrpar \s21 \rtlch\fcs1 \af0 \ltrch\fcs0 \cf1\lang9\langfe1049\dbch\af0\langnp9\insrsid2572821 \hich\af0\dbch\af0\loch\f0 4.\tab}Open the windows-explorer, go to the installation directory of Subversion (usually }{\rtlch\fcs1 -\af2\afs20 \ltrch\fcs0 \cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 C:\\Program Files\\Subversion}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 ) and in the }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 -\cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 bin}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 directory, find the files }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 -svnserve.exe}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 , }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 intl3_svn.dll}{\rtlch\fcs1 \af0 \ltrch\fcs0 -\lang9\langfe1049\langnp9\insrsid2572821 , }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 libapr.dll}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 , }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 -\cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 libapriconv.dll}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 , }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 libapriutil.dll}{ -\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 , }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 libdb*.dll}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 , }{ -\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 libeay32.dll}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 and }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 -\cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 ssleay32.dll}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 - copy these files, or just copy all of the }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 -\cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 bin}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 directory, into a directory on your server e.g. }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 -\cs23\f2\fs20\lang9\langfe1049\langnp9\insrsid2572821 c:\\svnserve}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 -\par }\pard\plain \ltrpar\s3\ql \li0\ri0\sb240\sa60\sl276\slmult1\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 \ab\af0\afs26\alang1025 \ltrch\fcs0 -\b\f36\fs26\lang1049\langfe1033\cgrid\langnp1049\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1033\langnp9\insrsid2572821 {\*\bkmkstart tsvn-serversetup-svnserve-3}{\*\bkmkend tsvn-serversetup-svnserve-3}3.6.3.\~Running svnserve -\par }\pard\plain \ltrpar\s21\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 -\fs24\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 Now that svnserve is installed, you need it running on your server. The simplest approach is to run the following from -a DOS shell or create a windows shortcut: -\par }\pard\plain \ltrpar\s24\ql \li0\ri0\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 -\af2\afs20\alang1025 \ltrch\fcs0 \f2\fs20\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af2 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 svnserve.exe --daemon -\par }\pard\plain \ltrpar\s21\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid2572821 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 -\fs24\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 -svnserve will now start waiting for incoming requests on port 3690. The --daemon switch tells svnserve to run as a daemon process, so it will always exist until it is manually terminated. -\par If you have not yet created a repository, follow the instructions given with the Apache server setup }{\field{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 HYPERLINK "mk:@MSITStore:C:\\\\Program%20Files\\\\TortoiseSVN -\\\\bin\\\\TortoiseSVN_en.chm::/tsvn-serversetup-apache.html" \\l "tsvn-serversetup-apache-4" \\o "3.7.4.\~Configuration" }}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs20\ul\cf2\lang9\langfe1049\langnp9\insrsid2572821 Section\~3.7.4, \'93Configuration\'94} -}}\sectd \ltrsect\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sectrsid2572821\sftnbj {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 . -\par To test that svnserve is working, use }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs26\lang9\langfe1049\langnp9\insrsid2572821 TortoiseSVN}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 \u8594\'3e }{\rtlch\fcs1 \af0 \ltrch\fcs0 -\cs27\lang9\langfe1049\langnp9\insrsid2572821 Repo-Browser}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang9\langfe1049\langnp9\insrsid2572821 to view a repository. -\par }{\*\themedata 504b030414000600080000002100828abc13fa0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb6ac3301045f785fe83d0b6d8 -72ba28a5d8cea249777d2cd20f18e4b12d6a8f843409c9df77ecb850ba082d74231062ce997b55ae8fe3a00e1893f354e9555e6885647de3a8abf4fbee29bbd7 -2a3150038327acf409935ed7d757e5ee14302999a654e99e393c18936c8f23a4dc072479697d1c81e51a3b13c07e4087e6b628ee8cf5c4489cf1c4d075f92a0b -44d7a07a83c82f308ac7b0a0f0fbf90c2480980b58abc733615aa2d210c2e02cb04430076a7ee833dfb6ce62e3ed7e14693e8317d8cd0433bf5c60f53fea2fe7 -065bd80facb647e9e25c7fc421fd2ddb526b2e9373fed4bb902e182e97b7b461e6bfad3f010000ffff0300504b030414000600080000002100a5d6a7e7c00000 -00360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4fc7060abb08 -84a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b63095120f88d94fbc -52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462a1a82fe353 -bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f7468656d652f7468 -656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b4b0d592c9c -070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b4757e8d3f7 -29e245eb2b260a0238fd010000ffff0300504b030414000600080000002100720765f398060000501b0000160000007468656d652f7468656d652f7468656d65 -312e786d6cec594f6fdb3614bf0fd87720746f6327761a07758ad8b19b2d4d1bc46e871e698996d850a240d2497d1bdae38001c3ba618715d86d87615b8116d8 -a5fb34d93a6c1dd0afb0475292c5585e9236d88aad0e105be48fefff7b7ca4ae5ebb1f33744884a43c697bf5cb350f91c4e7014dc2b6777bd8bfb4e621a97012 -60c613d2f6a6447ad736de7fef2a5e5711890982f5895cc76d2f522a5d5f5a923e0c637999a72481b931173156f028c2a540e023a01bb3a5e55a6d7529c634f1 -508263207b6b3ca63e41434dd2dbc889f7183c264aea019f8981264d9c15061b1cd435424e659709748859db033e013f1a92fbca430c4b05136dafd1d47fded2 -c6d525bc9e2d626ac1dad2babef964ebb205c1c1b2e129c251c1b4de6fb4ae6c15f40d80a9795cafd7ebf6ea053d03c0be0f9a5a59ca341bfdb57a27a75902d9 -9ff3b4bbb566ade1e24bf457e6646e753a9d662b93c5123520fbb331875fabad3636971dbc01597c730edfe86c76bbab0ede802c7e750edfbfd25a6db878038a -184d0ee6d035f8f4fb19f50232e66cbb12be06f0b55a069fa1201a8ae8d22cc63c518b622dc6f7b8e8034003195634416a9a9231f6218abb381e098a3503bc4e -7069c60ef9726e48f342d21734556defc3144346cce8bd7afefdabe74fd1f18367c70f7e3a7ef8f0f8c18f9690b36a1b276179d5cb6f3ffbf3f1c7e88fa7dfbc -7cf445355e96f1bffef0c92f3f7f5e0d84f49989f3e2cb27bf3d7bf2e2ab4f7fffee51057c53e051193ea43191e8263942fb3c06c58c555cc9c9489c6fc530c2 -b4bc623309254eb0e65241bfa722077d738a59e61d478e0e712d784740f9a8025e9fdc73041e4462a26805e79d287680bb9cb30e179556d8d1bc4a661e4e92b0 -9ab9989471fb181f56f1eee2c4f16f6f9242ddccc3d251bc1b1147cc3d86138543921085f41c3f20a442bbbb943a76dda5bee0928f15ba4b5107d34a930ce9c8 -89a6d9a26d1a835fa6553a83bf1ddbecde411dceaab4de22872e12b202b30ae187843966bc8e270ac755248738666583dfc02aaa127230157e19d7930a3c1d12 -c6512f205256adb92540df92d3773054ac4ab7efb269ec2285a20755346f60cecbc82d7ed08d709c5661073489cad80fe4018428467b5c55c177b99b21fa19fc -809385eebe4389e3eed3abc16d1a3a22cd0244cf4c84f625946aa702c734f9bb72cc28d4631b0317578ea100bef8fa714564bdad857813f6a4aa4cd83e517e17 -e14e16dd2e17017dfb6bee169e247b04c27c7ee3795772df955cef3f5f7217e5f3590bedacb642d9d57d836d8a4d8b1c2fec90c794b1819a3272439a2659c23e -11f46150af33a743529c98d2087e6675ddc185029b354870f51155d120c22934d8754f130965463a9428e5b2edd5cc70256d8d87265dd96361531f186c3d9058 -edf2c00eafe8e1fc5c509031bb4d680e9f39a3154de0accc56ae644441edd76156d7429d995bdd88664a9dc3ad50197c38af1a0c16d684060441db02565e85f3 -b9660d0713cc48a0ed6ef7dedc2dc60b17e92219e180643ed27acffba86e9c94c78ab90980d8a9f0913ee49d62b512b79626fb06dccee2a432bbc60276b9f7de -c44b7904cfbca4f3f6443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc399167ec629785dea9e0fb3102e867c256cd89f9acc26cb67de6ce58ab94950876b0a -6bf739859d3a900aa9b6b08c6c6898a92c0458a23959f9979b60d68b52c046fa6b48b1b206c1f0af490176745d4bc663e2abb2b34b23da76f6312ba57ca28818 -44c1111ab189d8c7e07e1daaa04f40255c4d988aa01fe01e4d5bdb4cb9c5394bbaf2ed95c1d971ccd20867e556a7689ec9166ef2b890c13c95c403dd2a6537ca -9d5f1593f217a44a398cff67aae8fd046e0a5602ed011fae7105463a5fdb1e172ae25085d288fa7d018d83a91d102d70170bd3105470996cbe0539d4df36e72c -0d93d670e053fb344482c27ea42241c81e9425137da710ab677b9725c9324226a24ae2cad48a3d2287840d750d5cd57bbb87220875534db232607027e3cf7dce -326814ea26a79c6f4e0d29f65e9b03ff74e76393199472ebb0696872fb172256ecaa76bd599eefbd6545f4c4accd6ae45901cc4a5b412b4bfbd714e19c5badad -58731a2f3773e1c08bf31ac360d110a570df83f43fd8ffa8f0997d33a137d421df87da8ae0458326066103517dc9361e4817483b3882c6c90eda60d2a4ac69b3 -d6495b2ddfac2fb8d32df89e30b696ec2cfe3ea7b18be6cc65e7e4e2451a3bb3b0636b3bb6d0d4e0d993290a43e3fc20631c635e6995df3af1d13d70f416dcef -4f98922698e09d92c0d07a0e4c1e40f25b8e66e9c65f000000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d65 -2f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d36 -3f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e -3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d985 -0528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100828abc13fa0000001c020000130000000000000000000000 -0000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b00000000000000000000 -0000002b0100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c0000000000000000000000000014020000 -7468656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100720765f398060000501b00001600000000000000 -000000000000d10200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b01000027000000 -000000000000000000009d0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000980a00000000} -{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d -617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 -6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 -656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} -{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7; -\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4; -\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7;\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid; -\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography; -\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 0105000002000000180000004d73786d6c322e534158584d4c5265616465722e352e3000000000000000000000060000 -d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffffec69d9888b8b3d4c859eaf6cd158be0f00000000000000000000000070c4 -317dca08ca01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ImageToPdf/Test.bmp b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ImageToPdf/Test.bmp deleted file mode 100644 index c9f5ffe3..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ImageToPdf/Test.bmp and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ImageToPdf/Test.jpg b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ImageToPdf/Test.jpg deleted file mode 100644 index c9083f44..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ImageToPdf/Test.jpg and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ImageToPdf/Test.png b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ImageToPdf/Test.png deleted file mode 100644 index 2f827899..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/ImageToPdf/Test.png and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/LoadAndSave/Test File (doc).doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/LoadAndSave/Test File (doc).doc deleted file mode 100644 index ef27828a..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/LoadAndSave/Test File (doc).doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/LoadAndSaveDocToDatabase/Test File (doc).doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/LoadAndSaveDocToDatabase/Test File (doc).doc deleted file mode 100644 index ef27828a..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/LoadAndSaveDocToDatabase/Test File (doc).doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/LoadAndSaveToStream/Test File (doc).doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/LoadAndSaveToStream/Test File (doc).doc deleted file mode 100644 index ef27828a..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/LoadAndSaveToStream/Test File (doc).doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/LoadEncryptedDoc/LoadEncrypted.docx b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/LoadEncryptedDoc/LoadEncrypted.docx deleted file mode 100644 index 2829d179..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/LoadEncryptedDoc/LoadEncrypted.docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/LoadTxt/LoadTxt.txt b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/LoadTxt/LoadTxt.txt deleted file mode 100644 index b3339816..00000000 --- a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/LoadTxt/LoadTxt.txt +++ /dev/null @@ -1,15 +0,0 @@ - Despite the fact txt format itself provides us with only "text" features for document lay-out, an ordinary txt file may contains many different pieces of formatting. - One of the text features is using "Tab" key to make indented paragraphs. - Paragraphs also may be nested within one another by using multiple "Tab" to increase the indent. - -Many txt files aslo contain lists formatted with bullets. The bullet symbol may take any of a variety of shapes, such as: -- circular. -- square. -- diamond. -- arrow. -- etc. - -An alternative method to format data is to use a numbered list. Here is some examples of using numbers and characters for making numbered list: -1. Arabic numerals (1, 2, 3, ...). -2. Roman numerals (I, II, III, ... or i, ii, iii, ...). -3. Letters (A, B, C, ... or a, b, c, ...). \ No newline at end of file diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/OpenDocUsingStream/test.docx b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/OpenDocUsingStream/test.docx deleted file mode 100644 index 475629b4..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/OpenDocUsingStream/test.docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/OpenDocument/test.docx b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/OpenDocument/test.docx deleted file mode 100644 index 475629b4..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/OpenDocument/test.docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/OpenEncryptedDocument/LoadEncrypted.docx b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/OpenEncryptedDocument/LoadEncrypted.docx deleted file mode 100644 index 2829d179..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/OpenEncryptedDocument/LoadEncrypted.docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/PageSplitter/Rendering.doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/PageSplitter/Rendering.doc deleted file mode 100644 index 6e97a1eb..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/PageSplitter/Rendering.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/PageSplitter/Sample Documentation.doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/PageSplitter/Sample Documentation.doc deleted file mode 100644 index 3789b896..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/PageSplitter/Sample Documentation.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/SendToClientBrowser/test.docx b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/SendToClientBrowser/test.docx deleted file mode 100644 index 475629b4..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/SendToClientBrowser/test.docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/SpecifySaveOption/TestFile RenderShape.docx b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/SpecifySaveOption/TestFile RenderShape.docx deleted file mode 100644 index 8b32147a..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/SpecifySaveOption/TestFile RenderShape.docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/SplitIntoHtmlPages/SOI 2007-2012-DeeM with footnote added.doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/SplitIntoHtmlPages/SOI 2007-2012-DeeM with footnote added.doc deleted file mode 100644 index 180c8617..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/SplitIntoHtmlPages/SOI 2007-2012-DeeM with footnote added.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/SplitIntoHtmlPages/TocTemplate.doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/SplitIntoHtmlPages/TocTemplate.doc deleted file mode 100644 index 539a474f..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/SplitIntoHtmlPages/TocTemplate.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/Word2Help/Sample Documentation.doc b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/Word2Help/Sample Documentation.doc deleted file mode 100644 index 7a1329be..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/Word2Help/Sample Documentation.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/Word2Help/banner.html b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/Word2Help/banner.html deleted file mode 100644 index f1c49264..00000000 --- a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/Word2Help/banner.html +++ /dev/null @@ -1,15 +0,0 @@ - -
          -
          - - - - - -
          Aspose.Words -
          -
          -
          -

          ###TOPIC_NAME###

          -
          -
          diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/Word2Help/footer.html b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/Word2Help/footer.html deleted file mode 100644 index ae51e811..00000000 --- a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/Word2Help/footer.html +++ /dev/null @@ -1,8 +0,0 @@ - - diff --git a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/Word2Help/header.html b/Examples/src/main/resources/com/aspose/words/examples/loading_saving/Word2Help/header.html deleted file mode 100644 index 5f2163f3..00000000 --- a/Examples/src/main/resources/com/aspose/words/examples/loading_saving/Word2Help/header.html +++ /dev/null @@ -1,6 +0,0 @@ - - - - title - - diff --git a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/ApplyCustomLogicToEmptyRegions/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/mail_merge/ApplyCustomLogicToEmptyRegions/TestFile.doc deleted file mode 100644 index 175afbb4..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/ApplyCustomLogicToEmptyRegions/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MailMergeFormFields/Template.doc b/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MailMergeFormFields/Template.doc deleted file mode 100644 index fae236eb..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MailMergeFormFields/Template.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MailMergeUsingMustacheSyntax/VendorTemplate.doc b/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MailMergeUsingMustacheSyntax/VendorTemplate.doc deleted file mode 100644 index 22582cad..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MailMergeUsingMustacheSyntax/VendorTemplate.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MailMergeUsingMustacheSyntax/Vendors.xml b/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MailMergeUsingMustacheSyntax/Vendors.xml deleted file mode 100644 index e1f6967e..00000000 --- a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MailMergeUsingMustacheSyntax/Vendors.xml +++ /dev/null @@ -1,28 +0,0 @@ - - -Toyota - -Corolla GLI -GLI Description -18 - - - Corolla XLI - XLI Description - 16 - - - -Honda - - City - City Description - 15 - - - Civic - Civic Description - 18 - - - \ No newline at end of file diff --git a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MultipleDocsInMailMerge/Customers.mdb b/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MultipleDocsInMailMerge/Customers.mdb deleted file mode 100644 index f49b6014..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MultipleDocsInMailMerge/Customers.mdb and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MultipleDocsInMailMerge/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MultipleDocsInMailMerge/TestFile.doc deleted file mode 100644 index f0e53535..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MultipleDocsInMailMerge/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MustacheTemplateSyntax/ExecuteTemplate.doc b/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MustacheTemplateSyntax/ExecuteTemplate.doc deleted file mode 100644 index 3978ca9b..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MustacheTemplateSyntax/ExecuteTemplate.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MustacheTemplateSyntax/Orders.xml b/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MustacheTemplateSyntax/Orders.xml deleted file mode 100644 index fb5680c7..00000000 --- a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MustacheTemplateSyntax/Orders.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - -
          - 23 - Nelson Street - Howick - Auckland -
          - 543 1234 - 03/01/2010 - 14.00 - - BBQ Chicken Pizza - 6.00 - 1 - 6.00 - - - 1.5 Litre Coke - 4.00 - 2 - 8.00 - -
          - -
          - 10 - Parkville Avenue - Pakuranga - Auckland -
          - 548 7342 - 05/03/2010 - 6.00 - - Hawaiian Pizza - 4.00 - 1 - 4.00 - - - Fries - 1.00 - 2 - 2.00 - -
          -
          \ No newline at end of file diff --git a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MustacheTemplateSyntax/Output.doc b/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MustacheTemplateSyntax/Output.doc deleted file mode 100644 index 9cb69f8e..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MustacheTemplateSyntax/Output.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MustacheTemplateSyntax/Output.docx b/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MustacheTemplateSyntax/Output.docx deleted file mode 100644 index bb9bcf5b..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/MustacheTemplateSyntax/Output.docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/NestedMailMerge/Invoice Template.doc b/Examples/src/main/resources/com/aspose/words/examples/mail_merge/NestedMailMerge/Invoice Template.doc deleted file mode 100644 index 8f8dc8c1..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/NestedMailMerge/Invoice Template.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/NestedMailMerge/InvoiceDB.mdb b/Examples/src/main/resources/com/aspose/words/examples/mail_merge/NestedMailMerge/InvoiceDB.mdb deleted file mode 100644 index 043b3390..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/NestedMailMerge/InvoiceDB.mdb and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/RemoveEmptyRegions/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/mail_merge/RemoveEmptyRegions/TestFile.doc deleted file mode 100644 index 175afbb4..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/RemoveEmptyRegions/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/RemoveUnmergedRegions/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/mail_merge/RemoveUnmergedRegions/TestFile.doc deleted file mode 100644 index 175afbb4..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/RemoveUnmergedRegions/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/SimpleMailMerge/MailMerge.ExecuteArray.doc b/Examples/src/main/resources/com/aspose/words/examples/mail_merge/SimpleMailMerge/MailMerge.ExecuteArray.doc deleted file mode 100644 index bef8b12e..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/SimpleMailMerge/MailMerge.ExecuteArray.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/XMLMailMerge/Customers.xml b/Examples/src/main/resources/com/aspose/words/examples/mail_merge/XMLMailMerge/Customers.xml deleted file mode 100644 index 92d13fcf..00000000 --- a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/XMLMailMerge/Customers.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/XMLMailMerge/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/mail_merge/XMLMailMerge/TestFile.doc deleted file mode 100644 index 5f36ff45..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/mail_merge/XMLMailMerge/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/Hyperlink/ReplaceHyperlinks/ReplaceHyperlinks.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/Hyperlink/ReplaceHyperlinks/ReplaceHyperlinks.doc deleted file mode 100644 index 5c3958df..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/Hyperlink/ReplaceHyperlinks/ReplaceHyperlinks.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/Ranges/RangesDeleteText/Document.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/Ranges/RangesDeleteText/Document.doc deleted file mode 100644 index cc74d18a..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/Ranges/RangesDeleteText/Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/Ranges/RangesGetText/Document.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/Ranges/RangesGetText/Document.doc deleted file mode 100644 index 4494cb0b..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/Ranges/RangesGetText/Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/Theme/GetThemeProperties/Document.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/Theme/GetThemeProperties/Document.doc deleted file mode 100644 index cc74d18a..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/Theme/GetThemeProperties/Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/Theme/SetThemeProperties/Document.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/Theme/SetThemeProperties/Document.doc deleted file mode 100644 index cc74d18a..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/Theme/SetThemeProperties/Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/bookmarks/AccessBookmarks/Bookmark.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/bookmarks/AccessBookmarks/Bookmark.doc deleted file mode 100644 index 725872cd..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/bookmarks/AccessBookmarks/Bookmark.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/bookmarks/BookmarkNameAndText/Bookmark.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/bookmarks/BookmarkNameAndText/Bookmark.doc deleted file mode 100644 index 725872cd..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/bookmarks/BookmarkNameAndText/Bookmark.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/bookmarks/CopyBookmarkedText/Template.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/bookmarks/CopyBookmarkedText/Template.doc deleted file mode 100644 index 49f1591f..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/bookmarks/CopyBookmarkedText/Template.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/bookmarks/GetAndSetBookmarkNameAndText/Bookmark.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/bookmarks/GetAndSetBookmarkNameAndText/Bookmark.doc deleted file mode 100644 index 725872cd..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/bookmarks/GetAndSetBookmarkNameAndText/Bookmark.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/bookmarks/ObtainBookmarkByIndexAndName/Bookmarks.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/bookmarks/ObtainBookmarkByIndexAndName/Bookmarks.doc deleted file mode 100644 index 938c6dc6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/bookmarks/ObtainBookmarkByIndexAndName/Bookmarks.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/bookmarks/UntangleRowBookmarks/TestDefect1352.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/bookmarks/UntangleRowBookmarks/TestDefect1352.doc deleted file mode 100644 index 23681de5..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/bookmarks/UntangleRowBookmarks/TestDefect1352.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/comments/ExtractComments/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/comments/ExtractComments/TestFile.doc deleted file mode 100644 index 718f83ac..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/comments/ExtractComments/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/comments/ExtractCommentsByAuthor/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/comments/ExtractCommentsByAuthor/TestFile.doc deleted file mode 100644 index 718f83ac..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/comments/ExtractCommentsByAuthor/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/comments/ProcessComments/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/comments/ProcessComments/TestFile.doc deleted file mode 100644 index 718f83ac..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/comments/ProcessComments/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/comments/RemoveComments/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/comments/RemoveComments/TestFile.doc deleted file mode 100644 index 718f83ac..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/comments/RemoveComments/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/comments/RemoveCommentsByAuthor/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/comments/RemoveCommentsByAuthor/TestFile.doc deleted file mode 100644 index 718f83ac..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/comments/RemoveCommentsByAuthor/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderCursorPosition/DocumentBuilder.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderCursorPosition/DocumentBuilder.doc deleted file mode 100644 index e29b2134..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderCursorPosition/DocumentBuilder.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertFloatingImage/test.jpg b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertFloatingImage/test.jpg deleted file mode 100644 index fe4c2e57..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertFloatingImage/test.jpg and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertInlineImage/test.jpg b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertInlineImage/test.jpg deleted file mode 100644 index fe4c2e57..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderInsertInlineImage/test.jpg and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToBookmark/DocumentBuilder.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToBookmark/DocumentBuilder.doc deleted file mode 100644 index de930c3e..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToBookmark/DocumentBuilder.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToBookmarkEnd/DocumentBuilder.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToBookmarkEnd/DocumentBuilder.doc deleted file mode 100644 index de930c3e..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToBookmarkEnd/DocumentBuilder.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToMergeField/DocumentBuilder.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToMergeField/DocumentBuilder.doc deleted file mode 100644 index e29b2134..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToMergeField/DocumentBuilder.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToNode/DocumentBuilder.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToNode/DocumentBuilder.doc deleted file mode 100644 index e29b2134..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToNode/DocumentBuilder.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToParagraph/DocumentBuilder.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToParagraph/DocumentBuilder.doc deleted file mode 100644 index de930c3e..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToParagraph/DocumentBuilder.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToSection/DocumentBuilder.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToSection/DocumentBuilder.doc deleted file mode 100644 index e29b2134..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToSection/DocumentBuilder.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToTableCell/DocumentBuilder.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToTableCell/DocumentBuilder.doc deleted file mode 100644 index de930c3e..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentBuilderMoveToTableCell/DocumentBuilder.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentInDB/DocDB.mdb b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentInDB/DocDB.mdb deleted file mode 100644 index b8df0026..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentInDB/DocDB.mdb and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentInDB/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentInDB/TestFile.doc deleted file mode 100644 index df3955e8..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/DocumentInDB/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenBlockLevelNodes/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenBlockLevelNodes/TestFile.doc deleted file mode 100644 index 9b2f7481..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenBlockLevelNodes/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenBookmarks/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenBookmarks/TestFile.doc deleted file mode 100644 index 9b2f7481..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenBookmarks/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenCommentRange/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenCommentRange/TestFile.doc deleted file mode 100644 index 9b2f7481..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenCommentRange/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenParagraphStyles/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenParagraphStyles/TestFile.doc deleted file mode 100644 index 9b2f7481..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenParagraphStyles/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenParagraphs/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenParagraphs/TestFile.doc deleted file mode 100644 index 9b2f7481..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenParagraphs/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenRuns/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenRuns/TestFile.doc deleted file mode 100644 index 9b2f7481..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ExtractContentBetweenRuns/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ExtractContentUsingField/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ExtractContentUsingField/TestFile.doc deleted file mode 100644 index 9b2f7481..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ExtractContentUsingField/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ModifyContentControls/CheckBoxTypeContentControl.docx b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ModifyContentControls/CheckBoxTypeContentControl.docx deleted file mode 100644 index 68427c2d..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ModifyContentControls/CheckBoxTypeContentControl.docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ModifyContentControls/Watermark.png b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ModifyContentControls/Watermark.png deleted file mode 100644 index 64558c4d..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ModifyContentControls/Watermark.png and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/RemovePageAndSectionBreaks/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/RemovePageAndSectionBreaks/TestFile.doc deleted file mode 100644 index 4373efc3..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/RemovePageAndSectionBreaks/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ReplaceWithEvaluator/Document.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ReplaceWithEvaluator/Document.doc deleted file mode 100644 index 563b9514..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ReplaceWithEvaluator/Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ReplaceWithRegex/Document.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ReplaceWithRegex/Document.doc deleted file mode 100644 index ad1cf49c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ReplaceWithRegex/Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ReplaceWithString/Document.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ReplaceWithString/Document.doc deleted file mode 100644 index 1a079806..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/ReplaceWithString/Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/SetCurrentStateOfCheckBox/CheckBoxTypeContentControl.docx b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/SetCurrentStateOfCheckBox/CheckBoxTypeContentControl.docx deleted file mode 100644 index 68427c2d..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/document/SetCurrentStateOfCheckBox/CheckBoxTypeContentControl.docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/ConvertFieldsInBody/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/ConvertFieldsInBody/TestFile.doc deleted file mode 100644 index a2728d06..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/ConvertFieldsInBody/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/ConvertFieldsInDocument/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/ConvertFieldsInDocument/TestFile.doc deleted file mode 100644 index a2728d06..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/ConvertFieldsInDocument/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/ConvertFieldsInParagraph/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/ConvertFieldsInParagraph/TestFile.doc deleted file mode 100644 index a2728d06..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/ConvertFieldsInParagraph/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/FormFieldsGetByName/FormFields.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/FormFieldsGetByName/FormFields.doc deleted file mode 100644 index 46b120b5..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/FormFieldsGetByName/FormFields.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/FormFieldsGetFormFieldsCollection/FormFields.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/FormFieldsGetFormFieldsCollection/FormFields.doc deleted file mode 100644 index 46b120b5..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/FormFieldsGetFormFieldsCollection/FormFields.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/FormFieldsWorkWithProperties/FormFields.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/FormFieldsWorkWithProperties/FormFields.doc deleted file mode 100644 index 46b120b5..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/FormFieldsWorkWithProperties/FormFields.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/GetFieldNames/Rendering.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/GetFieldNames/Rendering.doc deleted file mode 100644 index 6e97a1eb..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/GetFieldNames/Rendering.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/InsertAuthorField/in.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/InsertAuthorField/in.doc deleted file mode 100644 index 8fb3b40f..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/InsertAuthorField/in.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/InsertMailMergeAddressBlockFieldUsingDOM/in.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/InsertMailMergeAddressBlockFieldUsingDOM/in.doc deleted file mode 100644 index 8fb3b40f..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/InsertMailMergeAddressBlockFieldUsingDOM/in.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/InsertMergeFieldUsingDOM/in.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/InsertMergeFieldUsingDOM/in.doc deleted file mode 100644 index 8fb3b40f..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/InsertMergeFieldUsingDOM/in.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/RemoveField/Field.RemoveField.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/RemoveField/Field.RemoveField.doc deleted file mode 100644 index 56695289..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/RemoveField/Field.RemoveField.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/UpdateDocFields/Rendering.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/UpdateDocFields/Rendering.doc deleted file mode 100644 index 6e97a1eb..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/fields/UpdateDocFields/Rendering.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/find_replace/FindAndHighlight/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/find_replace/FindAndHighlight/TestFile.doc deleted file mode 100644 index 88abe746..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/find_replace/FindAndHighlight/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/find_replace/ReplaceTextWithField/Field.ReplaceTextWithFields.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/find_replace/ReplaceTextWithField/Field.ReplaceTextWithFields.doc deleted file mode 100644 index 5a8bcc4a..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/find_replace/ReplaceTextWithField/Field.ReplaceTextWithFields.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/find_replace/ReplaceWithEvaluator/Document.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/find_replace/ReplaceWithEvaluator/Document.doc deleted file mode 100644 index ad1cf49c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/find_replace/ReplaceWithEvaluator/Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/find_replace/ReplaceWithRegex/Document.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/find_replace/ReplaceWithRegex/Document.doc deleted file mode 100644 index ad1cf49c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/find_replace/ReplaceWithRegex/Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/find_replace/ReplaceWithString/test.docx b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/find_replace/ReplaceWithString/test.docx deleted file mode 100644 index ce5f4467..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/find_replace/ReplaceWithString/test.docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/images/AddWatermark/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/images/AddWatermark/TestFile.doc deleted file mode 100644 index c6719b1b..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/images/AddWatermark/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/images/CompressImages/Test.docx b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/images/CompressImages/Test.docx deleted file mode 100644 index 5d363c55..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/images/CompressImages/Test.docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/images/ExtractImagesToFiles/Image.SampleImages.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/images/ExtractImagesToFiles/Image.SampleImages.doc deleted file mode 100644 index 0617e2f0..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/images/ExtractImagesToFiles/Image.SampleImages.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/images/InsertBarcodeImage/Image.SampleImages.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/images/InsertBarcodeImage/Image.SampleImages.doc deleted file mode 100644 index 0617e2f0..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/images/InsertBarcodeImage/Image.SampleImages.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/AppendDocumentManually/TestFile.Destination.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/AppendDocumentManually/TestFile.Destination.doc deleted file mode 100644 index bd45b74c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/AppendDocumentManually/TestFile.Destination.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/AppendDocumentManually/TestFile.Source.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/AppendDocumentManually/TestFile.Source.doc deleted file mode 100644 index b6ca3a51..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/AppendDocumentManually/TestFile.Source.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/BaseDocument/TestFile.Destination.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/BaseDocument/TestFile.Destination.doc deleted file mode 100644 index bd45b74c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/BaseDocument/TestFile.Destination.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/BaseDocument/TestFile.DestinationList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/BaseDocument/TestFile.DestinationList.doc deleted file mode 100644 index 3c61a726..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/BaseDocument/TestFile.DestinationList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/BaseDocument/TestFile.Source.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/BaseDocument/TestFile.Source.doc deleted file mode 100644 index b6ca3a51..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/BaseDocument/TestFile.Source.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/BaseDocument/TestFile.SourceList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/BaseDocument/TestFile.SourceList.doc deleted file mode 100644 index e01971c6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/BaseDocument/TestFile.SourceList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/BaseDocument/TestFile.SourcePageSetup.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/BaseDocument/TestFile.SourcePageSetup.doc deleted file mode 100644 index 73422841..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/BaseDocument/TestFile.SourcePageSetup.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFields/TestFile.Destination.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFields/TestFile.Destination.doc deleted file mode 100644 index bd45b74c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFields/TestFile.Destination.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFields/TestFile.DestinationList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFields/TestFile.DestinationList.doc deleted file mode 100644 index 3c61a726..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFields/TestFile.DestinationList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFields/TestFile.Source.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFields/TestFile.Source.doc deleted file mode 100644 index b6ca3a51..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFields/TestFile.Source.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFields/TestFile.SourceList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFields/TestFile.SourceList.doc deleted file mode 100644 index e01971c6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFields/TestFile.SourceList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFields/TestFile.SourcePageSetup.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFields/TestFile.SourcePageSetup.doc deleted file mode 100644 index 73422841..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ConvertNumPageFields/TestFile.SourcePageSetup.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/DifferentPageSetup/TestFile.Destination.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/DifferentPageSetup/TestFile.Destination.doc deleted file mode 100644 index bd45b74c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/DifferentPageSetup/TestFile.Destination.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/DifferentPageSetup/TestFile.DestinationList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/DifferentPageSetup/TestFile.DestinationList.doc deleted file mode 100644 index 3c61a726..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/DifferentPageSetup/TestFile.DestinationList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/DifferentPageSetup/TestFile.Source.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/DifferentPageSetup/TestFile.Source.doc deleted file mode 100644 index b6ca3a51..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/DifferentPageSetup/TestFile.Source.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/DifferentPageSetup/TestFile.SourceList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/DifferentPageSetup/TestFile.SourceList.doc deleted file mode 100644 index e01971c6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/DifferentPageSetup/TestFile.SourceList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/DifferentPageSetup/TestFile.SourcePageSetup.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/DifferentPageSetup/TestFile.SourcePageSetup.doc deleted file mode 100644 index 73422841..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/DifferentPageSetup/TestFile.SourcePageSetup.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/JoinContinuous/TestFile.Destination.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/JoinContinuous/TestFile.Destination.doc deleted file mode 100644 index bd45b74c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/JoinContinuous/TestFile.Destination.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/JoinContinuous/TestFile.DestinationList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/JoinContinuous/TestFile.DestinationList.doc deleted file mode 100644 index 3c61a726..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/JoinContinuous/TestFile.DestinationList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/JoinContinuous/TestFile.Source.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/JoinContinuous/TestFile.Source.doc deleted file mode 100644 index b6ca3a51..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/JoinContinuous/TestFile.Source.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/JoinContinuous/TestFile.SourceList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/JoinContinuous/TestFile.SourceList.doc deleted file mode 100644 index e01971c6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/JoinContinuous/TestFile.SourceList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/JoinContinuous/TestFile.SourcePageSetup.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/JoinContinuous/TestFile.SourcePageSetup.doc deleted file mode 100644 index 73422841..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/JoinContinuous/TestFile.SourcePageSetup.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/JoinNewPage/TestFile.Destination.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/JoinNewPage/TestFile.Destination.doc deleted file mode 100644 index bd45b74c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/JoinNewPage/TestFile.Destination.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/JoinNewPage/TestFile.Source.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/JoinNewPage/TestFile.Source.doc deleted file mode 100644 index b6ca3a51..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/JoinNewPage/TestFile.Source.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceFormatting/TestFile.Destination.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceFormatting/TestFile.Destination.doc deleted file mode 100644 index bd45b74c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceFormatting/TestFile.Destination.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceFormatting/TestFile.DestinationList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceFormatting/TestFile.DestinationList.doc deleted file mode 100644 index 3c61a726..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceFormatting/TestFile.DestinationList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceFormatting/TestFile.Source.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceFormatting/TestFile.Source.doc deleted file mode 100644 index b6ca3a51..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceFormatting/TestFile.Source.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceFormatting/TestFile.SourceList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceFormatting/TestFile.SourceList.doc deleted file mode 100644 index e01971c6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceFormatting/TestFile.SourceList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceFormatting/TestFile.SourcePageSetup.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceFormatting/TestFile.SourcePageSetup.doc deleted file mode 100644 index 73422841..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceFormatting/TestFile.SourcePageSetup.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceTogether/TestFile.Destination.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceTogether/TestFile.Destination.doc deleted file mode 100644 index bd45b74c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceTogether/TestFile.Destination.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceTogether/TestFile.DestinationList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceTogether/TestFile.DestinationList.doc deleted file mode 100644 index 3c61a726..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceTogether/TestFile.DestinationList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceTogether/TestFile.Source.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceTogether/TestFile.Source.doc deleted file mode 100644 index b6ca3a51..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceTogether/TestFile.Source.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceTogether/TestFile.SourceList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceTogether/TestFile.SourceList.doc deleted file mode 100644 index e01971c6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceTogether/TestFile.SourceList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceTogether/TestFile.SourcePageSetup.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceTogether/TestFile.SourcePageSetup.doc deleted file mode 100644 index 73422841..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/KeepSourceTogether/TestFile.SourcePageSetup.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/LinkHeadersFooters/TestFile.Destination.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/LinkHeadersFooters/TestFile.Destination.doc deleted file mode 100644 index bd45b74c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/LinkHeadersFooters/TestFile.Destination.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/LinkHeadersFooters/TestFile.DestinationList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/LinkHeadersFooters/TestFile.DestinationList.doc deleted file mode 100644 index 3c61a726..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/LinkHeadersFooters/TestFile.DestinationList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/LinkHeadersFooters/TestFile.Source.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/LinkHeadersFooters/TestFile.Source.doc deleted file mode 100644 index b6ca3a51..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/LinkHeadersFooters/TestFile.Source.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/LinkHeadersFooters/TestFile.SourceList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/LinkHeadersFooters/TestFile.SourceList.doc deleted file mode 100644 index e01971c6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/LinkHeadersFooters/TestFile.SourceList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/LinkHeadersFooters/TestFile.SourcePageSetup.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/LinkHeadersFooters/TestFile.SourcePageSetup.doc deleted file mode 100644 index 73422841..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/LinkHeadersFooters/TestFile.SourcePageSetup.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListKeepSourceFormatting/TestFile.Destination.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListKeepSourceFormatting/TestFile.Destination.doc deleted file mode 100644 index bd45b74c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListKeepSourceFormatting/TestFile.Destination.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListKeepSourceFormatting/TestFile.DestinationList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListKeepSourceFormatting/TestFile.DestinationList.doc deleted file mode 100644 index 3c61a726..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListKeepSourceFormatting/TestFile.DestinationList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListKeepSourceFormatting/TestFile.Source.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListKeepSourceFormatting/TestFile.Source.doc deleted file mode 100644 index b6ca3a51..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListKeepSourceFormatting/TestFile.Source.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListKeepSourceFormatting/TestFile.SourceList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListKeepSourceFormatting/TestFile.SourceList.doc deleted file mode 100644 index e01971c6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListKeepSourceFormatting/TestFile.SourceList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListKeepSourceFormatting/TestFile.SourcePageSetup.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListKeepSourceFormatting/TestFile.SourcePageSetup.doc deleted file mode 100644 index 73422841..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListKeepSourceFormatting/TestFile.SourcePageSetup.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListUseDestinationStyles/TestFile.Destination.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListUseDestinationStyles/TestFile.Destination.doc deleted file mode 100644 index bd45b74c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListUseDestinationStyles/TestFile.Destination.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListUseDestinationStyles/TestFile.DestinationList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListUseDestinationStyles/TestFile.DestinationList.doc deleted file mode 100644 index 3c61a726..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListUseDestinationStyles/TestFile.DestinationList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListUseDestinationStyles/TestFile.Source.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListUseDestinationStyles/TestFile.Source.doc deleted file mode 100644 index b6ca3a51..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListUseDestinationStyles/TestFile.Source.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListUseDestinationStyles/TestFile.SourceList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListUseDestinationStyles/TestFile.SourceList.doc deleted file mode 100644 index e01971c6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListUseDestinationStyles/TestFile.SourceList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListUseDestinationStyles/TestFile.SourcePageSetup.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListUseDestinationStyles/TestFile.SourcePageSetup.doc deleted file mode 100644 index 73422841..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/ListUseDestinationStyles/TestFile.SourcePageSetup.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RemoveSourceHeadersFooters/TestFile.Destination.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RemoveSourceHeadersFooters/TestFile.Destination.doc deleted file mode 100644 index bd45b74c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RemoveSourceHeadersFooters/TestFile.Destination.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RemoveSourceHeadersFooters/TestFile.DestinationList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RemoveSourceHeadersFooters/TestFile.DestinationList.doc deleted file mode 100644 index 3c61a726..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RemoveSourceHeadersFooters/TestFile.DestinationList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RemoveSourceHeadersFooters/TestFile.Source.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RemoveSourceHeadersFooters/TestFile.Source.doc deleted file mode 100644 index b6ca3a51..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RemoveSourceHeadersFooters/TestFile.Source.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RemoveSourceHeadersFooters/TestFile.SourceList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RemoveSourceHeadersFooters/TestFile.SourceList.doc deleted file mode 100644 index e01971c6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RemoveSourceHeadersFooters/TestFile.SourceList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RemoveSourceHeadersFooters/TestFile.SourcePageSetup.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RemoveSourceHeadersFooters/TestFile.SourcePageSetup.doc deleted file mode 100644 index 73422841..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RemoveSourceHeadersFooters/TestFile.SourcePageSetup.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RestartPageNumbering/TestFile.Destination.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RestartPageNumbering/TestFile.Destination.doc deleted file mode 100644 index bd45b74c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RestartPageNumbering/TestFile.Destination.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RestartPageNumbering/TestFile.DestinationList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RestartPageNumbering/TestFile.DestinationList.doc deleted file mode 100644 index 3c61a726..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RestartPageNumbering/TestFile.DestinationList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RestartPageNumbering/TestFile.Source.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RestartPageNumbering/TestFile.Source.doc deleted file mode 100644 index b6ca3a51..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RestartPageNumbering/TestFile.Source.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RestartPageNumbering/TestFile.SourceList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RestartPageNumbering/TestFile.SourceList.doc deleted file mode 100644 index e01971c6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RestartPageNumbering/TestFile.SourceList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RestartPageNumbering/TestFile.SourcePageSetup.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RestartPageNumbering/TestFile.SourcePageSetup.doc deleted file mode 100644 index 73422841..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/RestartPageNumbering/TestFile.SourcePageSetup.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/SimpleAppendDocument/TestFile.Destination.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/SimpleAppendDocument/TestFile.Destination.doc deleted file mode 100644 index bd45b74c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/SimpleAppendDocument/TestFile.Destination.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/SimpleAppendDocument/TestFile.DestinationList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/SimpleAppendDocument/TestFile.DestinationList.doc deleted file mode 100644 index 3c61a726..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/SimpleAppendDocument/TestFile.DestinationList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/SimpleAppendDocument/TestFile.Source.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/SimpleAppendDocument/TestFile.Source.doc deleted file mode 100644 index b6ca3a51..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/SimpleAppendDocument/TestFile.Source.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/SimpleAppendDocument/TestFile.SourceList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/SimpleAppendDocument/TestFile.SourceList.doc deleted file mode 100644 index e01971c6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/SimpleAppendDocument/TestFile.SourceList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/SimpleAppendDocument/TestFile.SourcePageSetup.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/SimpleAppendDocument/TestFile.SourcePageSetup.doc deleted file mode 100644 index 73422841..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/SimpleAppendDocument/TestFile.SourcePageSetup.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UnlinkHeadersFooters/TestFile.Destination.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UnlinkHeadersFooters/TestFile.Destination.doc deleted file mode 100644 index bd45b74c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UnlinkHeadersFooters/TestFile.Destination.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UnlinkHeadersFooters/TestFile.DestinationList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UnlinkHeadersFooters/TestFile.DestinationList.doc deleted file mode 100644 index 3c61a726..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UnlinkHeadersFooters/TestFile.DestinationList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UnlinkHeadersFooters/TestFile.Source.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UnlinkHeadersFooters/TestFile.Source.doc deleted file mode 100644 index b6ca3a51..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UnlinkHeadersFooters/TestFile.Source.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UnlinkHeadersFooters/TestFile.SourceList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UnlinkHeadersFooters/TestFile.SourceList.doc deleted file mode 100644 index e01971c6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UnlinkHeadersFooters/TestFile.SourceList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UnlinkHeadersFooters/TestFile.SourcePageSetup.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UnlinkHeadersFooters/TestFile.SourcePageSetup.doc deleted file mode 100644 index 73422841..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UnlinkHeadersFooters/TestFile.SourcePageSetup.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UpdatePageLayout/TestFile.Destination.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UpdatePageLayout/TestFile.Destination.doc deleted file mode 100644 index bd45b74c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UpdatePageLayout/TestFile.Destination.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UpdatePageLayout/TestFile.DestinationList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UpdatePageLayout/TestFile.DestinationList.doc deleted file mode 100644 index 3c61a726..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UpdatePageLayout/TestFile.DestinationList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UpdatePageLayout/TestFile.Source.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UpdatePageLayout/TestFile.Source.doc deleted file mode 100644 index b6ca3a51..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UpdatePageLayout/TestFile.Source.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UpdatePageLayout/TestFile.SourceList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UpdatePageLayout/TestFile.SourceList.doc deleted file mode 100644 index e01971c6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UpdatePageLayout/TestFile.SourceList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UpdatePageLayout/TestFile.SourcePageSetup.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UpdatePageLayout/TestFile.SourcePageSetup.doc deleted file mode 100644 index 73422841..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UpdatePageLayout/TestFile.SourcePageSetup.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UseDestinationStyles/TestFile.Destination.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UseDestinationStyles/TestFile.Destination.doc deleted file mode 100644 index bd45b74c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UseDestinationStyles/TestFile.Destination.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UseDestinationStyles/TestFile.DestinationList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UseDestinationStyles/TestFile.DestinationList.doc deleted file mode 100644 index 3c61a726..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UseDestinationStyles/TestFile.DestinationList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UseDestinationStyles/TestFile.Source.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UseDestinationStyles/TestFile.Source.doc deleted file mode 100644 index b6ca3a51..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UseDestinationStyles/TestFile.Source.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UseDestinationStyles/TestFile.SourceList.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UseDestinationStyles/TestFile.SourceList.doc deleted file mode 100644 index e01971c6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UseDestinationStyles/TestFile.SourceList.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UseDestinationStyles/TestFile.SourcePageSetup.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UseDestinationStyles/TestFile.SourcePageSetup.doc deleted file mode 100644 index 73422841..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/joining_appending/UseDestinationStyles/TestFile.SourcePageSetup.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/sections/DeleteAllSections/Document.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/sections/DeleteAllSections/Document.doc deleted file mode 100644 index b7feb48a..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/sections/DeleteAllSections/Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/sections/SectionsAccessByIndex/Document.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/sections/SectionsAccessByIndex/Document.doc deleted file mode 100644 index cc74d18a..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/sections/SectionsAccessByIndex/Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/sections/SectionsAccessByIndex/Section.AddRemove.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/sections/SectionsAccessByIndex/Section.AddRemove.doc deleted file mode 100644 index 6fb9e0cf..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/sections/SectionsAccessByIndex/Section.AddRemove.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/sections/SectionsAccessByIndex/Section.AppendContent.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/sections/SectionsAccessByIndex/Section.AppendContent.doc deleted file mode 100644 index 40487391..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/sections/SectionsAccessByIndex/Section.AppendContent.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/styles/ExtractContentBasedOnStyles/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/styles/ExtractContentBasedOnStyles/TestFile.doc deleted file mode 100644 index 19dd9cb9..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/styles/ExtractContentBasedOnStyles/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/AddRemoveColumn/InsertBlankColumn/Table.SimpleTable.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/AddRemoveColumn/InsertBlankColumn/Table.SimpleTable.doc deleted file mode 100644 index ae4517db..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/AddRemoveColumn/InsertBlankColumn/Table.SimpleTable.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/BuildTableWithBordersEnabled/Table.EmptyTable.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/BuildTableWithBordersEnabled/Table.EmptyTable.doc deleted file mode 100644 index b5c3672a..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/BuildTableWithBordersEnabled/Table.EmptyTable.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/ModifyCellFormatting/Table.Document.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/ModifyCellFormatting/Table.Document.doc deleted file mode 100644 index 746320ca..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/ModifyCellFormatting/Table.Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/ModifyRowFormatting/Table.Document.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/ModifyRowFormatting/Table.Document.doc deleted file mode 100644 index 746320ca..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ApplyFormatting/ModifyRowFormatting/Table.Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ApplyStyle/ExpandFormattingOnCellsAndRowFromStyle/Table.TableStyle.docx b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ApplyStyle/ExpandFormattingOnCellsAndRowFromStyle/Table.TableStyle.docx deleted file mode 100644 index cee0d5a4..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ApplyStyle/ExpandFormattingOnCellsAndRowFromStyle/Table.TableStyle.docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/AutoFitTableToContents/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/AutoFitTableToContents/TestFile.doc deleted file mode 100644 index 271621c6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/AutoFitTableToContents/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/AutoFitTableToFixedWidthColumns/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/AutoFitTableToFixedWidthColumns/TestFile.doc deleted file mode 100644 index 271621c6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/AutoFitTableToFixedWidthColumns/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/AutoFitTableToPageWidth/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/AutoFitTableToPageWidth/TestFile.doc deleted file mode 100644 index 271621c6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/AutoFitTableToPageWidth/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/AutoFitTableToWindow/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/AutoFitTableToWindow/TestFile.doc deleted file mode 100644 index 271621c6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/AutoFitTableToWindow/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/CloneTable/CloneCompleteTable/Table.SimpleTable.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/CloneTable/CloneCompleteTable/Table.SimpleTable.doc deleted file mode 100644 index ae4517db..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/CloneTable/CloneCompleteTable/Table.SimpleTable.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/CloneTable/CloneLastRow/Table.SimpleTable.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/CloneTable/CloneLastRow/Table.SimpleTable.doc deleted file mode 100644 index ae4517db..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/CloneTable/CloneLastRow/Table.SimpleTable.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ExtractOrReplaceText/ExtractText/Table.Document.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ExtractOrReplaceText/ExtractText/Table.Document.doc deleted file mode 100644 index 746320ca..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ExtractOrReplaceText/ExtractText/Table.Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ExtractOrReplaceText/ExtractText/test.docx b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ExtractOrReplaceText/ExtractText/test.docx deleted file mode 100644 index 5bdb750e..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ExtractOrReplaceText/ExtractText/test.docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ExtractOrReplaceText/PrintTextRangeOFRowAndTable/Table.Document.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ExtractOrReplaceText/PrintTextRangeOFRowAndTable/Table.Document.doc deleted file mode 100644 index 746320ca..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ExtractOrReplaceText/PrintTextRangeOFRowAndTable/Table.Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ExtractOrReplaceText/ReplaceText/Table.SimpleTable.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ExtractOrReplaceText/ReplaceText/Table.SimpleTable.doc deleted file mode 100644 index ae4517db..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/ExtractOrReplaceText/ReplaceText/Table.SimpleTable.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/FindingIndex/RetrieveCellIndex/Table.Document.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/FindingIndex/RetrieveCellIndex/Table.Document.doc deleted file mode 100644 index 746320ca..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/FindingIndex/RetrieveCellIndex/Table.Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/FindingIndex/RetrieveRowIndex/Table.Document.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/FindingIndex/RetrieveRowIndex/Table.Document.doc deleted file mode 100644 index 746320ca..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/FindingIndex/RetrieveRowIndex/Table.Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/FindingIndex/RetrieveTableIndex/test.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/FindingIndex/RetrieveTableIndex/test.doc deleted file mode 100644 index eb20e1b4..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/FindingIndex/RetrieveTableIndex/test.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/JoiningAndSplittingTable/CombineRows/Table.Document.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/JoiningAndSplittingTable/CombineRows/Table.Document.doc deleted file mode 100644 index 746320ca..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/JoiningAndSplittingTable/CombineRows/Table.Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/JoiningAndSplittingTable/SplitTable/Table.Document.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/JoiningAndSplittingTable/SplitTable/Table.Document.doc deleted file mode 100644 index 746320ca..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/JoiningAndSplittingTable/SplitTable/Table.Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/JoiningAndSplittingTable/SplitTable/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/JoiningAndSplittingTable/SplitTable/TestFile.doc deleted file mode 100644 index 271621c6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/JoiningAndSplittingTable/SplitTable/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/KeepTablesAndRowsBreaking/RowFormatDisableBreakAcrossPages/Table.TableAcrossPage.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/KeepTablesAndRowsBreaking/RowFormatDisableBreakAcrossPages/Table.TableAcrossPage.doc deleted file mode 100644 index 7e0faf24..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/KeepTablesAndRowsBreaking/RowFormatDisableBreakAcrossPages/Table.TableAcrossPage.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/KeepTablesAndRowsBreaking/RowFormatDisableBreakAcrossPages/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/KeepTablesAndRowsBreaking/RowFormatDisableBreakAcrossPages/TestFile.doc deleted file mode 100644 index 271621c6..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/KeepTablesAndRowsBreaking/RowFormatDisableBreakAcrossPages/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/MergedCells/CheckCellsMerged/Table.TableAcrossPage.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/MergedCells/CheckCellsMerged/Table.TableAcrossPage.doc deleted file mode 100644 index ae1ed8b0..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/MergedCells/CheckCellsMerged/Table.TableAcrossPage.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/SpecifyHeightAndWidth/RetrievePreferredWidthType/Table.SimpleTable.doc b/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/SpecifyHeightAndWidth/RetrievePreferredWidthType/Table.SimpleTable.doc deleted file mode 100644 index ae4517db..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/programming_documents/tables/SpecifyHeightAndWidth/RetrievePreferredWidthType/Table.SimpleTable.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/quickstart/AppendDocuments/TestFile.Destination.doc b/Examples/src/main/resources/com/aspose/words/examples/quickstart/AppendDocuments/TestFile.Destination.doc deleted file mode 100644 index bd45b74c..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/quickstart/AppendDocuments/TestFile.Destination.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/quickstart/AppendDocuments/TestFile.Source.doc b/Examples/src/main/resources/com/aspose/words/examples/quickstart/AppendDocuments/TestFile.Source.doc deleted file mode 100644 index b6ca3a51..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/quickstart/AppendDocuments/TestFile.Source.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/quickstart/FindAndReplace/ReplaceSimple.doc b/Examples/src/main/resources/com/aspose/words/examples/quickstart/FindAndReplace/ReplaceSimple.doc deleted file mode 100644 index fa15a66d..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/quickstart/FindAndReplace/ReplaceSimple.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/quickstart/LoadAndSaveToDisk/Document.doc b/Examples/src/main/resources/com/aspose/words/examples/quickstart/LoadAndSaveToDisk/Document.doc deleted file mode 100644 index cc74d18a..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/quickstart/LoadAndSaveToDisk/Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/quickstart/LoadAndSaveToStream/Document.doc b/Examples/src/main/resources/com/aspose/words/examples/quickstart/LoadAndSaveToStream/Document.doc deleted file mode 100644 index cc74d18a..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/quickstart/LoadAndSaveToStream/Document.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/quickstart/SimpleMailMerge/Template.doc b/Examples/src/main/resources/com/aspose/words/examples/quickstart/SimpleMailMerge/Template.doc deleted file mode 100644 index ca71bb8e..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/quickstart/SimpleMailMerge/Template.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/rendering_printing/DocumentPreviewAndPrint/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/rendering_printing/DocumentPreviewAndPrint/TestFile.doc deleted file mode 100644 index 33768c95..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/rendering_printing/DocumentPreviewAndPrint/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/rendering_printing/RenderShapes/TestFile.RenderToGraphics.png b/Examples/src/main/resources/com/aspose/words/examples/rendering_printing/RenderShapes/TestFile.RenderToGraphics.png deleted file mode 100644 index 686e0c46..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/rendering_printing/RenderShapes/TestFile.RenderToGraphics.png and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/rendering_printing/RenderShapes/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/rendering_printing/RenderShapes/TestFile.doc deleted file mode 100644 index d6d7756d..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/rendering_printing/RenderShapes/TestFile.doc and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/rendering_printing/RenderShapes/TestFile.docx b/Examples/src/main/resources/com/aspose/words/examples/rendering_printing/RenderShapes/TestFile.docx deleted file mode 100644 index 8b32147a..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/rendering_printing/RenderShapes/TestFile.docx and /dev/null differ diff --git a/Examples/src/main/resources/com/aspose/words/examples/rendering_printing/SaveAsMultipageTiff/TestFile.doc b/Examples/src/main/resources/com/aspose/words/examples/rendering_printing/SaveAsMultipageTiff/TestFile.doc deleted file mode 100644 index 33768c95..00000000 Binary files a/Examples/src/main/resources/com/aspose/words/examples/rendering_printing/SaveAsMultipageTiff/TestFile.doc and /dev/null differ diff --git a/LICENSE b/LICENSE index f83cc4c8..3ebf2a16 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ -The MIT License (MIT) +MIT License -Copyright (c) 2001-2016 Aspose Pty Ltd +Copyright (c) 2001-2025 Aspose Pty Ltd Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Plugins/Aspose-Words-Java-for-NetBeans(Maven)/README.md b/Plugins/Aspose-Words-Java-for-NetBeans(Maven)/README.md index 2ff20c77..359d24ca 100644 --- a/Plugins/Aspose-Words-Java-for-NetBeans(Maven)/README.md +++ b/Plugins/Aspose-Words-Java-for-NetBeans(Maven)/README.md @@ -2,29 +2,29 @@ # **Aspose.Word Java for NetBeans (Maven)** -The project is **NetBeans IDE plugin** which lets developers to use [Aspose.Words for Java](http://goo.gl/Eg359W) in their Maven based Java projects. +The project is **NetBeans IDE plugin** which lets developers to use [Aspose.Words for Java](https://products.aspose.com/words/java) in their Maven based Java projects. ## Who is supposed to use this **Plugin?** -The Plugin intended for developers using Maven platform for Java developments and want to use [Aspose.Words for Java](http://goo.gl/Eg359W) in their projects. +The Plugin intended for developers using Maven platform for Java developments and want to use [Aspose.Words for Java](https://products.aspose.com/words/java) in their projects. -**NOTE:** [Aspose.Words for Java](http://goo.gl/Eg359W) is Java API developed by [Aspose](http://aspose.com) that offers easy Microsoft Word document creation and manipulation right from within Java Projects. For the API detailed features list check the [link](http://goo.gl/Eg359W). +**NOTE:** [Aspose.Words for Java](https://products.aspose.com/words/java) is Java API developed by [Aspose](https://www.aspose.com/) that offers easy Microsoft Word document creation and manipulation right from within Java Projects. For the API detailed features list check the [link](https://docs.aspose.com/display/wordsjava/Aspose.Words+Features). ## **Features** -The plugin provides following features to work with [Aspose.Words for Java](http://goo.gl/Eg359W) API within **NetBeans IDE** comfortably: +The plugin provides following features to work with [Aspose.Words for Java](https://products.aspose.com/words/java) API within **NetBeans IDE** comfortably: ![plugin title shot](http://i.imgur.com/ahtYw1V.png) ### Aspose.Words Maven Project (wizard) -* By using this wizard plugin creates Maven project for using [Aspose.Words for Java](http://goo.gl/Eg359W) from **New Project -> Maven-> Aspose.Words Maven Project** +* By using this wizard plugin creates Maven project for using [Aspose.Words for Java](https://products.aspose.com/words/java) from **New Project -> Maven-> Aspose.Words Maven Project** * The wizard will also give option for downloading latest available Code Examples for using the API. ### Aspose.Words Code Example (wizard) -* By using this wizard plugin lets you copy the downloaded Code Examples into your project for using [Aspose.Words for Java](http://goo.gl/Eg359W) from **New File -> Java -> Aspose.Words Code Example** -* The wizard will also look for and updates for newly available Code Examples from [Aspose.Words for Java examples repository.](https://goo.gl/Qx9Hp9) +* By using this wizard plugin lets you copy the downloaded Code Examples into your project for using [Aspose.Words for Java](https://products.aspose.com/words/java) from **New File -> Java -> Aspose.Words Code Example** +* The wizard will also look for and updates for newly available Code Examples from [Aspose.Words for Java examples repository.](https://github.com/aspose-words/Aspose.Words-for-Java/tree/master/Examples) **NOTE:** Selected Code Examples (category) source codes will be copied under **"com.aspose.words.examples"** package. Resources needed for running examples will be copied to the corresponding directory (package) within **"src/main/resources"**. ### Other Features @@ -40,8 +40,8 @@ The plugin provides following features to work with [Aspose.Words for Java](http Aspose.Words for Java supports processing word (**DOC, DOCX, OOXML, RTF**) **HTML, OpenDocument, PDF, EPUB, XPS, SWF and all image formats**. With Aspose.Words you can **generate**, **modify**, and **convert** documents without using Microsoft Word. -For more info about the **Aspose.Words for Java API**, [please check the api documentation - click here](http://www.aspose.com/java/word-component.aspx) +For more info about the **Aspose.Words for Java API**, [please check the api documentation - click here](https://docs.aspose.com/display/wordsjava/Home) ## Plugin Documentation -For the most complete documentation, [Please check this WIKI](http://www.aspose.com/docs/display/wordsjava/Aspose.Words+Java+for+NetBeans+(Maven)) +For the most complete documentation, [Please check this WIKI](https://docs.aspose.com/display/wordsjava/Aspose.Words+Java+for+NetBeans+(Maven)) diff --git a/Plugins/Aspose.Words Java for dotCMS/AsposeDotCMSExportToWord.servlet/README.md b/Plugins/Aspose.Words Java for dotCMS/AsposeDotCMSExportToWord.servlet/README.md index 8effefac..8577cc6c 100644 --- a/Plugins/Aspose.Words Java for dotCMS/AsposeDotCMSExportToWord.servlet/README.md +++ b/Plugins/Aspose.Words Java for dotCMS/AsposeDotCMSExportToWord.servlet/README.md @@ -1,6 +1,6 @@ # Export to Word Plugin for dotCMS -Export to Word Plugin for dotCMS allow users to export online content into Word Processing document using [Aspose.Words for Java](http://www.aspose.com/java/word-component.aspx). It dynamically exports the content of the Web page to a Word Processing document and then automatically downloads the file to the disk location selected by the user in just couple of seconds. The generated Word processing document can then be opened using any Word Processing Application such as Microsoft Word or Apache OpenOffice etc. +Export to Word Plugin for dotCMS allow users to export online content into Word Processing document using [Aspose.Words for Java](https://products.aspose.com/words/java). It dynamically exports the content of the Web page to a Word Processing document and then automatically downloads the file to the disk location selected by the user in just couple of seconds. The generated Word processing document can then be opened using any Word Processing Application such as Microsoft Word or Apache OpenOffice etc. ![Export to Word Image 1](http://i.imgur.com/aqlE55d.png|align=center,border=1!) @@ -45,7 +45,7 @@ To remove evaluation message and feature limitations, product license should be License license = new License(); license.setLicense("Aspose.Words.Java.lic"); ``` -Please check this [article](http://www.aspose.com/docs/display/wordsjava/Applying+a+License) for further details. +Please check this [article](https://docs.aspose.com/display/wordsjava/Applying+a+License) for further details. ## Supported Platforms diff --git a/Plugins/Aspose_Words_Java_for_Docx4j/README.md b/Plugins/Aspose_Words_Java_for_Docx4j/README.md index 2a80bb38..9f4d135a 100644 --- a/Plugins/Aspose_Words_Java_for_Docx4j/README.md +++ b/Plugins/Aspose_Words_Java_for_Docx4j/README.md @@ -4,15 +4,15 @@ Aspose.Words Java for Docx4j is a project to provide comparative source code exa Below are some code comparisons and features of Aspose.Words for Java that are not available in Docx4j. -* [Code Comparison for common features in **Aspose.Words** and **Docx4j**](http://www.aspose.com/docs/display/wordsjava/2.2+Code+Comparison+for+Common+Features+in+Aspose.Words+and+docx4j) -* [Missing Features of **Docx4j** available in **Aspose.Words**](http://www.aspose.com/docs/display/wordsjava/2.3+Missing+Features+of+docx4j+in+Aspose.Words) +* [Code Comparison for common features in **Aspose.Words** and **Docx4j**](https://docs.aspose.com/display/wordsjava/Code+Comparison+for+Common+Features+in+Aspose.Words+and+docx4j) +* [Missing Features of **Docx4j** available in **Aspose.Words**](https://docs.aspose.com/display/wordsjava/Missing+Features+of+docx4j+in+Aspose.Words) These examples are helpful for developers who want to compare Docx4j with Aspose.Words OR migrate from Docx4j to Aspose. ### Feedback and Suggestions -* Many more examples are yet to come. [Keep visiting us](http://www.aspose.com/java/total-component.aspx). -* Raise your queries and suggest more examples via [Aspose Forums](http://www.aspose.com/community/forums/default.aspx) or via this social coding site. +* Many more examples are yet to come. [Keep visiting us](https://products.aspose.com/total/java). +* Raise your queries and suggest more examples via [Aspose Forums](https://www.aspose.com/community/forums/default.aspx) or via this social coding site. ## Why Aspose for Docx4j ? @@ -45,13 +45,13 @@ All the Aspose APIs don’t have any dependency over any other engine. For examp ### Aspose.Words for Java -[![Aspose.Words for Java](http://www.aspose.com/App_Themes/V2/images/productLogos/Java/aspose_words-for-java.jpg)](http://www.aspose.com/java/word-component.aspx) +[![Aspose.Words for Java](http://www.aspose.com/App_Themes/V2/images/productLogos/Java/aspose_words-for-java.jpg)](https://products.aspose.com/words/java) Aspose.Words for Java is an advanced class library for Java that enables you to perform a great range of document processing tasks directly within your Java applications. Aspose.Words for Java supports DOC, OOXML, RTF, HTML and OpenDocument formats. With Aspose.Words you can generate, modify, and convert documents without using Microsoft Word. -[Learn More](http://www.aspose.com/java/word-component.aspx) +[Learn More](https://products.aspose.com/words/java) ## Download Latest Versions? diff --git a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipseFeature/feature.xml b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipseFeature/feature.xml index 0ac9dfe3..dc0596eb 100644 --- a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipseFeature/feature.xml +++ b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipseFeature/feature.xml @@ -2,7 +2,7 @@ @@ -18,7 +18,7 @@ The newly created project and the Code Examples you added is now ready to be enh The MIT License (MIT) -Copyright (c) 2001-2016 Aspose Pty Ltd +Copyright (c) 2001-2020 Aspose Pty Ltd Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: @@ -27,11 +27,15 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + + + diff --git a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/.settings/org.eclipse.jdt.core.prefs b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/.settings/org.eclipse.jdt.core.prefs index 11f6e462..ace45cee 100644 --- a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/.settings/org.eclipse.jdt.core.prefs +++ b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,12 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/resources/pom-xml-template.txt b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/resources/pom-xml-template.txt index e5aa7d6b..3a496db3 100644 --- a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/resources/pom-xml-template.txt +++ b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/resources/pom-xml-template.txt @@ -9,7 +9,7 @@ Aspose-Maven-Repository Aspose Maven Repository - http://maven.aspose.com/artifactory/simple/ext-release-local/ + https://repository.aspose.com/repo/ diff --git a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/src/com/aspose/words/maven/artifacts/maven-metada.xml b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/src/com/aspose/words/maven/artifacts/maven-metada.xml index 5d16b65e..c745bd33 100644 --- a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/src/com/aspose/words/maven/artifacts/maven-metada.xml +++ b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/src/com/aspose/words/maven/artifacts/maven-metada.xml @@ -2,16 +2,16 @@ com.aspose aspose-words - 14.5.0 + 16.1.0 - 14.8.0 - 14.8.0 + 16.4.0 + 16.4.0 - 14.5.0 - 14.6.0 - 14.7.0 - 14.8.0 + 16.1.0 + 16.2.0 + 16.3.0 + 16.4.0 - 20140924084136 + 20200924084136 \ No newline at end of file diff --git a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/src/com/aspose/words/maven/utils/AsposeConstants.java b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/src/com/aspose/words/maven/utils/AsposeConstants.java index b0f70e3f..fd05aaf6 100644 --- a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/src/com/aspose/words/maven/utils/AsposeConstants.java +++ b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/src/com/aspose/words/maven/utils/AsposeConstants.java @@ -92,7 +92,7 @@ public class AsposeConstants { /** * */ - public static final String ASPOSE_MAVEN_REPOSITORY = "http://maven.aspose.com"; + public static final String ASPOSE_MAVEN_REPOSITORY = "https://repository.aspose.com"; /** * diff --git a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/src/com/aspose/words/maven/utils/AsposeMavenProjectManager.java b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/src/com/aspose/words/maven/utils/AsposeMavenProjectManager.java index 9e94b372..debf1f06 100644 --- a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/src/com/aspose/words/maven/utils/AsposeMavenProjectManager.java +++ b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/src/com/aspose/words/maven/utils/AsposeMavenProjectManager.java @@ -45,10 +45,12 @@ import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; import org.xml.sax.SAXException; import com.aspose.words.maven.artifacts.Metadata; import com.aspose.words.maven.artifacts.ObjectFactory; + public class AsposeMavenProjectManager { private File projectDir = null; @@ -314,19 +316,31 @@ public String readURLContents(String Url) throws IOException { */ public Metadata getProductMavenDependency(String productMavenRepositoryUrl) { final String mavenMetaDataFileName = "maven-metadata.xml"; - Metadata data = null; + Metadata data = new Metadata(); try { String productMavenInfo; - productMavenInfo = readURLContents(productMavenRepositoryUrl + mavenMetaDataFileName); - JAXBContext jaxbContext = JAXBContext.newInstance(ObjectFactory.class); - Unmarshaller unmarshaller; - unmarshaller = jaxbContext.createUnmarshaller(); - - data = (Metadata) unmarshaller.unmarshal(new StreamSource(new StringReader(productMavenInfo))); - + productMavenInfo = readURLContents(productMavenRepositoryUrl + mavenMetaDataFileName); + + DocumentBuilder dBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + Document doc = dBuilder.parse(new InputSource(new StringReader(productMavenInfo))); + XPath xPath = XPathFactory.newInstance().newXPath(); + String groupId = XPathFactory.newInstance().newXPath().compile("//metadata/groupId").evaluate(doc); + String artifactId = XPathFactory.newInstance().newXPath().compile("//metadata/artifactId").evaluate(doc); + String version = XPathFactory.newInstance().newXPath().compile("//metadata/version").evaluate(doc); + String latest = XPathFactory.newInstance().newXPath().compile("//metadata/versioning/latest").evaluate(doc); + + data.setArtifactId(artifactId); + data.setGroupId(groupId); + data.setVersion(version); + + Metadata.Versioning ver = new Metadata.Versioning(); + ver.setLatest(latest); + data.setVersioning(ver); + String remoteArtifactFile = productMavenRepositoryUrl + data.getVersioning().getLatest() + "/" + data.getArtifactId() + "-" + data.getVersioning().getLatest(); + if (!remoteFileExists(remoteArtifactFile + ".jar")) { AsposeConstants.println("Not Exists"); @@ -334,7 +348,7 @@ public Metadata getProductMavenDependency(String productMavenRepositoryUrl) { } else { AsposeConstants.println("Exists"); } - } catch (IOException | JAXBException ex) { + } catch (Exception ex) { ex.printStackTrace(); data = null; } diff --git a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/src/com/aspose/words/maven/utils/AsposeWordsJavaAPI.java b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/src/com/aspose/words/maven/utils/AsposeWordsJavaAPI.java index b981222e..e488b8b5 100644 --- a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/src/com/aspose/words/maven/utils/AsposeWordsJavaAPI.java +++ b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/src/com/aspose/words/maven/utils/AsposeWordsJavaAPI.java @@ -23,9 +23,9 @@ */ public class AsposeWordsJavaAPI extends AsposeJavaAPI { - private final String _name = AsposeConstants.API_NAME; - private final String _mavenRepositoryURL = "http://maven.aspose.com/repository/ext-release-local/com/aspose/aspose-words/"; - private final String _remoteExamplesRepository = "https://github.com/asposewords/Aspose_Words_Java"; + private final String _name = AsposeConstants.API_NAME; + private final String _mavenRepositoryURL = "https://repository.aspose.com/repo/com/aspose/aspose-words/"; + private final String _remoteExamplesRepository = "https://github.com/aspose-words/Aspose.Words-for-Java"; /** * @return the _name diff --git a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/src/com/aspose/words/maven/utils/GitHelper.java b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/src/com/aspose/words/maven/utils/GitHelper.java index 8c1e70ed..3c196cb3 100644 --- a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/src/com/aspose/words/maven/utils/GitHelper.java +++ b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipsePlugin/src/com/aspose/words/maven/utils/GitHelper.java @@ -14,6 +14,7 @@ * @author Adeel Ilyas * */ +@SuppressWarnings("restriction") public class GitHelper { /** @@ -22,7 +23,7 @@ public class GitHelper { * @param remotePath * @throws Exception */ - public static void updateRepository(String localPath, String remotePath) throws Exception { + public static void updateRepository(String localPath, String remotePath) throws Exception { Repository localRepo; try { localRepo = new FileRepository(localPath + "/.git"); @@ -54,7 +55,7 @@ public static void updateRepository(String localPath, String remotePath) throws * @param remotePath * @throws Exception */ - public static void syncRepository(String localPath, String remotePath) throws Exception { + public static void syncRepository(String localPath, String remotePath) throws Exception { Repository localRepo; try { localRepo = new FileRepository(localPath + "/.git"); diff --git a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipseSite/site.xml b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipseSite/site.xml index 2321e3c6..7e3fcda9 100644 --- a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipseSite/site.xml +++ b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/AsposeWordsEclipseSite/site.xml @@ -1,6 +1,6 @@ - + Aspose.Words Maven Project wizard creates Maven Project for using Aspose.Words for Java API within Eclipse IDE. Aspose.Words for Java is an advanced class library for Java that @@ -16,7 +16,7 @@ Aspose Cloud Maven Repository. The wizard also gives you option to download the Code Examples to use Aspose.Words for Java API. - + diff --git a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/LICENSE b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/LICENSE index f83cc4c8..6d2e255f 100644 --- a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/LICENSE +++ b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2001-2016 Aspose Pty Ltd +Copyright (c) 2001-2020 Aspose Pty Ltd Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/README.md b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/README.md index e8d9a74b..549b7cc8 100644 --- a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/README.md +++ b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/README.md @@ -1,31 +1,31 @@ # **Aspose.Word Java for Eclipse (Maven)** -The project is **Eclipse IDE plugin** which lets developers to use [Aspose.Words for Java](http://goo.gl/Eg359W) in their Maven based Java projects. +The project is **Eclipse IDE plugin** which lets developers to use [Aspose.Words for Java](https://products.aspose.com/words/java) in their Maven based Java projects. ## Who is supposed to use this **Plugin?** -The Plugin intended for developers using Maven platform for Java developments and want to use [Aspose.Words for Java](http://goo.gl/Eg359W) in their projects. +The Plugin intended for developers using Maven platform for Java developments and want to use [Aspose.Words for Java](https://products.aspose.com/words/java) in their projects. -**NOTE:** [Aspose.Words for Java](http://goo.gl/Eg359W) is Java API developed by [Aspose](http://aspose.com) that offers easy Microsoft Word document creation and manipulation right from within Java Projects. For the API detailed features list check the [link](http://goo.gl/Eg359W). +**NOTE:** [Aspose.Words for Java](https://products.aspose.com/words/java) is Java API developed by [Aspose](https://www.aspose.com/) that offers easy Microsoft Word document creation and manipulation right from within Java Projects. For the API detailed features list check the [link](https://docs.aspose.com/display/wordsjava/Aspose.Words+Features). ## **Features** -The plugin provides following features to work with [Aspose.Words for Java](http://goo.gl/Eg359W) API within **Eclipse IDE** comfortably: +The plugin provides following features to work with [Aspose.Words for Java](https://products.aspose.com/words/java) API within **Eclipse IDE** comfortably: ### Aspose.Words Maven Project (wizard) ![plugin title shot](http://i.imgur.com/Q4oWEOp.png) -* By using this wizard plugin creates Maven project for using [Aspose.Words for Java](http://goo.gl/Eg359W) from **New -> Project -> Maven-> Aspose.Words Maven Project** +* By using this wizard plugin creates Maven project for using [Aspose.Words for Java](https://products.aspose.com/words/java) from **New -> Project -> Maven-> Aspose.Words Maven Project** * The wizard will also give option for downloading latest available Code Examples for using the API. ### Aspose.Words Code Example (wizard) ![plugin title shot](http://i.imgur.com/9EKXo7f.png) -* By using this wizard plugin lets you copy the downloaded Code Examples into your project for using [Aspose.Words for Java](http://goo.gl/Eg359W) from **New -> Other -> Java -> Aspose.Words Code Example** -* The wizard will also look for and updates for newly available Code Examples from [Aspose.Words for Java examples repository.](https://goo.gl/Qx9Hp9) +* By using this wizard plugin lets you copy the downloaded Code Examples into your project for using [Aspose.Words for Java](https://products.aspose.com/words/java) from **New -> Other -> Java -> Aspose.Words Code Example** +* The wizard will also look for and updates for newly available Code Examples from [Aspose.Words for Java examples repository.](https://github.com/aspose-words/Aspose.Words-for-Java/tree/master/Examples) **NOTE:** Selected Code Examples (category) source codes will be copied under **"com.aspose.words.examples"** package. Resources needed for running examples will be copied to the corresponding directory (package) within **"src/main/resources"**. ### Other Features -* Supports latest **Eclipse Mars.1 (4.5.1)** version +* Supports **Eclipse Mars.1 (4.5.1)** and later versions * Compatible with **Mac**, **Linux Flavors** and **Windows** * Native IDE user experience * Open Source @@ -36,8 +36,8 @@ The plugin provides following features to work with [Aspose.Words for Java](http Aspose.Words for Java supports processing word (**DOC, DOCX, OOXML, RTF**) **HTML, OpenDocument, PDF, EPUB, XPS, SWF and all image formats**. With Aspose.Words you can **generate**, **modify**, and **convert** documents without using Microsoft Word. -For more info about the **Aspose.Words for Java API**, [please check the api documentation - click here](http://www.aspose.com/java/word-component.aspx) +For more info about the **Aspose.Words for Java API**, [please check the api documentation - click here](https://docs.aspose.com/display/wordsjava/Introducing+Aspose.Words+for+Java) ## Plugin Documentation -For the most complete documentation, [Please check this WIKI](http://www.aspose.com/docs/display/wordsjava/Aspose.Words+Java+for+Eclipse+(Maven)) +For the most complete documentation, [Please check this WIKI](https://docs.aspose.com/display/wordsjava/Aspose.Words+Java+for+Eclipse+(Maven)) diff --git a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/Release Notes.html b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/Release Notes.html index 45c62de7..c2e66c92 100644 --- a/Plugins/Aspose_Words_Java_for_Eclipse_Maven/Release Notes.html +++ b/Plugins/Aspose_Words_Java_for_Eclipse_Maven/Release Notes.html @@ -6,12 +6,12 @@ -Aspose.Words Java for Eclipse (Maven) - v1.0.0 +Aspose.Words Java for Eclipse (Maven) - v20.10

          This is new Plugin for Eclipse IDE by Aspose. The Plugin intended for developers using Maven platform for Java developments and want to use Aspose.Words for Java in their projects.

          NOTE: Aspose.Words for Java is Java API developed by Aspose that offers easy Microsoft Word document creation and manipulation right from within Java Projects. For the API detailed features list check the link.

          The plugin provides following features to work with Aspose.Words for Java API within Eclipse IDE comfortably:

          • Aspose.Words Maven Project
            • By using this wizard plugin creates Maven project for using Aspose.Words for Java from New -> Project -> Maven-> Aspose.Words Maven Project
            • The wizard will also give option for downloading latest available Code Examples for using the API.
          • Aspose.Words Code Example
          • -
          • Other Features
            • Supports latest Eclipse Mars.1 (4.5.1) version
            • Compatible with Mac, Linux Flavors and Windows
            • Native IDE user experience
            • Open Source
          +
        5. Other Features
          • Supports Eclipse Mars.1 (4.5.1) and later versions
          • Compatible with Mac, Linux Flavors and Windows
          • Native IDE user experience
          • Open Source
        6. \ No newline at end of file diff --git a/Plugins/Aspose_Words_Java_for_IntelliJ(Maven)/README.md b/Plugins/Aspose_Words_Java_for_IntelliJ(Maven)/README.md index 109d9673..fb9de045 100644 --- a/Plugins/Aspose_Words_Java_for_IntelliJ(Maven)/README.md +++ b/Plugins/Aspose_Words_Java_for_IntelliJ(Maven)/README.md @@ -22,8 +22,8 @@ The plugin contains two wizards: Aspose.Words for Java supports processing word (**DOC, DOCX, OOXML, RTF**) **HTML, OpenDocument, PDF, EPUB, XPS, SWF and all image formats**. With Aspose.Words you can **generate**, **modify**, and **convert** documents without using Microsoft Word. -For more info about the **Aspose.Words for Java API**, [please check the api documentation - click here](http://www.aspose.com/java/word-component.aspx) +For more info about the **Aspose.Words for Java API**, [please check the api documentation - click here](https://docs.aspose.com/display/wordsjava/Introducing+Aspose.Words+for+Java) ## Plugin Documentation -For the complete documentation of this Intellij IDEA plugin, [please go through this wiki - click here](http://www.aspose.com/docs/display/wordsjava/7.+Aspose.Words+Java+for+IntelliJ+IDEA+%28Maven%29) \ No newline at end of file +For the complete documentation of this Intellij IDEA plugin, [please go through this wiki - click here](https://docs.aspose.com/display/wordsjava/Aspose.Words+Project+Wizard+for+IntelliJ+IDEA+-+Maven) diff --git a/Plugins/Aspose_Words_Java_for_Jython/README.md b/Plugins/Aspose_Words_Java_for_Jython/README.md index 4fe34381..8db37a11 100644 --- a/Plugins/Aspose_Words_Java_for_Jython/README.md +++ b/Plugins/Aspose_Words_Java_for_Jython/README.md @@ -4,7 +4,7 @@ Aspose.Words Java for Jython is a project that demonstrates / provides the Aspos ## Download -* To download Aspose.Words for Java API to be used with these examples, Please navigate to: http://www.aspose.com/community/files/72/java-components/aspose.words-for-java/ +* To download Aspose.Words for Java API to be used with these examples, Please navigate to: https://downloads.aspose.com/words/java * Place downloaded jar file into "lib" directory. * Replace "your-lib" with the jar filename. @@ -12,7 +12,7 @@ Aspose.Words Java for Jython is a project that demonstrates / provides the Aspos For most complete documentation of the project, check Aspose.Words Java For Jython confluence wiki link: -http://www.aspose.com/docs/display/wordsjava/Aspose.Words+Java+For+Jython +https://docs.aspose.com/display/wordsjava/Aspose.Words+Java+For+Jython ## Download Latest Versions? diff --git a/Plugins/Aspose_Words_Java_for_PHP/README.md b/Plugins/Aspose_Words_Java_for_PHP/README.md index 99dd5189..bb3642cf 100644 --- a/Plugins/Aspose_Words_Java_for_PHP/README.md +++ b/Plugins/Aspose_Words_Java_for_PHP/README.md @@ -10,11 +10,11 @@ http://php-java-bridge.sourceforge.net/pjb/index.php To download Aspose.Words for Java API to be used with these examples through PHP/Java Bridge Please navigate to: -http://www.aspose.com/community/files/72/java-components/aspose.words-for-java/ +https://downloads.aspose.com/words/java For most complete documentation of the project, check Aspose.Words Java for PHP confluence wiki link: -http://www.aspose.com/docs/display/wordsjava/3.+Aspose.Words+Java+For+PHP +https://docs.aspose.com/display/wordsjava/Aspose.Words+Java+For+PHP diff --git a/Plugins/Aspose_Words_Java_for_Python/default.py b/Plugins/Aspose_Words_Java_for_Python/default.py index 29d48d9e..91ab7e62 100644 --- a/Plugins/Aspose_Words_Java_for_Python/default.py +++ b/Plugins/Aspose_Words_Java_for_Python/default.py @@ -1,12 +1,12 @@ -from src.quickstart.helloworld.python import HelloWorld +from quickstart import HelloWorld import jpype import os.path asposeapispath = os.path.join(os.path.abspath("./"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) -hw = HelloWorld() +hw = HelloWorld('data/') hw.main() diff --git a/Plugins/Aspose_Words_Java_for_Python/loadingandsaving/__init__.py b/Plugins/Aspose_Words_Java_for_Python/loadingandsaving/__init__.py index 4b2a866c..c474b751 100644 --- a/Plugins/Aspose_Words_Java_for_Python/loadingandsaving/__init__.py +++ b/Plugins/Aspose_Words_Java_for_Python/loadingandsaving/__init__.py @@ -22,44 +22,44 @@ def main(self): continue nameOnly = file.getName() - print nameOnly + print (nameOnly) fileName = file.getPath() - print fileName + print (fileName) info = self.infoObj.detectFileFormat(fileName) if (info.getLoadFormat() == self.LoadFormat.DOC): - print "Microsoft Word 97-2003 document." + print ("Microsoft Word 97-2003 document.") elif (info.getLoadFormat() == self.LoadFormat.DOT): - print "Microsoft Word 97-2003 template." + print ("Microsoft Word 97-2003 template.") elif (info.getLoadFormat() == self.LoadFormat.DOCX): - print "Office Open XML WordprocessingML Macro-Free Document." + print ("Office Open XML WordprocessingML Macro-Free Document.") elif (info.getLoadFormat() == self.LoadFormat.DOCM): - print "Office Open XML WordprocessingML Macro-Enabled Document." + print ("Office Open XML WordprocessingML Macro-Enabled Document.") elif (info.getLoadFormat() == self.LoadFormat.DOTX): - print "Office Open XML WordprocessingML Macro-Free Template." + print ("Office Open XML WordprocessingML Macro-Free Template.") elif (info.getLoadFormat() == self.LoadFormat.DOTM): - print "Office Open XML WordprocessingML Macro-Enabled Template." + print ("Office Open XML WordprocessingML Macro-Enabled Template.") elif (info.getLoadFormat() == self.LoadFormat.FLAT_OPC): - print "Flat OPC document." + print ("Flat OPC document.") elif (info.getLoadFormat() == self.LoadFormat.RTF): - print "RTF format." + print ("RTF format.") elif (info.getLoadFormat() == self.LoadFormat.WORD_ML): - print "Microsoft Word 2003 WordprocessingML format." + print ("Microsoft Word 2003 WordprocessingML format.") elif (info.getLoadFormat() == self.LoadFormat.HTML): - print "HTML format." + print ("HTML format.") elif (info.getLoadFormat() == self.LoadFormat.MHTML): - print "MHTML (Web archive) format." + print ("MHTML (Web archive) format.") elif (info.getLoadFormat() == self.LoadFormat.ODT): - print "OpenDocument Text." + print ("OpenDocument Text.") elif (info.getLoadFormat() == self.LoadFormat.OTT): - print "OpenDocument Text Template." + print ("OpenDocument Text Template.") elif (info.getLoadFormat() == self.LoadFormat.DOC_PRE_WORD_97): - print "MS Word 6 or Word 95 format." + print ("MS Word 6 or Word 95 format.") elif (info.getLoadFormat() == self.LoadFormat.UNKNOWN): - print "Unknown format." + print ("Unknown format.") else : - print "Unknown format." + print ("Unknown format.") destFileObj = self.File(supportedDir + nameOnly) destFile = destFileObj.getPath() diff --git a/Plugins/Aspose_Words_Java_for_Python/mailmergeandreporting/__init__.py b/Plugins/Aspose_Words_Java_for_Python/mailmergeandreporting/__init__.py index d4b3b36f..90b936c3 100644 --- a/Plugins/Aspose_Words_Java_for_Python/mailmergeandreporting/__init__.py +++ b/Plugins/Aspose_Words_Java_for_Python/mailmergeandreporting/__init__.py @@ -47,12 +47,12 @@ def fieldMerging(self,e): self.mBuilder = self.DocumentBuilder(e.getDocument()) # We decided that we want all boolean values to be output as check box form fields. - if (e.getFieldValue() in ('True', 'False')) : + if (str(e.getFieldValue()) in ('True', 'False')) : # Move the "cursor" to the current merge field. self.mBuilder.moveToMergeField(e.getFieldName()) # It is nice to give names to check boxes. Lets generate a name such as MyField21 or so. - checkBoxName = e.getFieldName() + e.getRecordIndex() + checkBoxName = e.getFieldName() + str(e.getRecordIndex()) # Insert a check box. self.mBuilder.insertCheckBox(checkBoxName, e.getFieldValue(), 0) @@ -64,7 +64,7 @@ def fieldMerging(self,e): if ("Subject" == e.getFieldName()): self.mBuilder.moveToMergeField(e.getFieldName()) - textInputName = e.getFieldName() + e.getRecordIndex() + textInputName = e.getFieldName() + str(e.getRecordIndex()) self.mBuilder.insertTextInput(textInputName, self.TextFormFieldType.REGULAR, "", e.getFieldValue(), 0) def imageFieldMerging(self): diff --git a/Plugins/Aspose_Words_Java_for_Python/programmingwithdocuments/__init__.py b/Plugins/Aspose_Words_Java_for_Python/programmingwithdocuments/__init__.py index 35c54f5b..60eeac8d 100644 --- a/Plugins/Aspose_Words_Java_for_Python/programmingwithdocuments/__init__.py +++ b/Plugins/Aspose_Words_Java_for_Python/programmingwithdocuments/__init__.py @@ -351,20 +351,20 @@ def main(self): comments = self.extractComments(doc) for comment in comments: - print comment + print (comment) # Remove comments by the "pm" author. self.removeComments(doc, "pm") - print "Comments from \"pm\" are removed!" + print ("Comments from \"pm\" are removed!") # Extract the information about the comments of the "ks" author. comments = self.extractComments(doc, "ks") for comment in comments: - print comment + print (comment) # Remove all comments. self.removeComments(doc) - print "All comments are removed!" + print ("All comments are removed!") # Save the document. doc.save(self.dataDir + "Test File Out.doc") @@ -384,9 +384,9 @@ def extractComments(self,*args): if 1 < len(args) and args[1] is not None : authorName = args[1] if str(comment.getAuthor()) == authorName: - collectedComments.append(str(comment.getAuthor()) + " " + str(comment.getDateTime()) + " " + comment.toString(self.SaveFormat.TEXT)) + collectedComments.append(str(comment.getAuthor()) + " " + str(comment.getDateTime()) + " " + str(comment.toString())) else: - collectedComments.append(str(comment.getAuthor()) + " " + str(comment.getDateTime()) + " " + comment.toString(self.SaveFormat.TEXT)) + collectedComments.append(str(comment.getAuthor()) + " " + str(comment.getDateTime()) + " " + str(comment.toString())) return collectedComments @@ -504,7 +504,7 @@ def extractContentBetweenRuns(self): # Get the node from the list. There should only be one paragraph returned in the list. node = extractedNodes[0] # Print the text of this node to the console. - print node.toString(self.SaveFormat.TEXT) + print (node.toString()) #ExEnd @@ -669,8 +669,8 @@ def extractContents(self,startNode, endNode, isInclusive): while (endNode.getParentNode().getNodeType() != self.NodeType.BODY): endNode = endNode.getParentNode() - print str(originalStartNode) + " = " + str(startNode) - print str(originalEndNode) + " = " + str(endNode) + print (str(originalStartNode) + " = " + str(startNode)) + print (str(originalEndNode) + " = " + str(endNode)) isExtracting = True isStartingNode = True @@ -966,12 +966,12 @@ def __init__(self,dataDir): self.Shape = jpype.JClass("com.aspose.words.Shape") self.ShapeType = jpype.JClass("com.aspose.words.ShapeType") self.Color = jpype.JClass("java.awt.Color") - self.ColRelativeHorizontalPositionor = jpype.JClass("java.awt.RelativeHorizontalPosition") - self.RelativeVerticalPosition = jpype.JClass("java.awt.RelativeVerticalPosition") - self.WrapType = jpype.JClass("java.awt.WrapType") - self.VerticalAlignment = jpype.JClass("java.awt.VerticalAlignment") - self.HorizontalAlignment = jpype.JClass("java.awt.HorizontalAlignment") - self.Paragraph = jpype.JClass("java.awt.Paragraph") + self.RelativeHorizontalPosition = jpype.JClass("com.aspose.words.RelativeHorizontalPosition") + self.RelativeVerticalPosition = jpype.JClass("com.aspose.words.RelativeVerticalPosition") + self.WrapType = jpype.JClass("com.aspose.words.WrapType") + self.VerticalAlignment = jpype.JClass("com.aspose.words.VerticalAlignment") + self.HorizontalAlignment = jpype.JClass("com.aspose.words.HorizontalAlignment") + self.Paragraph = jpype.JClass("com.aspose.words.Paragraph") self.HeaderFooterType = jpype.JClass("com.aspose.words.HeaderFooterType") self.HeaderFooter = jpype.JClass("com.aspose.words.HeaderFooter") @@ -1055,20 +1055,20 @@ def main(self): # Show the number of collected paragraphs and display the text of this paragraphs. paragraphs = self.paragraphsByStyleName(doc, PARA_STYLE) - print "abc = " + str(paragraphs[0]) - print "Paragraphs with " + PARA_STYLE + " styles " + str(len(paragraphs)) + ":" + print ("abc = " + str(paragraphs[0])) + print ("Paragraphs with " + PARA_STYLE + " styles " + str(len(paragraphs)) + ":") for paragraph in paragraphs : - print str(paragraph.toString(self.SaveFormat.TEXT)) + print (str(paragraph.toString())) # Collect runs with defined styles. # Show the number of collected runs and display the text of this runs. runs = self.runsByStyleName(doc, RUN_STYLE) - print "Runs with " + RUN_STYLE + " styles " + str(len(runs)) + ":" + print ("Runs with " + RUN_STYLE + " styles " + str(len(runs)) + ":") for run in runs : - print run.getRange().getText() + print (run.getRange().getText()) diff --git a/Plugins/Aspose_Words_Java_for_Python/quickstart/__init__.py b/Plugins/Aspose_Words_Java_for_Python/quickstart/__init__.py index 2aba7a55..91b0c459 100644 --- a/Plugins/Aspose_Words_Java_for_Python/quickstart/__init__.py +++ b/Plugins/Aspose_Words_Java_for_Python/quickstart/__init__.py @@ -62,12 +62,12 @@ def main(self,srcDocFile,outputDocFile,searchString,replaceString): doc = Document(srcDocFile) - print "Original document text: " + doc.getRange().getText() + print ("Original document text: ", doc.getRange().getText()) doc.getRange().replace(searchString, replaceString, FindReplaceOptions(FindReplaceDirection.FORWARD)) # Check the replacement was made. - print "Document text after replace: " + doc.getRange().getText() + print ("Document text after replace: ", doc.getRange().getText()) # Save the modified document. doc.save(outputDocFile) @@ -172,7 +172,7 @@ def main(self,outputFile): builder.writeln("Heading 3.2") builder.writeln("Heading 3.3") - print "Updating all fields in the document." + print ("Updating all fields in the document.") # Call the method below to update the TOC. doc.updateFields() @@ -199,7 +199,7 @@ def main(self): # Next print the node type of one of the nodes in the document. nodeType = doc.getFirstSection().getBody().getNodeType() - print "NodeType: " + Node.nodeTypeToString(nodeType) + print ("NodeType: ", Node.nodeTypeToString(nodeType)) class ApplyLicense: @@ -215,4 +215,4 @@ def main(self): license.setLicense("Aspose.Words.lic") except Exception as e: # We do not ship any license with this example, visit the Aspose site to obtain either a temporary or permanent license. - print "There was an error setting the license: " + print ("There was an error setting the license: ") diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/loadandsaving/checkformat/CheckFormat.py b/Plugins/Aspose_Words_Java_for_Python/tests/loadandsaving/checkformat/CheckFormat.py index debc3e7d..f49e26c9 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/loadandsaving/checkformat/CheckFormat.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/loadandsaving/checkformat/CheckFormat.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/mailmergeandreporting/mailmergeformfields/MailMergeFormFields.py b/Plugins/Aspose_Words_Java_for_Python/tests/mailmergeandreporting/mailmergeformfields/MailMergeFormFields.py index 964af00b..e34219be 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/mailmergeandreporting/mailmergeformfields/MailMergeFormFields.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/mailmergeandreporting/mailmergeformfields/MailMergeFormFields.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/joiningandappending/AppendDocument.py b/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/joiningandappending/AppendDocument.py index d2b01201..641f3111 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/joiningandappending/AppendDocument.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/joiningandappending/AppendDocument.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithbookmarks/copybookmarkedtext/CopyBookmarkedText.py b/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithbookmarks/copybookmarkedtext/CopyBookmarkedText.py index 48867c8f..d868de53 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithbookmarks/copybookmarkedtext/CopyBookmarkedText.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithbookmarks/copybookmarkedtext/CopyBookmarkedText.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithbookmarks/untanglerowbookmarks/UntangleRowBookmarks.py b/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithbookmarks/untanglerowbookmarks/UntangleRowBookmarks.py index 062e7b74..b47a35b3 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithbookmarks/untanglerowbookmarks/UntangleRowBookmarks.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithbookmarks/untanglerowbookmarks/UntangleRowBookmarks.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithcomments/processcomments/ProcessComments/ProcessComments.py b/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithcomments/processcomments/ProcessComments/ProcessComments.py index 20099dc6..cd347422 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithcomments/processcomments/ProcessComments/ProcessComments.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithcomments/processcomments/ProcessComments/ProcessComments.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithdocument/extractcontent/ExtractContent.py b/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithdocument/extractcontent/ExtractContent.py index 86f85d73..a5d3b92a 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithdocument/extractcontent/ExtractContent.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithdocument/extractcontent/ExtractContent.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithdocument/removebreaks/RemoveBreaks.py b/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithdocument/removebreaks/RemoveBreaks.py index b230d6fc..e6e60f42 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithdocument/removebreaks/RemoveBreaks.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithdocument/removebreaks/RemoveBreaks.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithfields/insertnestedfields/InsertNestedFields.py b/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithfields/insertnestedfields/InsertNestedFields.py index d06c102d..b751aa8b 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithfields/insertnestedfields/InsertNestedFields.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithfields/insertnestedfields/InsertNestedFields.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithfields/removefield/RemoveField.py b/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithfields/removefield/RemoveField.py index 092d0001..6f4d5ec8 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithfields/removefield/RemoveField.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithfields/removefield/RemoveField.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithimages/addwatermark/AddWatermark.py b/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithimages/addwatermark/AddWatermark.py index 61e8ade7..07cbb312 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithimages/addwatermark/AddWatermark.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithimages/addwatermark/AddWatermark.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithstyles/extractcontentbasedonstyles/ExtractContentBasedOnStyles.py b/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithstyles/extractcontentbasedonstyles/ExtractContentBasedOnStyles.py index 8778ee14..0b1d163c 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithstyles/extractcontentbasedonstyles/ExtractContentBasedOnStyles.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithstyles/extractcontentbasedonstyles/ExtractContentBasedOnStyles.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithtables/autofittables/AutoFitTables.py b/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithtables/autofittables/AutoFitTables.py index b3f83556..bbe3d00b 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithtables/autofittables/AutoFitTables.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/programmingwithdocuments/workingwithtables/autofittables/AutoFitTables.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/HelloWorld/HelloWorld.py b/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/HelloWorld/HelloWorld.py index 5407cd40..4d280659 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/HelloWorld/HelloWorld.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/HelloWorld/HelloWorld.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/LoadAndsaveToStream/LoadAndSaveToStream.py b/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/LoadAndsaveToStream/LoadAndSaveToStream.py index acba4a99..7d63280e 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/LoadAndsaveToStream/LoadAndSaveToStream.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/LoadAndsaveToStream/LoadAndSaveToStream.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/appenddocument/appenddocument.py b/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/appenddocument/appenddocument.py index bcc8a035..62ac395f 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/appenddocument/appenddocument.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/appenddocument/appenddocument.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/applylicense/ApplyLicense.py b/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/applylicense/ApplyLicense.py index 96531e91..ea755136 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/applylicense/ApplyLicense.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/applylicense/ApplyLicense.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/doc2pdf/doc2pdf.py b/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/doc2pdf/doc2pdf.py index 9a4560c6..f1da2c5d 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/doc2pdf/doc2pdf.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/doc2pdf/doc2pdf.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/findandreplace/findandreplace.py b/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/findandreplace/findandreplace.py index 1b23b18d..c3f4a80e 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/findandreplace/findandreplace.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/findandreplace/findandreplace.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/loadandsavetodisk/LoadAndSaveToDisk.py b/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/loadandsavetodisk/LoadAndSaveToDisk.py index 94a128f4..5b9c0eee 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/loadandsavetodisk/LoadAndSaveToDisk.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/loadandsavetodisk/LoadAndSaveToDisk.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/simplemailmerge/SimpleMailMerge.py b/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/simplemailmerge/SimpleMailMerge.py index 0621c489..ec16dbee 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/simplemailmerge/SimpleMailMerge.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/simplemailmerge/SimpleMailMerge.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/updatefields/UpdateFields.py b/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/updatefields/UpdateFields.py index 479659d1..ef7845ed 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/updatefields/UpdateFields.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/updatefields/UpdateFields.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/workingwithnodes/WorkingWithNodes.py b/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/workingwithnodes/WorkingWithNodes.py index 45bcf1e3..2432ac62 100644 --- a/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/workingwithnodes/WorkingWithNodes.py +++ b/Plugins/Aspose_Words_Java_for_Python/tests/quickstart/workingwithnodes/WorkingWithNodes.py @@ -5,7 +5,7 @@ asposeapispath = os.path.join(os.path.abspath("../../../"), "lib") -print "You need to put your Aspose.Words for Java APIs .jars in this folder:\n"+asposeapispath +print ("You need to put your Aspose.Words for Java APIs .jars in this folder:\n", asposeapispath) jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % asposeapispath) diff --git a/Plugins/Aspose_Words_Java_for_Ruby/README.md b/Plugins/Aspose_Words_Java_for_Ruby/README.md index 20da678d..f8dcceb3 100644 --- a/Plugins/Aspose_Words_Java_for_Ruby/README.md +++ b/Plugins/Aspose_Words_Java_for_Ruby/README.md @@ -19,10 +19,10 @@ Or install it yourself as: To download Aspose.Words for Java API to be used with these examples through RJB, Please navigate to: -http://www.aspose.com/community/files/72/java-components/aspose.words-for-java/ +https://downloads.aspose.com/words/java For most complete documentation of the project, check Aspose.Words Java for Ruby confluence wiki link: -http://www.aspose.com/docs/display/wordsjava/4.+Aspose.Words+Java+For+Ruby +https://docs.aspose.com/display/wordsjava/Aspose.Words+Java+For+Ruby diff --git a/Plugins/Aspose_Words_for_Apache_POI/README.md b/Plugins/Aspose_Words_for_Apache_POI/README.md index 3216f7c2..4f4e5154 100644 --- a/Plugins/Aspose_Words_for_Apache_POI/README.md +++ b/Plugins/Aspose_Words_for_Apache_POI/README.md @@ -4,15 +4,15 @@ Aspose.Words Java for Apache POI WP is a project to provide comparative source c Below are some code comparisons and features of Aspose.Words for Java that are not available in Apache POI -* [Code Comparison for common features in **Aspose.Words** and **Apache POI WP**](http://www.aspose.com/docs/display/wordsjava/1.2+Code+Comparison+for+Common+Features+in+Aspose.Words+and+Apache+POI+-+HWPF+and+XWPF) -* [Missing Features of Apache POI WP available in Aspose.Words](http://www.aspose.com/docs/display/wordsjava/1.3+Missing+Features+in+Apache+POI+WP+-+HWPF+and+XWPF) +* [Code Comparison for common features in **Aspose.Words** and **Apache POI WP**](https://docs.aspose.com/display/wordsjava/Code+Comparison+for+Common+Features+in+Aspose.Words+and+Apache+POI+-+HWPF+and+XWPF) +* [Missing Features of Apache POI WP available in Aspose.Words](https://docs.aspose.com/display/wordsjava/Missing+Features+in+Apache+POI+-+HWPF+and+XWPF) These examples are helpful for developers who want to compare Apache POI with Aspose.Words OR migrate from Apache POI to Aspose. ### Feedback and Suggestions -* Many more examples are yet to come. [Keep visiting us](http://www.aspose.com/java/total-component.aspx). -* Raise your queries and suggest more examples via [Aspose Forums](http://www.aspose.com/community/forums/default.aspx) or via this social coding site. +* Many more examples are yet to come. [Keep visiting us](https://products.aspose.com/total/java). +* Raise your queries and suggest more examples via [Aspose Forums](https://forum.aspose.com/) or via this social coding site. ## Why Aspose for Apache POI ? @@ -45,13 +45,13 @@ All the Aspose APIs don’t have any dependency over any other engine. For examp ### Aspose.Words for Java -[![Aspose.Words for Java](http://www.aspose.com/App_Themes/V2/images/productLogos/Java/aspose_words-for-java.jpg)](http://www.aspose.com/java/word-component.aspx) +[![Aspose.Words for Java](http://www.aspose.com/App_Themes/V2/images/productLogos/Java/aspose_words-for-java.jpg)](https://products.aspose.com/words/java) Aspose.Words for Java is an advanced class library for Java that enables you to perform a great range of document processing tasks directly within your Java applications. Aspose.Words for Java supports DOC, OOXML, RTF, HTML and OpenDocument formats. With Aspose.Words you can generate, modify, and convert documents without using Microsoft Word. -[Learn More](http://www.aspose.com/java/word-component.aspx) +[Learn More](https://docs.aspose.com/display/wordsjava/Introducing+Aspose.Words+for+Java) ## Download Latest Versions? diff --git a/Plugins/Aspose_Words_for_Struts/README.md b/Plugins/Aspose_Words_for_Struts/README.md index f8ff5574..0c0453ac 100644 --- a/Plugins/Aspose_Words_for_Struts/README.md +++ b/Plugins/Aspose_Words_for_Struts/README.md @@ -9,6 +9,5 @@ You should have apache tomcat installed. After building the project .war file, c For most complete documentation of the project, check Aspose.Words Java for Struts confluence wiki -http://www.aspose.com/docs/display/wordsjava/5.+Aspose.Words+Java+for+Struts+1.3 - +https://docs.aspose.com/display/wordsjava/Aspose.Words+Java+for+Struts+1.3 diff --git a/README.md b/README.md index 8a2c6436..8f891018 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,107 @@ -##Aspose.Words for Java -[Aspose.Words for Java](http://www.aspose.com/products/words/java) is an advanced Java Word processing API that enables you to perform a great range of document processing tasks directly within your Java applications. Aspose.Words for Java API supports processing word (DOC, DOCX, OOXML, RTF) HTML, OpenDocument, PDF, EPUB, XPS, SWF and all image formats. With Aspose.Words you can generate, modify, and convert documents without using Microsoft Word. +![GitHub all releases](https://img.shields.io/github/downloads/aspose-words/Aspose.Words-for-Java/total) ![GitHub](https://img.shields.io/github/license/aspose-words/Aspose.Words-for-java) +# Java API for Various Document Formats -This repository contains [Examples](Examples), [Plugins](Plugins) and Showcases for [Aspose.Words for Java](http://www.aspose.com/products/words/java) to help you learn and write your own applications. +[Aspose.Words for Java](https://products.aspose.com/words/java) is an advanced Java Word processing API that enables you to perform a great range of document processing tasks directly within your Java applications. Aspose.Words for Java API supports processing word (DOC, DOCX, OOXML, RTF) HTML, OpenDocument, PDF, EPUB, XPS, SWF and all image formats. With Aspose.Words you can generate, modify, and convert documents without using Microsoft Word. -

          +Directory | Description +--------- | ----------- +[Examples](Examples) | A collection of Java examples that help you learn the product features. +[Plugins](Plugins) | Plugins that will demonstrate one or more features of Aspose.Words for Java. - +

          +

          -Directory | Description ---------- | ----------- -[Examples](Examples) | A collection of Java examples that help you learn and explore the API features -[Plugins](Plugins) | Plugins that will demonstrate one or more features of Aspose.Words for Java +## Word API Features + +### Rendering and Printing + +- Layout document into pages with high fidelity (exactly like Microsoft Word® would do that) to all the formats below. +- Render individual pages or complete documents to `PDF`, `XPS`, or `SWF`. +- Render document pages to raster images (Multipage `TIFF`, `PNG`, `JPEG`, `BMP`). +- Render pages to a Java Graphics object to a specific size. +- Print document pages using the Java printing infrastructure. +- Update TOC, page numbers, and other fields before rendering or printing. +- 3D Effects Rendering through the `OpenGL`. + +### Document Content Features + +- Access, create, and modify various document elements. +- Access and modify all document elements using `XmlDocument` -like classes and methods. +- Copy and move document elements between documents. +- Join and split documents. +- Specify document protection, open protected, and encrypted documents. +- Find and replace text, enumerate over document content. +- Preserve or extract OLE objects and ActiveX controls from the document. +- Preserve or remove VBA macros from the document. Preserve VBA macros digital signature. + +### Reporting Features + +- Support of C# syntax and LINQ extension methods directly in templates (even for `ADO.NET` data sources). +- Support of repeatable and conditional document blocks (loops and conditions) for tables, lists, and common content. +- Support of dynamically generated charts and images. +- Support of insertion of outer documents and `HTML` blocks into a document. +- Support of multiple data sources (including of different types) for the generation of a single document. +- Built-in support of data relations (master-detail). +- Comprehensive support of various data manipulations such as grouping, sorting, filtering, and others directly in templates. + +For a more comprehensive list of features, please visit [Feature Overview](https://docs.aspose.com/words/java/feature-overview/). + +## Read & Write Document Formats + +**Microsoft Word:** DOC, DOCX, RTF, DOT, DOTX, DOTM, DOCM FlatOPC, FlatOpcMacroEnabled, FlatOpcTemplate, FlatOpcTemplateMacroEnabled\ +**OpenOffice:** ODT, OTT\ +**WordprocessingML:** WordML\ +**Web:** HTML, MHTML\ +**Fixed Layout:** PDF\ +**Text:** TXT +**Other:** MD + +## Save Word Files As + +**Fixed Layout:** XPS, OpenXPS, PostScript (PS)\ +**Images:** TIFF, JPEG, PNG, BMP, SVG, EMF, GIF\ +**Web:** HtmlFixed\ +**Others:** PCL, EPUB, XamlFixed, XamlFlow, XamlFlowPack + +## Read File Formats + +**MS Office:** DocPreWord60 +**eBook:** MOBI + +## Supported Environments + +- **Microsoft Windows:** Windows Desktop & Server (x86, x64) +- **macOS:** Mac OS X +- **Linux:** Ubuntu, OpenSUSE, CentOS, and others +- **Java Versions:** `J2SE 7.0 (1.7)`, `J2SE 8.0 (1.8)` or above. + +## Get Started with Aspose.Words for Java + +Aspose hosts all Java APIs at the [Aspose Repository](https://repository.aspose.com/webapp/#/artifacts/browse/tree/General/repo/com/aspose/aspose-words). You can easily use Aspose.Words for Java API directly in your Maven projects with simple configurations. For the detailed instructions please visit [Installing Aspose.Words for Java from Maven Repository](https://docs.aspose.com/words/java/installation/) documentation page. + +## Printing Multiple Pages on One Sheet using Java + +```java +// Open the document. +Document doc = new Document(dataDir + "TestFile.doc"); + +// Create a print job to print our document with. +PrinterJob pj = PrinterJob.getPrinterJob(); + +// Initialize an attribute set with the number of pages in the document. +PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet(); +attributes.add(new PageRanges(1, doc.getPageCount())); + +// Pass the printer settings along with the other parameters to the print document. +MultipagePrintDocument awPrintDoc = new MultipagePrintDocument(doc, 4, true, attributes); + +// Pass the document to be printed using the print job. +pj.setPrintable(awPrintDoc); -## Resources +pj.print(); +``` -+ **Website:** [www.aspose.com](http://www.aspose.com) -+ **Product Home:** [Aspose.Words for Java](http://www.aspose.com/products/words/java) -+ **Download:** [Download Aspose.Words for Java](http://www.aspose.com/downloads/words/java) -+ **Documentation:** [Aspose.Words for Java Documentation](http://www.aspose.com/docs/display/wordsjava/Home) -+ **Forum:** [Aspose.Words for Java Forum](http://www.aspose.com/community/forums/aspose.words-product-family/75/showforum.aspx) -+ **Blog:** [Aspose.Words for Java Blog](http://www.aspose.com/blogs/aspose-products/aspose-words-product-family.html) +[Product Page](https://products.aspose.com/words/java) | [Docs](https://docs.aspose.com/words/java/) | [Demos](https://products.aspose.app/words/family) | [API Reference](https://apireference.aspose.com/words/java) | [Examples](https://github.com/aspose-words/Aspose.Words-for-Java/tree/master/Examples) | [Blog](https://blog.aspose.com/category/words/) | [Search](https://search.aspose.com/) | [Free Support](https://forum.aspose.com/c/words) | [Temporary License](https://purchase.aspose.com/temporary-license)